Merge topic 'improve-doc-consistency'

277c12a4c7 Help: Improve command usage formatting consistency

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !11687
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index c39cd71..3b19851 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1550,7 +1550,7 @@
     variables:
         CMAKE_CI_JOB_NIGHTLY: "true"
 
-t:windows-clang19.1-cl-ninja:
+t:windows-clang21.1-cl-ninja:
     extends:
         - .windows_clang_ninja
         - .cmake_test_windows_external
@@ -1560,10 +1560,10 @@
     needs:
         - t:windows-vs2026-x64-ninja
     variables:
-        CMAKE_CI_BUILD_NAME: windows_clang19.1_cl_ninja
+        CMAKE_CI_BUILD_NAME: windows_clang21.1_cl_ninja
         CMAKE_CI_JOB_NIGHTLY: "true"
 
-t:windows-clang19.1-cl-nmake:
+t:windows-clang21.1-cl-nmake:
     extends:
         - .windows_clang_nmake
         - .cmake_test_windows_external
@@ -1573,10 +1573,10 @@
     needs:
         - t:windows-vs2026-x64-ninja
     variables:
-        CMAKE_CI_BUILD_NAME: windows_clang19.1_cl_nmake
+        CMAKE_CI_BUILD_NAME: windows_clang21.1_cl_nmake
         CMAKE_CI_JOB_NIGHTLY: "true"
 
-t:windows-clang19.1-gnu-ninja:
+t:windows-clang21.1-gnu-ninja:
     extends:
         - .windows_clang_ninja
         - .cmake_test_windows_external
@@ -1586,10 +1586,10 @@
     needs:
         - t:windows-vs2026-x64-ninja
     variables:
-        CMAKE_CI_BUILD_NAME: windows_clang19.1_gnu_ninja
+        CMAKE_CI_BUILD_NAME: windows_clang21.1_gnu_ninja
         CMAKE_CI_JOB_NIGHTLY: "true"
 
-t:windows-clang19.1-gnu-nmake:
+t:windows-clang21.1-gnu-nmake:
     extends:
         - .windows_clang_nmake
         - .cmake_test_windows_external
@@ -1599,7 +1599,7 @@
     needs:
         - t:windows-vs2026-x64-ninja
     variables:
-        CMAKE_CI_BUILD_NAME: windows_clang19.1_gnu_nmake
+        CMAKE_CI_BUILD_NAME: windows_clang21.1_gnu_nmake
         CMAKE_CI_JOB_NIGHTLY: "true"
 
 t:windows-intel2021.9-ninja:
diff --git a/.gitlab/ci/clang.ps1 b/.gitlab/ci/clang.ps1
index 61361b1..327fe3b 100644
--- a/.gitlab/ci/clang.ps1
+++ b/.gitlab/ci/clang.ps1
@@ -1,10 +1,10 @@
 $erroractionpreference = "stop"
 
-if ("$env:CMAKE_CI_BUILD_NAME".Contains("clang19.1")) {
-    # LLVM/Clang 19.1.0
-    # https://github.com/llvm/llvm-project/releases/tag/llvmorg-19.1.0
-    $filename = "llvm-19.1.0-win-x86_64-1"
-    $sha256sum = "C1F974511A6FA2DC5B4892996C064A55BF81D7F244514F8AB5A453110ADEC0EC"
+if ("$env:CMAKE_CI_BUILD_NAME".Contains("clang21.1")) {
+    # LLVM/Clang 21.1.8
+    # https://github.com/llvm/llvm-project/releases/tag/llvmorg-21.1.8
+    $filename = "llvm-21.1.8-win-x86_64-1"
+    $sha256sum = "3DB0063A6E434C694799CDD70052F27F08A758F1FF4B4C04D9910AD4198F6064"
 } else {
     throw ('unknown CMAKE_CI_BUILD_NAME: ' + "$env:CMAKE_CI_BUILD_NAME")
 }
diff --git a/.gitlab/ci/configure_fedora43_makefiles.cmake b/.gitlab/ci/configure_fedora43_makefiles.cmake
index b5a9f30..3ddf236 100644
--- a/.gitlab/ci/configure_fedora43_makefiles.cmake
+++ b/.gitlab/ci/configure_fedora43_makefiles.cmake
@@ -108,6 +108,7 @@
 if (NOT "$ENV{CMAKE_CI_NIGHTLY}" STREQUAL "")
   set(CMake_TEST_ISPC "ON" CACHE STRING "")
 endif()
+set(CMake_TEST_LOCALE_CHARSET "ISO-8859-1" CACHE STRING "")
 set(CMake_TEST_Qt5 "ON" CACHE BOOL "")
 set(CMake_TEST_TLS_VERIFY_URL "https://gitlab.kitware.com" CACHE STRING "")
 set(CMake_TEST_TLS_VERIFY_URL_BAD "https://badtls-expired.kitware.com" CACHE STRING "")
diff --git a/.gitlab/ci/configure_fedora43_ninja.cmake b/.gitlab/ci/configure_fedora43_ninja.cmake
index 5c75c1e..a67e40a 100644
--- a/.gitlab/ci/configure_fedora43_ninja.cmake
+++ b/.gitlab/ci/configure_fedora43_ninja.cmake
@@ -4,6 +4,7 @@
   set(CMake_TEST_CPACK_APPIMAGE_RUNTIME_FILE "$ENV{CI_PROJECT_DIR}/.gitlab/appimagetool/lib/appimagetool/runtime" CACHE FILEPATH "")
   set(CMake_TEST_ISPC "ON" CACHE STRING "")
 endif()
+set(CMake_TEST_LOCALE_CHARSET "UTF-8" CACHE STRING "")
 set(CMake_TEST_MODULE_COMPILATION "named,compile_commands,collation,partitions,internal_partitions,export_bmi,install_bmi,shared,bmionly,build_database" CACHE STRING "")
 set(CMake_TEST_Rust "ON" CACHE STRING "")
 set(CMake_TEST_TLS_VERIFY_URL "https://gitlab.kitware.com" CACHE STRING "")
diff --git a/.gitlab/ci/configure_linux_gcc_cxx_modules_reloc_ninja.cmake b/.gitlab/ci/configure_linux_gcc_cxx_modules_reloc_ninja.cmake
index 75e94df..eb728ed 100644
--- a/.gitlab/ci/configure_linux_gcc_cxx_modules_reloc_ninja.cmake
+++ b/.gitlab/ci/configure_linux_gcc_cxx_modules_reloc_ninja.cmake
@@ -2,7 +2,7 @@
 # `CMAKE_CXX_STDLIB_MODULES_JSON` is needed to use `import std`.
 set(gcc_prefix "/opt/gcc-importstd")
 set(CMake_TEST_CXX_STDLIB_MODULES_JSON
-  "${gcc_prefix}/lib64/libstdc++.modules.json"
+  "${gcc_prefix}/lib64.reloc/libstdc++.modules.json"
   CACHE FILEPATH "")
 file(MAKE_DIRECTORY
   "${gcc_prefix}/lib64.reloc")
diff --git a/.gitlab/ci/configure_macos_arm64_ninja.cmake b/.gitlab/ci/configure_macos_arm64_ninja.cmake
index 3bfdcf2..c1924fe 100644
--- a/.gitlab/ci/configure_macos_arm64_ninja.cmake
+++ b/.gitlab/ci/configure_macos_arm64_ninja.cmake
@@ -6,6 +6,7 @@
 set(CMake_TEST_FindOpenMP_C "ON" CACHE BOOL "")
 set(CMake_TEST_FindOpenMP_CXX "ON" CACHE BOOL "")
 set(CMake_TEST_GUI "ON" CACHE BOOL "")
+set(CMake_TEST_LOCALE_CHARSET "UTF-8" CACHE STRING "")
 set(CMake_TEST_TLS_VERIFY_URL "https://gitlab.kitware.com" CACHE STRING "")
 set(CMake_TEST_TLS_VERIFY_URL_BAD "https://badtls-expired.kitware.com" CACHE STRING "")
 set(CMake_TEST_TLS_VERSION "1.2" CACHE STRING "")
diff --git a/.gitlab/ci/configure_macos_x86_64_ninja.cmake b/.gitlab/ci/configure_macos_x86_64_ninja.cmake
index 48f9dcb..1af144f 100644
--- a/.gitlab/ci/configure_macos_x86_64_ninja.cmake
+++ b/.gitlab/ci/configure_macos_x86_64_ninja.cmake
@@ -9,6 +9,7 @@
 if (NOT "$ENV{CMAKE_CI_NIGHTLY}" STREQUAL "")
   set(CMake_TEST_ISPC "ON" CACHE STRING "")
 endif()
+set(CMake_TEST_LOCALE_CHARSET "UTF-8" CACHE STRING "")
 set(CMake_TEST_TLS_VERIFY_URL "https://gitlab.kitware.com" CACHE STRING "")
 set(CMake_TEST_TLS_VERIFY_URL_BAD "https://badtls-expired.kitware.com" CACHE STRING "")
 set(CMake_TEST_TLS_VERSION "1.2" CACHE STRING "")
diff --git a/.gitlab/ci/configure_windows_common.cmake b/.gitlab/ci/configure_windows_common.cmake
index 7467cfd..1246885 100644
--- a/.gitlab/ci/configure_windows_common.cmake
+++ b/.gitlab/ci/configure_windows_common.cmake
@@ -2,6 +2,7 @@
 set(BUILD_CursesDialog ON CACHE BOOL "")
 set(CMAKE_PREFIX_PATH "$ENV{CI_PROJECT_DIR}/.gitlab/qt" CACHE STRING "")
 set(CMake_TEST_Java OFF CACHE BOOL "")
+set(CMake_TEST_LOCALE_CHARSET "UTF-8" CACHE STRING "")
 set(Python_FIND_REGISTRY NEVER CACHE STRING "")
 
 include("${CMAKE_CURRENT_LIST_DIR}/configure_common.cmake")
diff --git a/.gitlab/ci/env_fedora43_makefiles.sh b/.gitlab/ci/env_fedora43_makefiles.sh
index 217ff30..f02e487 100644
--- a/.gitlab/ci/env_fedora43_makefiles.sh
+++ b/.gitlab/ci/env_fedora43_makefiles.sh
@@ -1,3 +1,6 @@
 if test "$CMAKE_CI_NIGHTLY" = "true"; then
   source .gitlab/ci/ispc-env.sh
 fi
+
+# Test in a Latin-1 locale.
+export LANG=en_US.ISO-8859-1
diff --git a/.gitlab/ci/env_fedora43_ninja.sh b/.gitlab/ci/env_fedora43_ninja.sh
index a2b941b..0ef4bce 100644
--- a/.gitlab/ci/env_fedora43_ninja.sh
+++ b/.gitlab/ci/env_fedora43_ninja.sh
@@ -2,3 +2,6 @@
   source .gitlab/ci/appimagetool-env.sh
   source .gitlab/ci/ispc-env.sh
 fi
+
+# Test in a UTF-8 locale.
+export LANG=en_US.UTF-8
diff --git a/Auxiliary/vim/syntax/cmake.vim b/Auxiliary/vim/syntax/cmake.vim
index adcfed4..280dd9b 100644
--- a/Auxiliary/vim/syntax/cmake.vim
+++ b/Auxiliary/vim/syntax/cmake.vim
@@ -3539,7 +3539,6 @@
             \ APPENDIX
             \ AUTO
             \ CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_DEPENDENCIES
-            \ CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO
             \ CMAKE_MAP_IMPORTED_CONFIG_
             \ COMPAT_VERSION
             \ CONFIG
@@ -3835,7 +3834,6 @@
             \ BYPASS_PROVIDER
             \ CATEGORY
             \ CMAKE_DISABLE_FIND_PACKAGE_
-            \ CMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES
             \ CMAKE_FIND_ROOT_PATH_BOTH
             \ CMAKE_FIND_USE_
             \ CMAKE_REQUIRE_FIND_PACKAGE_
@@ -4149,7 +4147,6 @@
             \ BUILD_TYPE
             \ BUNDLE_EXECUTABLE
             \ CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_DEPENDENCIES
-            \ CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO
             \ CMAKE_INSTALL_BINDIR
             \ CMAKE_INSTALL_DATADIR
             \ CMAKE_INSTALL_DATAROOTDIR
@@ -4417,7 +4414,6 @@
             \ ASM_MASM
             \ ASM_NASM
             \ ATT
-            \ CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO
             \ CMAKE_PROJECT_
             \ COMPAT_VERSION
             \ CPS
diff --git a/Help/command/cmake_host_system_information.rst b/Help/command/cmake_host_system_information.rst
index 73effab..35360c2 100644
--- a/Help/command/cmake_host_system_information.rst
+++ b/Help/command/cmake_host_system_information.rst
@@ -137,6 +137,17 @@
 
   Human readable full processor description
 
+``LOCALE_CHARSET``
+  .. versionadded:: 4.3
+
+  The locale's character set, if known, otherwise empty.
+
+  This is the :ref:`encoding <CMake Language Encoding>` expected
+  in :manual:`cmake-language(7)` files and scripts:
+
+  * On Windows, this is always ``UTF-8``.
+  * On UNIX and macOS, this is based on the current locale.
+
 ``OS_NAME``
   .. versionadded:: 3.10
 
diff --git a/Help/command/cmake_path.rst b/Help/command/cmake_path.rst
index 3fc3b7c..5fb0ef1 100644
--- a/Help/command/cmake_path.rst
+++ b/Help/command/cmake_path.rst
@@ -169,6 +169,7 @@
 be empty.  A ``relative-part`` refers to the full path with any ``root-path``
 removed.
 
+.. _Creating a Path Variable:
 
 Creating A Path Variable
 ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -193,6 +194,16 @@
 keyword.  All other sub-commands store the result in a mandatory ``<out-var>``
 variable.
 
+.. note::
+
+  The ``cmake_path`` command can be used directly with variables provided by
+  CMake representing paths (e.g., :variable:`CMAKE_SOURCE_DIR`). However, since
+  the command can modify these variables, and many of them have undefined
+  behavior when modified, they should never be specified as an ``<out-var>``,
+  and only as the ``<path-var>`` when a separate ``<out-var>`` is specified.
+  See :manual:`cmake-variables(7)` for the list of CMake variables and
+  identifiers reserved by CMake.
+
 .. _Normalization:
 
 Normalization
@@ -395,7 +406,7 @@
 Query
 ^^^^^
 
-Each of the `cmake_path(GET) <GET_>`_ subcommands has a corresponding
+Each of the :cref:`GET` subcommands has a corresponding
 ``HAS_...`` subcommand which can be used to discover whether a particular path
 component is present.  See `Path Structure And Terminology`_ for the
 meaning of each path component.
@@ -500,7 +511,7 @@
   cmake_path(SET <path-var> [NORMALIZE] <input>)
 
   Assigns the ``<input>`` path to ``<path-var>``.  If ``<input>`` is a native
-  path, it is converted into a cmake-style path with forward-slashes
+  path, it is converted into a CMake-style path with forward-slashes
   (``/``). On Windows, the long filename marker is taken into account.
 
   When the ``NORMALIZE`` option is specified, the path is :ref:`normalized
@@ -550,12 +561,16 @@
 
     append <input> omitting any root-name to <path>
 
+  See :ref:`Creating a Path Variable` for details on the output variable.
+
 .. signature::
   cmake_path(APPEND_STRING <path-var> [<input>...] [OUTPUT_VARIABLE <out-var>])
 
   Appends all the ``<input>`` arguments to the ``<path-var>`` without adding any
   ``directory-separator``.
 
+  See :ref:`Creating a Path Variable` for details on the output variable.
+
 .. signature::
   cmake_path(REMOVE_FILENAME <path-var> [OUTPUT_VARIABLE <out-var>])
 
@@ -563,8 +578,8 @@
   :cref:`GET ... FILENAME`) from ``<path-var>``.  After removal, any trailing
   ``directory-separator`` is left alone, if present.
 
-  If ``OUTPUT_VARIABLE`` is not given, then after this function returns,
-  :cref:`HAS_FILENAME` returns false for ``<path-var>``.
+  :cref:`HAS_FILENAME` will return false for the result, whether stored in
+  ``<out-var>`` or ``<path-var>``.
 
   For example:
 
@@ -583,6 +598,8 @@
     First path is "/a/"
     Second path is "/a/"
 
+  See :ref:`Creating a Path Variable` for details on the output variable.
+
 .. signature::
   cmake_path(REPLACE_FILENAME <path-var> <input> [OUTPUT_VARIABLE <out-var>])
 
@@ -599,12 +616,16 @@
       cmake_path(APPEND path "${input}")
     endif()
 
+  See :ref:`Creating a Path Variable` for details on the output variable.
+
 .. signature::
   cmake_path(REMOVE_EXTENSION <path-var> [LAST_ONLY]
                                          [OUTPUT_VARIABLE <out-var>])
 
   Removes the :ref:`extension <EXTENSION_DEF>`, if any, from ``<path-var>``.
 
+  See :ref:`Creating a Path Variable` for details on the output variable.
+
 .. signature::
   cmake_path(REPLACE_EXTENSION <path-var> [LAST_ONLY] <input>
                                [OUTPUT_VARIABLE <out-var>])
@@ -620,6 +641,8 @@
     endif()
     cmake_path(APPEND_STRING path "${input}")
 
+  See :ref:`Creating a Path Variable` for details on the output variable.
+
 
 .. _Path Generation:
 
@@ -632,6 +655,8 @@
   Normalizes ``<path-var>`` according the steps described in
   :ref:`Normalization`.
 
+  See :ref:`Creating a Path Variable` for details on the output variable.
+
 .. signature::
   cmake_path(RELATIVE_PATH <path-var> [BASE_DIRECTORY <input>]
                                       [OUTPUT_VARIABLE <out-var>])
@@ -645,6 +670,8 @@
   `std::filesystem::path::lexically_relative
   <https://en.cppreference.com/w/cpp/filesystem/path/lexically_normal>`_.
 
+  See :ref:`Creating a Path Variable` for details on the output variable.
+
 .. signature::
   cmake_path(ABSOLUTE_PATH <path-var> [BASE_DIRECTORY <input>] [NORMALIZE]
                                       [OUTPUT_VARIABLE <out-var>])
@@ -662,6 +689,8 @@
   with symbolic links resolved and leading tildes expanded, use the
   :command:`file(REAL_PATH)` command instead.
 
+  See :ref:`Creating a Path Variable` for details on the output variable.
+
 Native Conversion
 ^^^^^^^^^^^^^^^^^
 
@@ -671,12 +700,14 @@
 .. signature::
   cmake_path(NATIVE_PATH <path-var> [NORMALIZE] <out-var>)
 
-  Converts a cmake-style ``<path-var>`` into a native path with
+  Converts a CMake-style ``<path-var>`` into a native path with
   platform-specific slashes (``\`` on Windows hosts and ``/`` elsewhere).
 
   When the ``NORMALIZE`` option is specified, the path is :ref:`normalized
   <Normalization>` before the conversion.
 
+  See :ref:`Creating a Path Variable` for details on the output variable.
+
 .. _CONVERT:
 
 .. signature::
@@ -684,17 +715,20 @@
   :target:
     CONVERT ... TO_CMAKE_PATH_LIST
 
-  Converts a native ``<input>`` path into a cmake-style path with forward
-  slashes (``/``).  On Windows hosts, the long filename marker is taken into
+  Converts a native ``<input>`` path into a CMake-style path with forward
+  slashes (``/``).
+
+  On Windows hosts, the long filename marker is taken into
   account.  The input can be a single path or a system search path like
-  ``$ENV{PATH}``.  A search path will be converted to a cmake-style list
-  separated by ``;`` characters (on non-Windows platforms, this essentially
-  means ``:`` separators are replaced with ``;``).  The result of the
-  conversion is stored in the ``<out-var>`` variable.
+  ``$ENV{PATH}``.  A search path will be converted to a
+  :ref:`semicolon-separated list <CMake Language Lists>` (on non-Windows
+  platforms, this essentially means ``:`` separators are replaced with ``;``).
 
   When the ``NORMALIZE`` option is specified, the path is :ref:`normalized
   <Normalization>` before the conversion.
 
+  See :ref:`Creating a Path Variable` for details on the output variable.
+
   .. note::
     Unlike most other ``cmake_path()`` subcommands, the ``CONVERT`` subcommand
     takes a literal string as input, not the name of a variable.
@@ -704,16 +738,18 @@
   :target:
     CONVERT ... TO_NATIVE_PATH_LIST
 
-  Converts a cmake-style ``<input>`` path into a native path with
+  Converts a CMake-style ``<input>`` path into a native path with
   platform-specific slashes (``\`` on Windows hosts and ``/`` elsewhere).
-  The input can be a single path or a cmake-style list.  A list will be
-  converted into a native search path (``;``-separated on Windows,
-  ``:``-separated on other platforms).  The result of the conversion is
-  stored in the ``<out-var>`` variable.
+
+  The input can be a single path or a :ref:`semicolon-separated list
+  <CMake Language Lists>`.  A list will be converted into a native search path
+  (``;``-separated on Windows, ``:``-separated on other platforms).
 
   When the ``NORMALIZE`` option is specified, the path is :ref:`normalized
   <Normalization>` before the conversion.
 
+  See :ref:`Creating a Path Variable` for details on the output variable.
+
   .. note::
     Unlike most other ``cmake_path()`` subcommands, the ``CONVERT`` subcommand
     takes a literal string as input, not the name of a variable.
@@ -744,3 +780,5 @@
   ``p2`` that compare equal (:cref:`COMPARE ... EQUAL`), the hash value of
   ``p1`` is equal to the hash value of ``p2``.  The path is always
   :ref:`normalized <Normalization>` before the hash is computed.
+
+  See :ref:`Creating a Path Variable` for details on the output variable.
diff --git a/Help/command/export.rst b/Help/command/export.rst
index 91c3cd8..0ecdbd9 100644
--- a/Help/command/export.rst
+++ b/Help/command/export.rst
@@ -153,9 +153,6 @@
          [CXX_MODULES_DIRECTORY <directory>])
 
 .. versionadded:: 4.3
-.. note::
-
-  Experimental. Gated by ``CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO``.
 
 Creates a file in the |CPS|_ that may be included by outside projects to import
 targets named by ``<target>...`` from the current project's build tree.  See
diff --git a/Help/command/file.rst b/Help/command/file.rst
index 75335dc..9334fa0 100644
--- a/Help/command/file.rst
+++ b/Help/command/file.rst
@@ -710,12 +710,12 @@
   file(TO_CMAKE_PATH "<path>" <variable>)
   file(TO_NATIVE_PATH "<path>" <variable>)
 
-  The ``TO_CMAKE_PATH`` mode converts a native ``<path>`` into a cmake-style
+  The ``TO_CMAKE_PATH`` mode converts a native ``<path>`` into a CMake-style
   path with forward-slashes (``/``).  The input can be a single path or a
   system search path like ``$ENV{PATH}``.  A search path will be converted
-  to a cmake-style list separated by ``;`` characters.
+  to a :ref:`semicolon-separated list <CMake Language Lists>`.
 
-  The ``TO_NATIVE_PATH`` mode converts a cmake-style ``<path>`` into a native
+  The ``TO_NATIVE_PATH`` mode converts a CMake-style ``<path>`` into a native
   path with platform-specific slashes (``\`` on Windows hosts and ``/``
   elsewhere).
 
diff --git a/Help/command/find_package.rst b/Help/command/find_package.rst
index 2a6df20..2432434 100644
--- a/Help/command/find_package.rst
+++ b/Help/command/find_package.rst
@@ -75,23 +75,25 @@
 .. _`Config mode`:
 
 **Config mode**
-  In this mode, CMake searches for a file called
-  ``<lowercasePackageName>-config.cmake`` or ``<PackageName>Config.cmake``.
-  It will also look for ``<lowercasePackageName>-config-version.cmake`` or
+  In this mode, CMake searches for a file matching any of:
+
+  * ``<lowercasePackageName>-config.cmake``
+  * ``<PackageName>Config.cmake``
+  * ``<PackageName>.cps``
+  * ``<lowercasePackageName>.cps``
+
+  If one of the first two is found, CMake will also look respectively, for
+  ``<lowercasePackageName>-config-version.cmake`` or
   ``<PackageName>ConfigVersion.cmake`` if version details were specified
   (see :ref:`version selection` for an explanation of how these separate
-  version files are used).
+  version files are used).  The first two options are CMake-script package
+  descriptions.  The latter two are |CPS|_ (CPS) package descriptions, which
+  are more portable and include version information in the 'base' file.  Aside
+  from any explicitly noted exceptions, any references to "config files",
+  "config mode", "package configuration files", and so forth refer equally to
+  both CPS and CMake-script files.
 
   .. note::
-    If the experimental ``CMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES`` is enabled,
-    files named ``<PackageName>.cps`` and ``<lowercasePackageName>.cps`` are
-    also considered.  These files provide package information according to the
-    |CPS|_ (CPS), which is more portable than CMake script.  Aside from any
-    explicitly noted exceptions, any references to "config files", "config
-    mode", "package configuration files", and so forth refer equally to both
-    CPS and CMake-script files.  This functionality is a work in progress, and
-    some features may be missing.
-
     Search is implemented in a manner that will tend to prefer |CPS| files
     over CMake-script config files in most cases.  Specifying ``CONFIGS``
     suppresses consideration of CPS files.
@@ -312,8 +314,14 @@
 also considered when determining whether to redirect the call to a package
 provided by :module:`FetchContent`.
 
-The command searches for a file called ``<PackageName>Config.cmake`` or
-``<lowercasePackageName>-config.cmake`` for each name specified.
+The command searches for a file whose name, for each package name specified,
+matches any of:
+
+* ``<PackageName>Config.cmake``
+* ``<lowercasePackageName>-config.cmake``
+* ``<PackageName>.cps``
+* ``<lowercasePackageName>.cps``
+
 A replacement set of possible configuration file names may be given
 using the ``CONFIGS`` option.  The :ref:`search procedure` is specified below.
 Once found, any :ref:`version constraint <version selection>` is checked,
@@ -324,9 +332,8 @@
 
 .. note::
 
-  If the experimental ``CMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES`` is enabled,
-  files named ``<PackageName>.cps`` and ``<lowercasePackageName>.cps`` are
-  also considered, unless ``CONFIGS`` is given.
+  Because CPS files are not permitted to have names that do *not* match the
+  package name, specifying ``CONFIGS`` will suppress searcing for CPS files.
 
 All configuration files which have been considered by CMake while
 searching for the package with an appropriate version are stored in the
@@ -396,7 +403,7 @@
 
 .. [#p1] .. versionadded:: 3.25
 
-.. [#p2] .. versionadded:: 4.0
+.. [#p2] .. versionadded:: 4.3
 
 On systems supporting macOS :prop_tgt:`FRAMEWORK` and :prop_tgt:`BUNDLE`, the
 following directories are searched for Frameworks or Application Bundles
@@ -416,7 +423,7 @@
  ``<prefix>/<name>.app/Contents/Resources/CMake/``                 A
 =============================================================== ==========
 
-.. [#p3] .. versionadded:: 4.0
+.. [#p3] .. versionadded:: 4.3
 
 When searching the above paths, ``find_package`` will only look for ``.cps``
 files in search paths which contain ``/cps/``, and will only look for
@@ -986,15 +993,6 @@
 ``<PackageName>_FOUND`` to false to tell ``find_package`` that component
 requirements are not satisfied.
 
-.. _CPS: https://cps-org.github.io/cps/
-.. |CPS| replace:: Common Package Specification
-
-.. _cps-compat_version: https://cps-org.github.io/cps/schema.html#compat-version
-.. |cps-compat_version| replace:: ``compat_version``
-
-.. _cps-version_schema: https://cps-org.github.io/cps/schema.html#version-schema
-.. |cps-version_schema| replace:: ``version_schema``
-
 CPS Transitive Requirements
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -1028,3 +1026,12 @@
 targets.  Those targets must be named ``<PackageName>::<ComponentName>``, in
 conformance with CPS convention, or the check will consider the package not
 found.
+
+.. _CPS: https://cps-org.github.io/cps/
+.. |CPS| replace:: Common Package Specification
+
+.. _cps-compat_version: https://cps-org.github.io/cps/schema.html#compat-version
+.. |cps-compat_version| replace:: ``compat_version``
+
+.. _cps-version_schema: https://cps-org.github.io/cps/schema.html#version-schema
+.. |cps-version_schema| replace:: ``version_schema``
diff --git a/Help/command/install.rst b/Help/command/install.rst
index b2ac69a..68fda6c 100644
--- a/Help/command/install.rst
+++ b/Help/command/install.rst
@@ -975,10 +975,7 @@
 .. signature::
   install(PACKAGE_INFO <package-name> [...])
 
-  .. versionadded:: 3.31
-  .. note::
-
-    Experimental. Gated by ``CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO``.
+  .. versionadded:: 4.3
 
   Installs a |CPS|_ ("CPS") file exporting targets for dependent projects:
 
@@ -1275,6 +1272,11 @@
   In any case, any metadata values specified in the ``install`` command will
   take precedence.
 
+  Note that an SBOM file cannot be generated for targets with generator
+  expressions contained in their :prop_tgt:`LINK_LIBRARIES` or
+  :prop_tgt:`INTERFACE_LINK_LIBRARIES` properties, unless the generator
+  expressions are guarded by :genex:`LINK_ONLY`.
+
 Examples
 ^^^^^^^^
 
diff --git a/Help/command/project.rst b/Help/command/project.rst
index a77e0b1..ad4f32e 100644
--- a/Help/command/project.rst
+++ b/Help/command/project.rst
@@ -89,10 +89,7 @@
     :variable:`CMAKE_PROJECT_VERSION`.
 
 ``COMPAT_VERSION <version>``
-  .. versionadded:: 4.1
-  .. note::
-
-    Experimental. Gated by ``CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO``.
+  .. versionadded:: 4.3
 
   Optional; requires ``VERSION`` also be set.
 
@@ -101,17 +98,14 @@
   and sets the variables
 
   * :variable:`PROJECT_COMPAT_VERSION`,
-    :variable:`<PROJECT-NAME>_COMPAT_VERSION`
+    :variable:`<PROJECT-NAME>_COMPAT_VERSION`.
 
-    When the ``project()`` command is called from the top-level
-    ``CMakeLists.txt``, then the compatibility version is also stored in the
-    variable :variable:`CMAKE_PROJECT_COMPAT_VERSION`.
+  When the ``project()`` command is called from the top-level
+  ``CMakeLists.txt``, then the compatibility version is also stored in the
+  variable :variable:`CMAKE_PROJECT_COMPAT_VERSION`.
 
 ``SPDX_LICENSE <license-string>``
-  .. versionadded:: 4.2
-  .. note::
-
-    Experimental. Gated by ``CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO``.
+  .. versionadded:: 4.3
 
   Optional.
   Sets the variables
diff --git a/Help/cpack_gen/wix.rst b/Help/cpack_gen/wix.rst
index fce5c38..738ee7c 100644
--- a/Help/cpack_gen/wix.rst
+++ b/Help/cpack_gen/wix.rst
@@ -408,8 +408,9 @@
  In 32-bit builds the token will expand empty while in 64-bit builds
  it will expand to ``64``.
 
- When unset generated installers will default installing to
- ``ProgramFiles<64>Folder``.
+ When unset generated installers will install to
+ ``LocalAppDataFolder`` if :variable:`CPACK_WIX_INSTALL_SCOPE` is ``perUser``,
+ and to ``ProgramFiles<64>Folder`` otherwise.
 
 .. variable:: CPACK_WIX_ROOT
 
@@ -451,7 +452,7 @@
  .. versionadded:: 3.29
 
  This variable can be optionally set to specify the ``InstallScope``
- of the installer:
+ of the installer (see https://docs.firegiant.com/wix3/xsd/wix/package/):
 
  ``perMachine``
    Create an installer that installs for all users and requires
@@ -461,7 +462,20 @@
    This is the default.  See policy :policy:`CMP0172`.
 
  ``perUser``
-   Not yet supported. This is reserved for future use.
+   Create an installer that installs only for the current user
+   and does not require administrative privileges. Start menu entries created
+   by the installer are visible only to the current user.
+
+   To enable per-user installation, the installer has to generate some
+   additional registry entries to serve as "key paths" for installed
+   components (see https://learn.microsoft.com/en-us/windows/win32/msi/ice38).
+   These registry entries are created under ``HKEY_CURRENT_USER``, using the
+   path specified by the :variable:`CPACK_WIX_COMPONENT_KEYS_REGISTRY_PATH`
+   variable.
+
+   .. versionchanged:: 4.3
+
+     Before CMake 4.3, this value was reserved for future use and not supported.
 
  ``NONE``
    Create an installer without any ``InstallScope`` attribute.
@@ -477,16 +491,30 @@
      but the start menu entry and uninstaller registration are created only
      for the current user.
 
-   .. warning::
+ .. warning::
+   Installations performed by installers created with different
+   ``InstallScope`` values cannot be cleanly updated or replaced by each other.
+   For example, to transition a project's installers from ``NONE`` to
+   ``perMachine``, or from ``perMachine`` to ``perUser``, the latter installer
+   should be distributed with instructions to first manually uninstall
+   any older version.
 
-     An installation performed by an installer created without any
-     ``InstallScope`` cannot be cleanly updated or replaced by an
-     installer with an ``InstallScope``.  In order to transition
-     a project's installers from ``NONE`` to ``perMachine``, the
-     latter installer should be distributed with instructions to
-     first manually uninstall any older version.
+.. variable:: CPACK_WIX_COMPONENT_KEYS_REGISTRY_PATH
 
- See https://docs.firegiant.com/wix3/xsd/wix/package/
+ .. versionadded:: 4.3
+
+ This variable determines the registry path under ``HKEY_CURRENT_USER``
+ where the installer will create registry entries to serve as "key paths"
+ for components if :variable:`CPACK_WIX_INSTALL_SCOPE` is set to ``perUser``.
+
+ Use forward slashes (``/``) as path separators to avoid issues with escapes;
+ they will be converted to backslashes (``\``) by the WIX generator.
+
+ Default value is ``Software/<Vendor>/<PackageName>/Components``,
+ where ``<Vendor>`` is taken from :variable:`CPACK_PACKAGE_VENDOR`,
+ and ``<PackageName>`` is taken from :variable:`CPACK_PACKAGE_NAME`.
+
+ Example: ``Software/MyCompany/MyProduct/Components``
 
 .. variable:: CPACK_WIX_CAB_PER_COMPONENT
 
diff --git a/Help/dev/experimental.rst b/Help/dev/experimental.rst
index fd85b81..caa089d 100644
--- a/Help/dev/experimental.rst
+++ b/Help/dev/experimental.rst
@@ -39,31 +39,11 @@
   using the ``CMAKE_EXPORT_FIND_PACKAGE_NAME`` variable and/or
 ``EXPORT_FIND_PACKAGE_NAME`` target property.
 
-Export |CPS| Package Information
-================================
-
-In order to activate support for this experimental feature, set
-
-* variable ``CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO`` to
-* value ``7fa7d13b-8308-4dc7-af39-9e450456d68f``.
-
-This UUID may change in future versions of CMake.  Be sure to use the value
-documented here by the source tree of the version of CMake with which you are
-experimenting.
-
-When activated, this experimental feature provides the following:
-
-* The experimental ``export(PACKAGE_INFO)`` and ``install(PACKAGE_INFO)``
-  commands are available to export package information in the |CPS|_ format.
-  See :command:`install(PACKAGE_INFO)` for a complete overview of the command.
-
 Export |CPS| Package Information for ``install(EXPORT)``
-""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+========================================================
 
 In order to activate support for this experimental feature, set
 
-* variable ``CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO`` to
-* value ``b80be207-778e-46ba-8080-b23bba22639e``.
 * variable ``CMAKE_EXPERIMENTAL_MAPPED_PACKAGE_INFO`` to
 * value ``ababa1b5-7099-495f-a9cd-e22d38f274f2``.
 
@@ -76,24 +56,6 @@
 * Setting ``CMAKE_INSTALL_EXPORTS_AS_PACKAGE_INFO`` enables generation of
   package information in the |CPS|_ format via the ``install(EXPORT)`` command.
 
-Find/Import |CPS| Packages
-==========================
-
-In order to activate support for this experimental feature, set
-
-* variable ``CMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES`` to
-* value ``e82e467b-f997-4464-8ace-b00808fff261``.
-
-This UUID may change in future versions of CMake.  Be sure to use the value
-documented here by the source tree of the version of CMake with which you are
-experimenting.
-
-When activated, this experimental feature provides the following:
-
-* The :command:`find_package` command will also search for packages which are
-  described using |CPS|_. Refer to the :command:`find_package` documentation
-  for details.
-
 Build database support
 ======================
 
diff --git a/Help/manual/cmake-cxxmodules.7.rst b/Help/manual/cmake-cxxmodules.7.rst
index c676296..35ad2a2 100644
--- a/Help/manual/cmake-cxxmodules.7.rst
+++ b/Help/manual/cmake-cxxmodules.7.rst
@@ -88,6 +88,10 @@
 The :variable:`CMAKE_CXX_COMPILER_IMPORT_STD` variable lists standard levels
 which have support for ``import std`` in the active C++ toolchain.
 
+Additionally, only the :ref:`Ninja Generators` currently support
+``import std`` at this time because :ref:`Visual Studio Generators` do not
+support building :term:`BMIs <BMI>` for ``IMPORTED`` targets.
+
 Generator Support
 =================
 
diff --git a/Help/manual/cmake-language.7.rst b/Help/manual/cmake-language.7.rst
index 908c46c..777ef0b 100644
--- a/Help/manual/cmake-language.7.rst
+++ b/Help/manual/cmake-language.7.rst
@@ -78,6 +78,11 @@
 
 .. _Byte-Order Mark: https://en.wikipedia.org/wiki/Byte_order_mark
 
+.. versionadded:: 4.3
+
+  The :command:`cmake_host_system_information` command's ``LOCALE_CHARSET``
+  query returns the expected character set encoding.
+
 Source Files
 ------------
 
diff --git a/Help/release/dev/cmake-locale.rst b/Help/release/dev/cmake-locale.rst
new file mode 100644
index 0000000..ce91492
--- /dev/null
+++ b/Help/release/dev/cmake-locale.rst
@@ -0,0 +1,6 @@
+cmake-locale
+------------
+
+* The :command:`cmake_host_system_information` command gained a
+  ``LOCALE_CHARSET`` query for the expected :manual:`cmake-language(7)`
+  script encoding.
diff --git a/Help/release/dev/cpack-wix-perUser.rst b/Help/release/dev/cpack-wix-perUser.rst
new file mode 100644
index 0000000..b35aef0
--- /dev/null
+++ b/Help/release/dev/cpack-wix-perUser.rst
@@ -0,0 +1,5 @@
+cpack-wix-perUser
+-----------------
+
+* The :cpack_gen:`CPack WIX Generator` now supports per-user installers
+  by setting :variable:`CPACK_WIX_INSTALL_SCOPE` to ``perUser``.
diff --git a/Help/variable/CMAKE_PROJECT_COMPAT_VERSION.rst b/Help/variable/CMAKE_PROJECT_COMPAT_VERSION.rst
index e32d381..1b5e96a 100644
--- a/Help/variable/CMAKE_PROJECT_COMPAT_VERSION.rst
+++ b/Help/variable/CMAKE_PROJECT_COMPAT_VERSION.rst
@@ -1,24 +1,20 @@
 CMAKE_PROJECT_COMPAT_VERSION
 ----------------------------
 
-.. versionadded:: 4.1
-
-.. note::
-
-  Experimental. Gated by ``CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO``.
+.. versionadded:: 4.3
 
 The compatibility version of the top level project.
 
-This variable holds the compatibility version of the project as specified in the
-top level CMakeLists.txt file by a :command:`project` command.  In the event
-that the top level CMakeLists.txt contains multiple :command:`project` calls,
-the most recently called one from that top level CMakeLists.txt will determine
-the value that ``CMAKE_PROJECT_COMPAT_VERSION`` contains.  For example, consider
-the following top level CMakeLists.txt:
+This variable holds the compatibility version of the project as specified in
+the top level CMakeLists.txt file by a :command:`project` command.  In the
+event that the top level CMakeLists.txt contains multiple :command:`project`
+calls, the most recently called one from that top level CMakeLists.txt will
+determine the value that ``CMAKE_PROJECT_COMPAT_VERSION`` contains.  For
+example, consider the following top level CMakeLists.txt:
 
 .. code-block:: cmake
 
-  cmake_minimum_required(VERSION 4.1)
+  cmake_minimum_required(VERSION 4.3)
   project(First VERSION 9.0 COMPAT_VERSION 1.2.3)
   project(Second VERSION 9.0 COMPAT_VERSION 3.4.5)
   add_subdirectory(sub)
@@ -36,6 +32,6 @@
 
   CMAKE_PROJECT_COMPAT_VERSION = 3.4.5
 
-To obtain the version from the most recent call to :command:`project` in
-the current directory scope or above, see the :variable:`PROJECT_COMPAT_VERSION`
-variable.
+To obtain the version from the most recent call to :command:`project`
+in the current directory scope or above, see the
+:variable:`PROJECT_COMPAT_VERSION` variable.
diff --git a/Help/variable/CMAKE_PROJECT_SPDX_LICENSE.rst b/Help/variable/CMAKE_PROJECT_SPDX_LICENSE.rst
index 0cbde7c..3164b7e 100644
--- a/Help/variable/CMAKE_PROJECT_SPDX_LICENSE.rst
+++ b/Help/variable/CMAKE_PROJECT_SPDX_LICENSE.rst
@@ -1,11 +1,7 @@
 CMAKE_PROJECT_SPDX_LICENSE
 --------------------------
 
-.. versionadded:: 4.2
-
-.. note::
-
-  Experimental. Gated by ``CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO``.
+.. versionadded:: 4.3
 
 The license(s) of the top level project.
 
@@ -18,7 +14,7 @@
 
 .. code-block:: cmake
 
-  cmake_minimum_required(VERSION 4.2)
+  cmake_minimum_required(VERSION 4.3)
   project(First SPDX_LICENSE "BSD-3-Clause")
   project(Second SPDX_LICENSE "BSD-3-Clause AND CC-BY-SA-4.0")
   add_subdirectory(sub)
diff --git a/Help/variable/CTEST_BINARY_DIRECTORY.rst b/Help/variable/CTEST_BINARY_DIRECTORY.rst
index 8413e37..ec30f2d 100644
--- a/Help/variable/CTEST_BINARY_DIRECTORY.rst
+++ b/Help/variable/CTEST_BINARY_DIRECTORY.rst
@@ -4,4 +4,4 @@
 .. versionadded:: 3.1
 
 Specify the CTest ``BuildDirectory`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_BUILD_COMMAND.rst b/Help/variable/CTEST_BUILD_COMMAND.rst
index 31c44e2..e4110c7 100644
--- a/Help/variable/CTEST_BUILD_COMMAND.rst
+++ b/Help/variable/CTEST_BUILD_COMMAND.rst
@@ -4,4 +4,4 @@
 .. versionadded:: 3.1
 
 Specify the CTest ``MakeCommand`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_BUILD_NAME.rst b/Help/variable/CTEST_BUILD_NAME.rst
index 3d08397..d6b0636 100644
--- a/Help/variable/CTEST_BUILD_NAME.rst
+++ b/Help/variable/CTEST_BUILD_NAME.rst
@@ -4,4 +4,4 @@
 .. versionadded:: 3.1
 
 Specify the CTest ``BuildName`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_BZR_COMMAND.rst b/Help/variable/CTEST_BZR_COMMAND.rst
index 0c05d1a..8927886 100644
--- a/Help/variable/CTEST_BZR_COMMAND.rst
+++ b/Help/variable/CTEST_BZR_COMMAND.rst
@@ -4,4 +4,4 @@
 .. versionadded:: 3.1
 
 Specify the CTest ``BZRCommand`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_BZR_UPDATE_OPTIONS.rst b/Help/variable/CTEST_BZR_UPDATE_OPTIONS.rst
index 4dd5e5b..475dab2 100644
--- a/Help/variable/CTEST_BZR_UPDATE_OPTIONS.rst
+++ b/Help/variable/CTEST_BZR_UPDATE_OPTIONS.rst
@@ -4,4 +4,4 @@
 .. versionadded:: 3.1
 
 Specify the CTest ``BZRUpdateOptions`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_CHANGE_ID.rst b/Help/variable/CTEST_CHANGE_ID.rst
index a6d15f7..5202020 100644
--- a/Help/variable/CTEST_CHANGE_ID.rst
+++ b/Help/variable/CTEST_CHANGE_ID.rst
@@ -4,7 +4,7 @@
 .. versionadded:: 3.4
 
 Specify the CTest ``ChangeId`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
 
 This setting allows CTest to pass arbitrary information about this
 build up to CDash.  One use of this feature is to allow CDash to
diff --git a/Help/variable/CTEST_CHECKOUT_COMMAND.rst b/Help/variable/CTEST_CHECKOUT_COMMAND.rst
index 852c28e..2203d6b 100644
--- a/Help/variable/CTEST_CHECKOUT_COMMAND.rst
+++ b/Help/variable/CTEST_CHECKOUT_COMMAND.rst
@@ -4,4 +4,4 @@
 .. 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.
+the source directory in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_CONFIGURATION_TYPE.rst b/Help/variable/CTEST_CONFIGURATION_TYPE.rst
index 932f81d..6ae4a34 100644
--- a/Help/variable/CTEST_CONFIGURATION_TYPE.rst
+++ b/Help/variable/CTEST_CONFIGURATION_TYPE.rst
@@ -4,7 +4,7 @@
 .. versionadded:: 3.1
 
 Specify the CTest ``DefaultCTestConfigurationType`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
 
 If the configuration type is set via :option:`-C \<cfg\> <ctest -C>` from the command line
 then this variable is populated accordingly.
diff --git a/Help/variable/CTEST_CONFIGURE_COMMAND.rst b/Help/variable/CTEST_CONFIGURE_COMMAND.rst
index 992ef47..90c50f4 100644
--- a/Help/variable/CTEST_CONFIGURE_COMMAND.rst
+++ b/Help/variable/CTEST_CONFIGURE_COMMAND.rst
@@ -4,4 +4,4 @@
 .. versionadded:: 3.1
 
 Specify the CTest ``ConfigureCommand`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_COVERAGE_COMMAND.rst b/Help/variable/CTEST_COVERAGE_COMMAND.rst
index 3df2262..8168b33 100644
--- a/Help/variable/CTEST_COVERAGE_COMMAND.rst
+++ b/Help/variable/CTEST_COVERAGE_COMMAND.rst
@@ -4,7 +4,7 @@
 .. versionadded:: 3.1
 
 Specify the CTest ``CoverageCommand`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
 
 Cobertura
 '''''''''
diff --git a/Help/variable/CTEST_COVERAGE_EXTRA_FLAGS.rst b/Help/variable/CTEST_COVERAGE_EXTRA_FLAGS.rst
index 39d9b5d..bae5c79 100644
--- a/Help/variable/CTEST_COVERAGE_EXTRA_FLAGS.rst
+++ b/Help/variable/CTEST_COVERAGE_EXTRA_FLAGS.rst
@@ -4,4 +4,4 @@
 .. versionadded:: 3.1
 
 Specify the CTest ``CoverageExtraFlags`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_CURL_OPTIONS.rst b/Help/variable/CTEST_CURL_OPTIONS.rst
index 45e84ed..07557e9 100644
--- a/Help/variable/CTEST_CURL_OPTIONS.rst
+++ b/Help/variable/CTEST_CURL_OPTIONS.rst
@@ -8,4 +8,4 @@
 .. versionadded:: 3.1
 
 Specify the CTest ``CurlOptions`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_CVS_COMMAND.rst b/Help/variable/CTEST_CVS_COMMAND.rst
index 7932070..797a4e7 100644
--- a/Help/variable/CTEST_CVS_COMMAND.rst
+++ b/Help/variable/CTEST_CVS_COMMAND.rst
@@ -4,4 +4,4 @@
 .. versionadded:: 3.1
 
 Specify the CTest ``CVSCommand`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_CVS_UPDATE_OPTIONS.rst b/Help/variable/CTEST_CVS_UPDATE_OPTIONS.rst
index 359e708..6d9288a 100644
--- a/Help/variable/CTEST_CVS_UPDATE_OPTIONS.rst
+++ b/Help/variable/CTEST_CVS_UPDATE_OPTIONS.rst
@@ -4,4 +4,4 @@
 .. versionadded:: 3.1
 
 Specify the CTest ``CVSUpdateOptions`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_DROP_LOCATION.rst b/Help/variable/CTEST_DROP_LOCATION.rst
index f66793b..3955193 100644
--- a/Help/variable/CTEST_DROP_LOCATION.rst
+++ b/Help/variable/CTEST_DROP_LOCATION.rst
@@ -4,4 +4,4 @@
 .. versionadded:: 3.1
 
 Specify the CTest ``DropLocation`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_DROP_METHOD.rst b/Help/variable/CTEST_DROP_METHOD.rst
index 3a84658..6a0d0a7 100644
--- a/Help/variable/CTEST_DROP_METHOD.rst
+++ b/Help/variable/CTEST_DROP_METHOD.rst
@@ -4,4 +4,4 @@
 .. versionadded:: 3.1
 
 Specify the CTest ``DropMethod`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_DROP_SITE.rst b/Help/variable/CTEST_DROP_SITE.rst
index 9c871e3..be64d72 100644
--- a/Help/variable/CTEST_DROP_SITE.rst
+++ b/Help/variable/CTEST_DROP_SITE.rst
@@ -4,4 +4,4 @@
 .. versionadded:: 3.1
 
 Specify the CTest ``DropSite`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_DROP_SITE_CDASH.rst b/Help/variable/CTEST_DROP_SITE_CDASH.rst
index dcdb286..7d09a36 100644
--- a/Help/variable/CTEST_DROP_SITE_CDASH.rst
+++ b/Help/variable/CTEST_DROP_SITE_CDASH.rst
@@ -4,4 +4,4 @@
 .. versionadded:: 3.1
 
 Specify the CTest ``IsCDash`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_DROP_SITE_PASSWORD.rst b/Help/variable/CTEST_DROP_SITE_PASSWORD.rst
index 8259651..b2f684e 100644
--- a/Help/variable/CTEST_DROP_SITE_PASSWORD.rst
+++ b/Help/variable/CTEST_DROP_SITE_PASSWORD.rst
@@ -4,4 +4,4 @@
 .. versionadded:: 3.1
 
 Specify the CTest ``DropSitePassword`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_DROP_SITE_USER.rst b/Help/variable/CTEST_DROP_SITE_USER.rst
index 8d2e3a3..07f115e 100644
--- a/Help/variable/CTEST_DROP_SITE_USER.rst
+++ b/Help/variable/CTEST_DROP_SITE_USER.rst
@@ -4,4 +4,4 @@
 .. versionadded:: 3.1
 
 Specify the CTest ``DropSiteUser`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_EXTRA_SUBMIT_FILES.rst b/Help/variable/CTEST_EXTRA_SUBMIT_FILES.rst
index 21f801f..a721ecf 100644
--- a/Help/variable/CTEST_EXTRA_SUBMIT_FILES.rst
+++ b/Help/variable/CTEST_EXTRA_SUBMIT_FILES.rst
@@ -2,4 +2,4 @@
 ------------------------
 
 Specify files for :command:`ctest_submit(PARTS ExtraFiles)` to submit
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_GIT_COMMAND.rst b/Help/variable/CTEST_GIT_COMMAND.rst
index eb9b440..01ffca7 100644
--- a/Help/variable/CTEST_GIT_COMMAND.rst
+++ b/Help/variable/CTEST_GIT_COMMAND.rst
@@ -4,4 +4,4 @@
 .. versionadded:: 3.1
 
 Specify the CTest ``GITCommand`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_GIT_INIT_SUBMODULES.rst b/Help/variable/CTEST_GIT_INIT_SUBMODULES.rst
index 529bfc7..6e4b9c1 100644
--- a/Help/variable/CTEST_GIT_INIT_SUBMODULES.rst
+++ b/Help/variable/CTEST_GIT_INIT_SUBMODULES.rst
@@ -4,4 +4,4 @@
 .. versionadded:: 3.6
 
 Specify the CTest ``GITInitSubmodules`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_GIT_UPDATE_CUSTOM.rst b/Help/variable/CTEST_GIT_UPDATE_CUSTOM.rst
index 82a8a6a..1ae1099 100644
--- a/Help/variable/CTEST_GIT_UPDATE_CUSTOM.rst
+++ b/Help/variable/CTEST_GIT_UPDATE_CUSTOM.rst
@@ -4,4 +4,4 @@
 .. versionadded:: 3.1
 
 Specify the CTest ``GITUpdateCustom`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_GIT_UPDATE_OPTIONS.rst b/Help/variable/CTEST_GIT_UPDATE_OPTIONS.rst
index 1568239..a063ba3 100644
--- a/Help/variable/CTEST_GIT_UPDATE_OPTIONS.rst
+++ b/Help/variable/CTEST_GIT_UPDATE_OPTIONS.rst
@@ -4,4 +4,4 @@
 .. versionadded:: 3.1
 
 Specify the CTest ``GITUpdateOptions`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_HG_COMMAND.rst b/Help/variable/CTEST_HG_COMMAND.rst
index 3372fe4..426cfd5 100644
--- a/Help/variable/CTEST_HG_COMMAND.rst
+++ b/Help/variable/CTEST_HG_COMMAND.rst
@@ -4,4 +4,4 @@
 .. versionadded:: 3.1
 
 Specify the CTest ``HGCommand`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_HG_UPDATE_OPTIONS.rst b/Help/variable/CTEST_HG_UPDATE_OPTIONS.rst
index 85c6b03..751b300 100644
--- a/Help/variable/CTEST_HG_UPDATE_OPTIONS.rst
+++ b/Help/variable/CTEST_HG_UPDATE_OPTIONS.rst
@@ -4,4 +4,4 @@
 .. versionadded:: 3.1
 
 Specify the CTest ``HGUpdateOptions`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_LABELS_FOR_SUBPROJECTS.rst b/Help/variable/CTEST_LABELS_FOR_SUBPROJECTS.rst
index dd6d125..4c1ec4b 100644
--- a/Help/variable/CTEST_LABELS_FOR_SUBPROJECTS.rst
+++ b/Help/variable/CTEST_LABELS_FOR_SUBPROJECTS.rst
@@ -4,4 +4,4 @@
 .. versionadded:: 3.10
 
 Specify the CTest ``LabelsForSubprojects`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_MEMORYCHECK_COMMAND.rst b/Help/variable/CTEST_MEMORYCHECK_COMMAND.rst
index 25f1bd9..1c86357 100644
--- a/Help/variable/CTEST_MEMORYCHECK_COMMAND.rst
+++ b/Help/variable/CTEST_MEMORYCHECK_COMMAND.rst
@@ -4,4 +4,4 @@
 .. versionadded:: 3.1
 
 Specify the CTest ``MemoryCheckCommand`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_MEMORYCHECK_COMMAND_OPTIONS.rst b/Help/variable/CTEST_MEMORYCHECK_COMMAND_OPTIONS.rst
index 51830d5..f2c91e3 100644
--- a/Help/variable/CTEST_MEMORYCHECK_COMMAND_OPTIONS.rst
+++ b/Help/variable/CTEST_MEMORYCHECK_COMMAND_OPTIONS.rst
@@ -4,4 +4,4 @@
 .. versionadded:: 3.1
 
 Specify the CTest ``MemoryCheckCommandOptions`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_MEMORYCHECK_SANITIZER_OPTIONS.rst b/Help/variable/CTEST_MEMORYCHECK_SANITIZER_OPTIONS.rst
index b6fee2e..d9f3eea 100644
--- a/Help/variable/CTEST_MEMORYCHECK_SANITIZER_OPTIONS.rst
+++ b/Help/variable/CTEST_MEMORYCHECK_SANITIZER_OPTIONS.rst
@@ -4,7 +4,7 @@
 .. versionadded:: 3.1
 
 Specify the CTest ``MemoryCheckSanitizerOptions`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
 
 CTest prepends correct sanitizer options ``*_OPTIONS``
 environment variable to executed command. CTests adds
diff --git a/Help/variable/CTEST_MEMORYCHECK_SUPPRESSIONS_FILE.rst b/Help/variable/CTEST_MEMORYCHECK_SUPPRESSIONS_FILE.rst
index a61a3ef..fe54eb9 100644
--- a/Help/variable/CTEST_MEMORYCHECK_SUPPRESSIONS_FILE.rst
+++ b/Help/variable/CTEST_MEMORYCHECK_SUPPRESSIONS_FILE.rst
@@ -4,4 +4,4 @@
 .. versionadded:: 3.1
 
 Specify the CTest ``MemoryCheckSuppressionFile`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_MEMORYCHECK_TYPE.rst b/Help/variable/CTEST_MEMORYCHECK_TYPE.rst
index 80353a4..d412e79 100644
--- a/Help/variable/CTEST_MEMORYCHECK_TYPE.rst
+++ b/Help/variable/CTEST_MEMORYCHECK_TYPE.rst
@@ -4,7 +4,7 @@
 .. versionadded:: 3.1
 
 Specify the CTest ``MemoryCheckType`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
 Valid values are ``Valgrind``, ``Purify``, ``BoundsChecker``, ``DrMemory``,
 ``CudaSanitizer``, ``ThreadSanitizer``, ``AddressSanitizer``, ``LeakSanitizer``,
 ``MemorySanitizer`` and ``UndefinedBehaviorSanitizer``.
diff --git a/Help/variable/CTEST_NIGHTLY_START_TIME.rst b/Help/variable/CTEST_NIGHTLY_START_TIME.rst
index 2d707d5..3ccf50a 100644
--- a/Help/variable/CTEST_NIGHTLY_START_TIME.rst
+++ b/Help/variable/CTEST_NIGHTLY_START_TIME.rst
@@ -4,7 +4,7 @@
 .. versionadded:: 3.1
 
 Specify the CTest ``NightlyStartTime`` setting in a :manual:`ctest(1)`
-dashboard client script.
+:ref:`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
diff --git a/Help/variable/CTEST_NOTES_FILES.rst b/Help/variable/CTEST_NOTES_FILES.rst
index 301b78a..cc66345 100644
--- a/Help/variable/CTEST_NOTES_FILES.rst
+++ b/Help/variable/CTEST_NOTES_FILES.rst
@@ -2,4 +2,4 @@
 -----------------
 
 Specify files for :command:`ctest_submit(PARTS Notes)` to submit
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_P4_CLIENT.rst b/Help/variable/CTEST_P4_CLIENT.rst
index 0778c5b..63c1739 100644
--- a/Help/variable/CTEST_P4_CLIENT.rst
+++ b/Help/variable/CTEST_P4_CLIENT.rst
@@ -4,4 +4,4 @@
 .. versionadded:: 3.1
 
 Specify the CTest ``P4Client`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_P4_COMMAND.rst b/Help/variable/CTEST_P4_COMMAND.rst
index 5cc2a81..61cd4a1 100644
--- a/Help/variable/CTEST_P4_COMMAND.rst
+++ b/Help/variable/CTEST_P4_COMMAND.rst
@@ -4,4 +4,4 @@
 .. versionadded:: 3.1
 
 Specify the CTest ``P4Command`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_P4_OPTIONS.rst b/Help/variable/CTEST_P4_OPTIONS.rst
index 01b6534..b4889f8 100644
--- a/Help/variable/CTEST_P4_OPTIONS.rst
+++ b/Help/variable/CTEST_P4_OPTIONS.rst
@@ -4,4 +4,4 @@
 .. versionadded:: 3.1
 
 Specify the CTest ``P4Options`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_P4_UPDATE_OPTIONS.rst b/Help/variable/CTEST_P4_UPDATE_OPTIONS.rst
index 365aa3f..5dec345 100644
--- a/Help/variable/CTEST_P4_UPDATE_OPTIONS.rst
+++ b/Help/variable/CTEST_P4_UPDATE_OPTIONS.rst
@@ -4,4 +4,4 @@
 .. versionadded:: 3.1
 
 Specify the CTest ``P4UpdateOptions`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_RESOURCE_SPEC_FILE.rst b/Help/variable/CTEST_RESOURCE_SPEC_FILE.rst
index 8e9bf01..294e138 100644
--- a/Help/variable/CTEST_RESOURCE_SPEC_FILE.rst
+++ b/Help/variable/CTEST_RESOURCE_SPEC_FILE.rst
@@ -4,7 +4,7 @@
 .. versionadded:: 3.18
 
 Specify the CTest ``ResourceSpecFile`` setting in a :manual:`ctest(1)`
-dashboard client script.
+:ref:`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
diff --git a/Help/variable/CTEST_SITE.rst b/Help/variable/CTEST_SITE.rst
index 526e6ed..7875b30 100644
--- a/Help/variable/CTEST_SITE.rst
+++ b/Help/variable/CTEST_SITE.rst
@@ -4,4 +4,4 @@
 .. versionadded:: 3.1
 
 Specify the CTest ``Site`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_SOURCE_DIRECTORY.rst b/Help/variable/CTEST_SOURCE_DIRECTORY.rst
index 4c6ac54..84fd1f8 100644
--- a/Help/variable/CTEST_SOURCE_DIRECTORY.rst
+++ b/Help/variable/CTEST_SOURCE_DIRECTORY.rst
@@ -4,4 +4,4 @@
 .. versionadded:: 3.1
 
 Specify the CTest ``SourceDirectory`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_SUBMIT_INACTIVITY_TIMEOUT.rst b/Help/variable/CTEST_SUBMIT_INACTIVITY_TIMEOUT.rst
index 175885a..cdc4ff4 100644
--- a/Help/variable/CTEST_SUBMIT_INACTIVITY_TIMEOUT.rst
+++ b/Help/variable/CTEST_SUBMIT_INACTIVITY_TIMEOUT.rst
@@ -4,4 +4,4 @@
 .. versionadded:: 3.23
 
 Specify the CTest ``SubmitInactivityTimeout`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_SUBMIT_URL.rst b/Help/variable/CTEST_SUBMIT_URL.rst
index b6e7f68..3147b4a 100644
--- a/Help/variable/CTEST_SUBMIT_URL.rst
+++ b/Help/variable/CTEST_SUBMIT_URL.rst
@@ -4,4 +4,4 @@
 .. versionadded:: 3.14
 
 Specify the CTest ``SubmitURL`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_SVN_COMMAND.rst b/Help/variable/CTEST_SVN_COMMAND.rst
index e97acd0..8d8b263 100644
--- a/Help/variable/CTEST_SVN_COMMAND.rst
+++ b/Help/variable/CTEST_SVN_COMMAND.rst
@@ -4,4 +4,4 @@
 .. versionadded:: 3.1
 
 Specify the CTest ``SVNCommand`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_SVN_OPTIONS.rst b/Help/variable/CTEST_SVN_OPTIONS.rst
index 5326e20..3d111cc 100644
--- a/Help/variable/CTEST_SVN_OPTIONS.rst
+++ b/Help/variable/CTEST_SVN_OPTIONS.rst
@@ -4,4 +4,4 @@
 .. versionadded:: 3.1
 
 Specify the CTest ``SVNOptions`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_SVN_UPDATE_OPTIONS.rst b/Help/variable/CTEST_SVN_UPDATE_OPTIONS.rst
index 24e0bbf..0830c2f 100644
--- a/Help/variable/CTEST_SVN_UPDATE_OPTIONS.rst
+++ b/Help/variable/CTEST_SVN_UPDATE_OPTIONS.rst
@@ -4,4 +4,4 @@
 .. versionadded:: 3.1
 
 Specify the CTest ``SVNUpdateOptions`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_TEST_LOAD.rst b/Help/variable/CTEST_TEST_LOAD.rst
index b6a9d62..fed4042 100644
--- a/Help/variable/CTEST_TEST_LOAD.rst
+++ b/Help/variable/CTEST_TEST_LOAD.rst
@@ -4,6 +4,6 @@
 .. versionadded:: 3.4
 
 Specify the ``TestLoad`` setting in the :ref:`CTest Test Step`
-of a :manual:`ctest(1)` dashboard client script.  This sets the
+of a :manual:`ctest(1)` :ref:`Dashboard Client` script.  This sets the
 default value for the ``TEST_LOAD`` option of the :command:`ctest_test`
 command.
diff --git a/Help/variable/CTEST_TEST_TIMEOUT.rst b/Help/variable/CTEST_TEST_TIMEOUT.rst
index 61d9191..f6a1daa 100644
--- a/Help/variable/CTEST_TEST_TIMEOUT.rst
+++ b/Help/variable/CTEST_TEST_TIMEOUT.rst
@@ -4,4 +4,4 @@
 .. versionadded:: 3.1
 
 Specify the CTest ``TimeOut`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_UPDATE_COMMAND.rst b/Help/variable/CTEST_UPDATE_COMMAND.rst
index c4ed645..1084065 100644
--- a/Help/variable/CTEST_UPDATE_COMMAND.rst
+++ b/Help/variable/CTEST_UPDATE_COMMAND.rst
@@ -4,4 +4,4 @@
 .. versionadded:: 3.1
 
 Specify the CTest ``UpdateCommand`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_UPDATE_OPTIONS.rst b/Help/variable/CTEST_UPDATE_OPTIONS.rst
index 96c4b6c..ef2dad3 100644
--- a/Help/variable/CTEST_UPDATE_OPTIONS.rst
+++ b/Help/variable/CTEST_UPDATE_OPTIONS.rst
@@ -4,4 +4,4 @@
 .. versionadded:: 3.1
 
 Specify the CTest ``UpdateOptions`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_UPDATE_VERSION_ONLY.rst b/Help/variable/CTEST_UPDATE_VERSION_ONLY.rst
index f7c863c..c778338 100644
--- a/Help/variable/CTEST_UPDATE_VERSION_ONLY.rst
+++ b/Help/variable/CTEST_UPDATE_VERSION_ONLY.rst
@@ -4,4 +4,4 @@
 .. versionadded:: 3.1
 
 Specify the CTest :ref:`UpdateVersionOnly <UpdateVersionOnly>` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_UPDATE_VERSION_OVERRIDE.rst b/Help/variable/CTEST_UPDATE_VERSION_OVERRIDE.rst
index 87918cb..9f4ecc3 100644
--- a/Help/variable/CTEST_UPDATE_VERSION_OVERRIDE.rst
+++ b/Help/variable/CTEST_UPDATE_VERSION_OVERRIDE.rst
@@ -4,4 +4,4 @@
 .. versionadded:: 3.15
 
 Specify the CTest :ref:`UpdateVersionOverride <UpdateVersionOverride>` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/CTEST_USE_LAUNCHERS.rst b/Help/variable/CTEST_USE_LAUNCHERS.rst
index 728cdc5..3326bad 100644
--- a/Help/variable/CTEST_USE_LAUNCHERS.rst
+++ b/Help/variable/CTEST_USE_LAUNCHERS.rst
@@ -4,4 +4,4 @@
 .. versionadded:: 3.1
 
 Specify the CTest ``UseLaunchers`` setting
-in a :manual:`ctest(1)` dashboard client script.
+in a :manual:`ctest(1)` :ref:`Dashboard Client` script.
diff --git a/Help/variable/PROJECT-NAME_COMPAT_VERSION.rst b/Help/variable/PROJECT-NAME_COMPAT_VERSION.rst
index 29c24b8..5bcd8d5 100644
--- a/Help/variable/PROJECT-NAME_COMPAT_VERSION.rst
+++ b/Help/variable/PROJECT-NAME_COMPAT_VERSION.rst
@@ -1,11 +1,7 @@
 <PROJECT-NAME>_COMPAT_VERSION
 -----------------------------
 
-.. versionadded:: 4.1
-
-.. note::
-
-  Experimental. Gated by ``CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO``.
+.. versionadded:: 4.3
 
 Value given to the ``COMPAT_VERSION`` 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_SPDX_LICENSE.rst b/Help/variable/PROJECT-NAME_SPDX_LICENSE.rst
index 06c395d..0febd48 100644
--- a/Help/variable/PROJECT-NAME_SPDX_LICENSE.rst
+++ b/Help/variable/PROJECT-NAME_SPDX_LICENSE.rst
@@ -1,11 +1,7 @@
 <PROJECT-NAME>_SPDX_LICENSE
 ---------------------------
 
-.. versionadded:: 4.2
-
-.. note::
-
-  Experimental. Gated by ``CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO``.
+.. versionadded:: 4.3
 
 Value given to the ``SPDX_LICENSE`` option of the most recent call to the
 :command:`project` command with project name ``<PROJECT-NAME>``, if any.
diff --git a/Help/variable/PROJECT_COMPAT_VERSION.rst b/Help/variable/PROJECT_COMPAT_VERSION.rst
index cab800c..94bea94 100644
--- a/Help/variable/PROJECT_COMPAT_VERSION.rst
+++ b/Help/variable/PROJECT_COMPAT_VERSION.rst
@@ -1,11 +1,7 @@
 PROJECT_COMPAT_VERSION
 ----------------------
 
-.. versionadded:: 4.1
-
-.. note::
-
-  Experimental. Gated by ``CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO``.
+.. versionadded:: 4.3
 
 Value given to the ``COMPAT_VERSION`` option of the most recent call to the
 :command:`project` command, if any. To obtain the compatibility version of the
diff --git a/Help/variable/PROJECT_SPDX_LICENSE.rst b/Help/variable/PROJECT_SPDX_LICENSE.rst
index 4f62e94..947e753 100644
--- a/Help/variable/PROJECT_SPDX_LICENSE.rst
+++ b/Help/variable/PROJECT_SPDX_LICENSE.rst
@@ -1,11 +1,7 @@
 PROJECT_SPDX_LICENSE
 --------------------
 
-.. versionadded:: 4.2
-
-.. note::
-
-  Experimental. Gated by ``CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO``.
+.. versionadded:: 4.3
 
 Value given to the ``SPDX_LICENSE`` option of the most recent call to the
 :command:`project` command, if any. To obtain the compatibility version of the
diff --git a/Modules/CMakeCXXCompiler.cmake.in b/Modules/CMakeCXXCompiler.cmake.in
index 677402b..7642c09 100644
--- a/Modules/CMakeCXXCompiler.cmake.in
+++ b/Modules/CMakeCXXCompiler.cmake.in
@@ -98,6 +98,4 @@
 
 set(CMAKE_CXX_COMPILER_IMPORT_STD "@CMAKE_CXX_COMPILER_IMPORT_STD@")
 set(CMAKE_CXX_COMPILER_IMPORT_STD_ERROR_MESSAGE  "@CMAKE_CXX_COMPILER_IMPORT_STD_ERROR_MESSAGE@")
-if(CMAKE_CXX_STDLIB_MODULES_JSON)
-  set(CMAKE_CXX_STDLIB_MODULES_JSON "@CMAKE_CXX_STDLIB_MODULES_JSON@")
-endif()
+set(CMAKE_CXX_STDLIB_MODULES_JSON "@CMAKE_CXX_STDLIB_MODULES_JSON@")
diff --git a/Modules/CTest.cmake b/Modules/CTest.cmake
index 06d11bb..66f6cda 100644
--- a/Modules/CTest.cmake
+++ b/Modules/CTest.cmake
@@ -7,7 +7,7 @@
 
 Configure a project for testing with CTest/CDash
 
-Include this module in the top CMakeLists.txt file of a project to
+Include this module in the top ``CMakeLists.txt`` file of a project to
 enable testing with CTest and dashboard submissions to CDash:
 
 .. code-block:: cmake
@@ -41,8 +41,8 @@
   set(CTEST_NIGHTLY_START_TIME "01:00:00 UTC")
   set(CTEST_SUBMIT_URL "http://my.cdash.org/submit.php?project=MyProject")
 
-(the CDash server can provide the file to a project administrator who
-configures ``MyProject``).  Settings in the config file are shared by
+The CDash server can provide the file to a project administrator who
+configures ``MyProject``.  Settings in the config file are shared by
 both this ``CTest`` module and the :manual:`ctest(1)` command-line
 :ref:`Dashboard Client` mode (:option:`ctest -S`).
 
diff --git a/Modules/Compiler/Clang-C.cmake b/Modules/Compiler/Clang-C.cmake
index 24b7157..b7359b2 100644
--- a/Modules/Compiler/Clang-C.cmake
+++ b/Modules/Compiler/Clang-C.cmake
@@ -5,11 +5,6 @@
   set(CMAKE_C_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -TC)
   set(CMAKE_C_CLANG_TIDY_DRIVER_MODE "cl")
   set(CMAKE_C_INCLUDE_WHAT_YOU_USE_DRIVER_MODE "cl")
-  if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
-      AND CMAKE_GENERATOR MATCHES "Makefiles|WMake"
-      AND CMAKE_DEPFILE_FLAGS_C)
-    set(CMAKE_C_DEPENDS_USE_COMPILER TRUE)
-  endif()
 elseif("x${CMAKE_C_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU")
   set(CMAKE_C_COMPILE_OPTIONS_EXPLICIT_LANGUAGE -x c)
   if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
diff --git a/Modules/Compiler/Clang-CXX-CXXImportStd.cmake b/Modules/Compiler/Clang-CXX-CXXImportStd.cmake
index 4099a35..95b53d0 100644
--- a/Modules/Compiler/Clang-CXX-CXXImportStd.cmake
+++ b/Modules/Compiler/Clang-CXX-CXXImportStd.cmake
@@ -8,7 +8,7 @@
     return ()
   endif ()
 
-  if (NOT DEFINED CMAKE_CXX_STDLIB_MODULES_JSON)
+  if (NOT CMAKE_CXX_STDLIB_MODULES_JSON)
     execute_process(
       COMMAND
         "${CMAKE_CXX_COMPILER}"
diff --git a/Modules/Compiler/Clang-CXX.cmake b/Modules/Compiler/Clang-CXX.cmake
index 87a4cdd..a6412e9 100644
--- a/Modules/Compiler/Clang-CXX.cmake
+++ b/Modules/Compiler/Clang-CXX.cmake
@@ -18,11 +18,6 @@
 if("x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC")
   set(CMAKE_CXX_CLANG_TIDY_DRIVER_MODE "cl")
   set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE_DRIVER_MODE "cl")
-  if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
-      AND CMAKE_GENERATOR MATCHES "Makefiles"
-      AND CMAKE_DEPFILE_FLAGS_CXX)
-    set(CMAKE_CXX_DEPENDS_USE_COMPILER TRUE)
-  endif()
 endif()
 
 if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 16.0)
diff --git a/Modules/Compiler/GNU-CXX-CXXImportStd.cmake b/Modules/Compiler/GNU-CXX-CXXImportStd.cmake
index 08d6273..c8bd960 100644
--- a/Modules/Compiler/GNU-CXX-CXXImportStd.cmake
+++ b/Modules/Compiler/GNU-CXX-CXXImportStd.cmake
@@ -4,7 +4,7 @@
     return ()
   endif ()
 
-  if (NOT DEFINED CMAKE_CXX_STDLIB_MODULES_JSON)
+  if (NOT CMAKE_CXX_STDLIB_MODULES_JSON)
     execute_process(
       COMMAND
         "${CMAKE_CXX_COMPILER}"
diff --git a/Modules/Compiler/MSVC-CXX-CXXImportStd.cmake b/Modules/Compiler/MSVC-CXX-CXXImportStd.cmake
index 733b31b..b7bd525 100644
--- a/Modules/Compiler/MSVC-CXX-CXXImportStd.cmake
+++ b/Modules/Compiler/MSVC-CXX-CXXImportStd.cmake
@@ -1,5 +1,5 @@
 function (_cmake_cxx_find_modules_json)
-  if (DEFINED CMAKE_CXX_STDLIB_MODULES_JSON)
+  if (CMAKE_CXX_STDLIB_MODULES_JSON)
     return ()
   endif ()
 
diff --git a/Modules/FindLibLZMA.cmake b/Modules/FindLibLZMA.cmake
index 4a39d2c..95d2692 100644
--- a/Modules/FindLibLZMA.cmake
+++ b/Modules/FindLibLZMA.cmake
@@ -6,7 +6,7 @@
 -----------
 
 Finds the liblzma, a data compression library that implements the LZMA
-(Lempel–Ziv–Markov chain algorithm):
+(Lempel-Ziv-Markov chain algorithm):
 
 .. code-block:: cmake
 
diff --git a/Modules/Platform/Windows-Clang-C.cmake b/Modules/Platform/Windows-Clang-C.cmake
index a90e4b7..a1c52d9 100644
--- a/Modules/Platform/Windows-Clang-C.cmake
+++ b/Modules/Platform/Windows-Clang-C.cmake
@@ -1,18 +1,10 @@
 include(Platform/Windows-Clang)
 __windows_compiler_clang(C)
 
-if("x${CMAKE_C_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC")
-  if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
-      AND CMAKE_GENERATOR MATCHES "Makefiles|WMake"
-      AND CMAKE_DEPFILE_FLAGS_C)
-    set(CMAKE_C_DEPENDS_USE_COMPILER TRUE)
-  endif()
-elseif("x${CMAKE_C_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU")
-  if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
-      AND CMAKE_GENERATOR MATCHES "Makefiles|WMake"
-      AND CMAKE_DEPFILE_FLAGS_C)
-    # dependencies are computed by the compiler itself
-    set(CMAKE_C_DEPFILE_FORMAT gcc)
-    set(CMAKE_C_DEPENDS_USE_COMPILER TRUE)
-  endif()
+if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
+    AND CMAKE_GENERATOR MATCHES "Makefiles|WMake"
+    AND CMAKE_DEPFILE_FLAGS_C)
+  # dependencies are computed by the compiler itself
+  set(CMAKE_C_DEPFILE_FORMAT gcc)
+  set(CMAKE_C_DEPENDS_USE_COMPILER TRUE)
 endif()
diff --git a/Modules/Platform/Windows-Clang-CXX.cmake b/Modules/Platform/Windows-Clang-CXX.cmake
index af2a48f..6624088 100644
--- a/Modules/Platform/Windows-Clang-CXX.cmake
+++ b/Modules/Platform/Windows-Clang-CXX.cmake
@@ -2,18 +2,10 @@
 set(_COMPILE_CXX_MSVC " -TP")
 __windows_compiler_clang(CXX)
 
-if("x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC")
-  if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
-      AND CMAKE_GENERATOR MATCHES "Makefiles|WMake"
-      AND CMAKE_DEPFILE_FLAGS_CXX)
-    set(CMAKE_CXX_DEPENDS_USE_COMPILER TRUE)
-  endif()
-elseif("x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU")
-  if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
-      AND CMAKE_GENERATOR MATCHES "Makefiles|WMake"
-      AND CMAKE_DEPFILE_FLAGS_CXX)
-    # dependencies are computed by the compiler itself
-    set(CMAKE_CXX_DEPFILE_FORMAT gcc)
-    set(CMAKE_CXX_DEPENDS_USE_COMPILER TRUE)
-  endif()
+if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
+    AND CMAKE_GENERATOR MATCHES "Makefiles|WMake"
+    AND CMAKE_DEPFILE_FLAGS_CXX)
+  # dependencies are computed by the compiler itself
+  set(CMAKE_CXX_DEPFILE_FORMAT gcc)
+  set(CMAKE_CXX_DEPENDS_USE_COMPILER TRUE)
 endif()
diff --git a/Modules/Platform/Windows-Clang-HIP.cmake b/Modules/Platform/Windows-Clang-HIP.cmake
index 75b38e2..bb80e59 100644
--- a/Modules/Platform/Windows-Clang-HIP.cmake
+++ b/Modules/Platform/Windows-Clang-HIP.cmake
@@ -2,18 +2,10 @@
 set(_COMPILE_HIP_MSVC " -x hip")
 __windows_compiler_clang(HIP)
 
-if("x${CMAKE_HIP_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC")
-  if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
-      AND CMAKE_GENERATOR MATCHES "Makefiles|WMake"
-      AND CMAKE_DEPFILE_FLAGS_HIP)
-    set(CMAKE_HIP_DEPENDS_USE_COMPILER TRUE)
-  endif()
-elseif("x${CMAKE_HIP_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU")
-  if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
-      AND CMAKE_GENERATOR MATCHES "Makefiles|WMake"
-      AND CMAKE_DEPFILE_FLAGS_HIP)
-    # dependencies are computed by the compiler itself
-    set(CMAKE_HIP_DEPFILE_FORMAT gcc)
-    set(CMAKE_HIP_DEPENDS_USE_COMPILER TRUE)
-  endif()
+if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
+    AND CMAKE_GENERATOR MATCHES "Makefiles|WMake"
+    AND CMAKE_DEPFILE_FLAGS_HIP)
+  # dependencies are computed by the compiler itself
+  set(CMAKE_HIP_DEPFILE_FORMAT gcc)
+  set(CMAKE_HIP_DEPENDS_USE_COMPILER TRUE)
 endif()
diff --git a/Modules/Platform/Windows-Clang-OBJC.cmake b/Modules/Platform/Windows-Clang-OBJC.cmake
index 7babb98..7e9a164 100644
--- a/Modules/Platform/Windows-Clang-OBJC.cmake
+++ b/Modules/Platform/Windows-Clang-OBJC.cmake
@@ -1,18 +1,10 @@
 include(Platform/Windows-Clang)
 __windows_compiler_clang(OBJC)
 
-if("x${CMAKE_OBJC_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC")
-  if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
-      AND CMAKE_GENERATOR MATCHES "Makefiles|WMake"
-      AND CMAKE_DEPFILE_FLAGS_OBJC)
-    set(CMAKE_OBJC_DEPENDS_USE_COMPILER TRUE)
-  endif()
-elseif("x${CMAKE_OBJC_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU")
-  if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
-      AND CMAKE_GENERATOR MATCHES "Makefiles|WMake"
-      AND CMAKE_DEPFILE_FLAGS_OBJC)
-    # dependencies are computed by the compiler itself
-    set(CMAKE_OBJC_DEPFILE_FORMAT gcc)
-    set(CMAKE_OBJC_DEPENDS_USE_COMPILER TRUE)
-  endif()
+if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
+    AND CMAKE_GENERATOR MATCHES "Makefiles|WMake"
+    AND CMAKE_DEPFILE_FLAGS_OBJC)
+  # dependencies are computed by the compiler itself
+  set(CMAKE_OBJC_DEPFILE_FORMAT gcc)
+  set(CMAKE_OBJC_DEPENDS_USE_COMPILER TRUE)
 endif()
diff --git a/Modules/Platform/Windows-Clang-OBJCXX.cmake b/Modules/Platform/Windows-Clang-OBJCXX.cmake
index 3bc1673..55b9070 100644
--- a/Modules/Platform/Windows-Clang-OBJCXX.cmake
+++ b/Modules/Platform/Windows-Clang-OBJCXX.cmake
@@ -1,18 +1,10 @@
 include(Platform/Windows-Clang)
 __windows_compiler_clang(OBJCXX)
 
-if("x${CMAKE_OBJCXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC")
-  if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
-      AND CMAKE_GENERATOR MATCHES "Makefiles|WMake"
-      AND CMAKE_DEPFILE_FLAGS_OBJCXX)
-    set(CMAKE_OBJCXX_DEPENDS_USE_COMPILER TRUE)
-  endif()
-elseif("x${CMAKE_OBJCXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xGNU")
-  if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
-      AND CMAKE_GENERATOR MATCHES "Makefiles|WMake"
-      AND CMAKE_DEPFILE_FLAGS_OBJCXX)
-    # dependencies are computed by the compiler itself
-    set(CMAKE_OBJCXX_DEPFILE_FORMAT gcc)
-    set(CMAKE_OBJCXX_DEPENDS_USE_COMPILER TRUE)
-  endif()
+if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
+    AND CMAKE_GENERATOR MATCHES "Makefiles|WMake"
+    AND CMAKE_DEPFILE_FLAGS_OBJCXX)
+  # dependencies are computed by the compiler itself
+  set(CMAKE_OBJCXX_DEPFILE_FORMAT gcc)
+  set(CMAKE_OBJCXX_DEPENDS_USE_COMPILER TRUE)
 endif()
diff --git a/Modules/Platform/Windows-Clang.cmake b/Modules/Platform/Windows-Clang.cmake
index 82e9d82..0c002dd 100644
--- a/Modules/Platform/Windows-Clang.cmake
+++ b/Modules/Platform/Windows-Clang.cmake
@@ -233,6 +233,11 @@
     macro(__windows_compiler_clang_base lang)
       set(_COMPILE_${lang} "${_COMPILE_${lang}_MSVC}")
       __windows_compiler_msvc(${lang})
+
+      # Prefer clang-cl's gcc-style depfile over cl-style /showIncludes
+      set(CMAKE_DEPFILE_FLAGS_${lang} "-clang:-MD -clang:-MT<DEP_TARGET> -clang:-MF<DEP_FILE>")
+      unset(CMAKE_${lang}_DEPFILE_FORMAT)
+
       unset(CMAKE_${lang}_COMPILE_OPTIONS_MSVC_DEBUG_INFORMATION_FORMAT_EditAndContinue) # -ZI not supported by Clang
       set(CMAKE_${lang}_COMPILE_OPTIONS_WARNING_AS_ERROR "-WX")
       set(CMAKE_INCLUDE_SYSTEM_FLAG_${lang} "-imsvc")
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index ef4985a..ff49eef 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -401,7 +401,6 @@
   cmRulePlaceholderExpander.cxx
   cmRulePlaceholderExpander.h
   cmLocalUnixMakefileGenerator3.cxx
-  cmLocale.h
   cmMakefile.cxx
   cmMakefile.h
   cmMakefileTargetGenerator.cxx
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 7e9b346..0a5745b 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,7 +1,7 @@
 # CMake version number components.
 set(CMake_VERSION_MAJOR 4)
 set(CMake_VERSION_MINOR 2)
-set(CMake_VERSION_PATCH 20260210)
+set(CMake_VERSION_PATCH 20260216)
 #set(CMake_VERSION_RC 0)
 set(CMake_VERSION_IS_DIRTY 0)
 
diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.cxx b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
index 8b955aa..e440b84 100644
--- a/Source/CPack/WiX/cmCPackWIXGenerator.cxx
+++ b/Source/CPack/WiX/cmCPackWIXGenerator.cxx
@@ -27,6 +27,7 @@
 #include "cmWIXDirectoriesSourceWriter.h"
 #include "cmWIXFeaturesSourceWriter.h"
 #include "cmWIXFilesSourceWriter.h"
+#include "cmWIXInstallScope.h"
 #include "cmWIXRichTextFormatWriter.h"
 #include "cmWIXSourceWriter.h"
 
@@ -545,9 +546,20 @@
 
   this->WixSources.push_back(directoryDefinitionsFilename);
 
+  cmWIXInstallScope installScope = GetInstallScope();
+
+  std::string componentKeysRegistryPath =
+    GetOption("CPACK_WIX_COMPONENT_KEYS_REGISTRY_PATH");
+  if (componentKeysRegistryPath.empty()) {
+    componentKeysRegistryPath =
+      cmStrCat("Software\\", GetOption("CPACK_PACKAGE_VENDOR"), "\\",
+               GetOption("CPACK_PACKAGE_NAME"), "\\Components");
+  }
+  cmSystemTools::ReplaceString(componentKeysRegistryPath, "/", "\\");
+
   cmWIXDirectoriesSourceWriter directoryDefinitions(
     this->WixVersion, this->Logger, directoryDefinitionsFilename,
-    this->ComponentGuidType);
+    this->ComponentGuidType, installScope, componentKeysRegistryPath);
   InjectXmlNamespaces(directoryDefinitions);
   directoryDefinitions.BeginElement("Fragment");
 
@@ -565,15 +577,18 @@
   auto installationPrefixDirectory =
     directoryDefinitions.BeginInstallationPrefixDirectory(GetRootFolderId(),
                                                           installRoot);
+  cm::optional<std::string> removeFolderComponentId =
+    directoryDefinitions.EmitRemoveFolderComponentOnUserInstall(
+      "INSTALL_ROOT");
 
   std::string fileDefinitionsFilename =
     cmStrCat(this->CPackTopLevel, "/files.wxs");
 
   this->WixSources.push_back(fileDefinitionsFilename);
 
-  cmWIXFilesSourceWriter fileDefinitions(this->WixVersion, this->Logger,
-                                         fileDefinitionsFilename,
-                                         this->ComponentGuidType);
+  cmWIXFilesSourceWriter fileDefinitions(
+    this->WixVersion, this->Logger, fileDefinitionsFilename,
+    this->ComponentGuidType, installScope, componentKeysRegistryPath);
   InjectXmlNamespaces(fileDefinitions);
 
   fileDefinitions.BeginElement("Fragment");
@@ -622,6 +637,10 @@
       *package, GetOption("CPACK_WIX_UPGRADE_GUID"));
   }
 
+  if (removeFolderComponentId.has_value()) {
+    featureDefinitions.EmitComponentRef(*removeFolderComponentId);
+  }
+
   if (!CreateFeatureHierarchy(featureDefinitions)) {
     return false;
   }
@@ -728,6 +747,8 @@
   cmValue rootFolderId = GetOption("CPACK_WIX_ROOT_FOLDER_ID");
   if (rootFolderId) {
     result = *rootFolderId;
+  } else if (GetInstallScope() == cmWIXInstallScope::PER_USER) {
+    result = "LocalAppDataFolder";
   } else if (this->WixVersion >= 4) {
     result = "ProgramFiles6432Folder";
   } else {
@@ -1083,6 +1104,13 @@
       directoryDefinitions.AddAttribute("Name", fileName);
       this->Patch->ApplyFragment(subDirectoryId, directoryDefinitions);
 
+      cm::optional<std::string> removeFolderComponentId =
+        directoryDefinitions.EmitRemoveFolderComponentOnUserInstall(
+          subDirectoryId);
+      if (removeFolderComponentId.has_value()) {
+        featureDefinitions.EmitComponentRef(*removeFolderComponentId);
+      }
+
       AddDirectoryAndFileDefinitions(fullPath, subDirectoryId,
                                      directoryDefinitions, fileDefinitions,
                                      featureDefinitions, packageExecutables,
@@ -1374,3 +1402,24 @@
                                          ns.second);
   }
 }
+
+cmWIXInstallScope cmCPackWIXGenerator::GetInstallScope() const
+{
+  cmValue value = this->GetOption("CPACK_WIX_INSTALL_SCOPE");
+
+  if (value == "perUser"_s) {
+    return cmWIXInstallScope::PER_USER;
+  }
+  if (value == "perMachine"_s) {
+    return cmWIXInstallScope::PER_MACHINE;
+  }
+  if (value == "NONE"_s) {
+    return cmWIXInstallScope::NONE;
+  }
+
+  cmCPackLogger(
+    cmCPackLog::LOG_ERROR,
+    "Invalid CPACK_WIX_INSTALL_SCOPE value, defaulting to perMachine: "
+      << (value ? *value : "") << std::endl);
+  return cmWIXInstallScope::PER_MACHINE;
+}
diff --git a/Source/CPack/WiX/cmCPackWIXGenerator.h b/Source/CPack/WiX/cmCPackWIXGenerator.h
index bfad0d4..0d59eeb 100644
--- a/Source/CPack/WiX/cmCPackWIXGenerator.h
+++ b/Source/CPack/WiX/cmCPackWIXGenerator.h
@@ -7,6 +7,7 @@
 #include <string>
 
 #include "cmCPackGenerator.h"
+#include "cmWIXInstallScope.h"
 #include "cmWIXPatch.h"
 #include "cmWIXShortcut.h"
 
@@ -159,6 +160,8 @@
 
   void InjectXmlNamespaces(cmWIXSourceWriter& sourceWriter);
 
+  cmWIXInstallScope GetInstallScope() const;
+
   std::vector<std::string> WixSources;
   id_map_t PathToIdMap;
   ambiguity_map_t IdAmbiguityCounter;
diff --git a/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.cxx b/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.cxx
index b6e3cd2..4cee0f1 100644
--- a/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.cxx
+++ b/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.cxx
@@ -6,9 +6,24 @@
 
 cmWIXDirectoriesSourceWriter::cmWIXDirectoriesSourceWriter(
   unsigned long wixVersion, cmCPackLog* logger, std::string const& filename,
-  GuidType componentGuidType)
+  GuidType componentGuidType, cmWIXInstallScope installScope,
+  std::string componentKeysRegistryPath)
   : cmWIXSourceWriter(wixVersion, logger, filename, componentGuidType)
+  , ComponentKeysRegistryPath(std::move(componentKeysRegistryPath))
 {
+  switch (installScope) {
+    case cmWIXInstallScope::PER_USER:
+      this->PerUserInstall = true;
+      break;
+    case cmWIXInstallScope::PER_MACHINE:
+    case cmWIXInstallScope::NONE:
+      this->PerUserInstall = false;
+      break;
+    default:
+      cmCPackLogger(cmCPackLog::LOG_ERROR,
+                    "Unhandled install scope value, this is a CPack Bug.");
+      break;
+  }
 }
 
 void cmWIXDirectoriesSourceWriter::EmitStartMenuFolder(
@@ -47,6 +62,43 @@
   EndElement_StandardDirectory();
 }
 
+cm::optional<std::string>
+cmWIXDirectoriesSourceWriter::EmitRemoveFolderComponentOnUserInstall(
+  std::string const& directoryId)
+{
+  if (!this->PerUserInstall) {
+    return {};
+  }
+
+  BeginElement("Component");
+
+  std::string componentId = directoryId + "_RemoveFolderComponent";
+  AddAttribute("Id", componentId);
+  AddAttribute("Guid", CreateGuidFromComponentId(componentId));
+
+  BeginElement("RemoveFolder");
+  AddAttribute("Id", directoryId + "_RemoveFolder");
+  AddAttribute("Directory", directoryId);
+  AddAttribute("On", "uninstall");
+  EndElement("RemoveFolder");
+
+  // Need a keyPath for the component
+  BeginElement("RegistryValue");
+
+  AddAttribute("Root", "HKCU");
+  AddAttribute("Key", this->ComponentKeysRegistryPath);
+  AddAttribute("Name", componentId);
+  AddAttribute("Type", "string");
+  AddAttribute("Value", "1");
+  AddAttribute("KeyPath", "yes");
+
+  EndElement("RegistryValue");
+
+  EndElement("Component");
+
+  return componentId;
+}
+
 cmWIXDirectoriesSourceWriter::InstallationPrefixDirectory
 cmWIXDirectoriesSourceWriter::BeginInstallationPrefixDirectory(
   std::string const& programFilesFolderId,
diff --git a/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.h b/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.h
index 5aa194d..8ec5810 100644
--- a/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.h
+++ b/Source/CPack/WiX/cmWIXDirectoriesSourceWriter.h
@@ -4,7 +4,10 @@
 
 #include <string>
 
+#include <cm/optional>
+
 #include "cmCPackGenerator.h"
+#include "cmWIXInstallScope.h"
 #include "cmWIXSourceWriter.h"
 
 /** \class cmWIXDirectoriesSourceWriter
@@ -15,7 +18,9 @@
 public:
   cmWIXDirectoriesSourceWriter(unsigned long wixVersion, cmCPackLog* logger,
                                std::string const& filename,
-                               GuidType componentGuidType);
+                               GuidType componentGuidType,
+                               cmWIXInstallScope installScope,
+                               std::string componentKeysRegistryPath);
 
   void EmitStartMenuFolder(std::string const& startMenuFolder);
 
@@ -23,6 +28,9 @@
 
   void EmitStartupFolder();
 
+  cm::optional<std::string> EmitRemoveFolderComponentOnUserInstall(
+    std::string const& directoryId);
+
   struct InstallationPrefixDirectory
   {
     bool HasStandardDirectory = false;
@@ -35,4 +43,8 @@
 
   void EndInstallationPrefixDirectory(
     InstallationPrefixDirectory installationPrefixDirectory);
+
+private:
+  bool PerUserInstall = false;
+  std::string ComponentKeysRegistryPath;
 };
diff --git a/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx b/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx
index 550e029..9581d9f 100644
--- a/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx
+++ b/Source/CPack/WiX/cmWIXFilesSourceWriter.cxx
@@ -19,12 +19,26 @@
 #  include "cmsys/Encoding.hxx"
 #endif
 
-cmWIXFilesSourceWriter::cmWIXFilesSourceWriter(unsigned long wixVersion,
-                                               cmCPackLog* logger,
-                                               std::string const& filename,
-                                               GuidType componentGuidType)
+cmWIXFilesSourceWriter::cmWIXFilesSourceWriter(
+  unsigned long wixVersion, cmCPackLog* logger, std::string const& filename,
+  GuidType componentGuidType, cmWIXInstallScope installScope,
+  std::string componentKeysRegistryPath)
   : cmWIXSourceWriter(wixVersion, logger, filename, componentGuidType)
+  , ComponentKeysRegistryPath(std::move(componentKeysRegistryPath))
 {
+  switch (installScope) {
+    case cmWIXInstallScope::PER_USER:
+      this->PerUserInstall = true;
+      break;
+    case cmWIXInstallScope::PER_MACHINE:
+    case cmWIXInstallScope::NONE:
+      this->PerUserInstall = false;
+      break;
+    default:
+      cmCPackLogger(cmCPackLog::LOG_ERROR,
+                    "Unhandled install scope value, this is a CPack Bug.");
+      break;
+  }
 }
 
 void cmWIXFilesSourceWriter::EmitShortcut(std::string const& id,
@@ -127,7 +141,11 @@
   std::string componentId = std::string("CM_C") + id;
   std::string fileId = std::string("CM_F") + id;
 
-  std::string guid = CreateGuidFromComponentId(componentId);
+  // Wix doesn't support automatic GUIDs for components which have both
+  // registry entries and files.
+  std::string guid = this->PerUserInstall
+    ? CreateCmakeGeneratedGuidFromComponentId(componentId)
+    : CreateGuidFromComponentId(componentId);
 
   BeginElement("DirectoryRef");
   AddAttribute("Id", directoryId);
@@ -150,6 +168,22 @@
   }
 
   patch.ApplyFragment(componentId, *this);
+
+  if (this->PerUserInstall) {
+    // For perUser installs, MSI requires using a registry entry as the key
+    // path for components.
+    BeginElement("RegistryValue");
+
+    AddAttribute("Root", "HKCU");
+    AddAttribute("Key", this->ComponentKeysRegistryPath);
+    AddAttribute("Name", fileId);
+    AddAttribute("Type", "string");
+    AddAttribute("Value", "1");
+    AddAttribute("KeyPath", "yes");
+
+    EndElement("RegistryValue");
+  }
+
   BeginElement("File");
   AddAttribute("Id", fileId);
 
@@ -164,7 +198,9 @@
 #endif
   AddAttribute("Source", sourcePath);
 
-  AddAttribute("KeyPath", "yes");
+  if (!this->PerUserInstall) {
+    AddAttribute("KeyPath", "yes");
+  }
 
   mode_t fileMode = 0;
   cmSystemTools::GetPermissions(filePath.c_str(), fileMode);
diff --git a/Source/CPack/WiX/cmWIXFilesSourceWriter.h b/Source/CPack/WiX/cmWIXFilesSourceWriter.h
index fff7c4f..1d55067 100644
--- a/Source/CPack/WiX/cmWIXFilesSourceWriter.h
+++ b/Source/CPack/WiX/cmWIXFilesSourceWriter.h
@@ -2,7 +2,10 @@
    file LICENSE.rst or https://cmake.org/licensing for details.  */
 #pragma once
 
+#include <string>
+
 #include "cmCPackGenerator.h"
+#include "cmWIXInstallScope.h"
 #include "cmWIXPatch.h"
 #include "cmWIXShortcut.h"
 #include "cmWIXSourceWriter.h"
@@ -15,7 +18,9 @@
 public:
   cmWIXFilesSourceWriter(unsigned long wixVersion, cmCPackLog* logger,
                          std::string const& filename,
-                         GuidType componentGuidType);
+                         GuidType componentGuidType,
+                         cmWIXInstallScope installScope,
+                         std::string componentKeysRegistryPath);
 
   void EmitShortcut(std::string const& id, cmWIXShortcut const& shortcut,
                     std::string const& shortcutPrefix, size_t shortcutIndex);
@@ -37,4 +42,8 @@
                                 std::string const& filePath, cmWIXPatch& patch,
                                 cmInstalledFile const* installedFile,
                                 int diskId);
+
+private:
+  bool PerUserInstall = false;
+  std::string ComponentKeysRegistryPath;
 };
diff --git a/Source/CPack/WiX/cmWIXInstallScope.h b/Source/CPack/WiX/cmWIXInstallScope.h
new file mode 100644
index 0000000..6b69457
--- /dev/null
+++ b/Source/CPack/WiX/cmWIXInstallScope.h
@@ -0,0 +1,10 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file LICENSE.rst or https://cmake.org/licensing for details.  */
+#pragma once
+
+enum class cmWIXInstallScope
+{
+  NONE,
+  PER_MACHINE,
+  PER_USER
+};
diff --git a/Source/CPack/WiX/cmWIXSourceWriter.cxx b/Source/CPack/WiX/cmWIXSourceWriter.cxx
index ed3cbe0..f2cb8b4 100644
--- a/Source/CPack/WiX/cmWIXSourceWriter.cxx
+++ b/Source/CPack/WiX/cmWIXSourceWriter.cxx
@@ -159,15 +159,21 @@
 {
   std::string guid = "*";
   if (this->ComponentGuidType == CMAKE_GENERATED_GUID) {
-    cmCryptoHash hasher(cmCryptoHash::AlgoMD5);
-    std::string md5 = hasher.HashString(componentId);
-    cmUuid uuid;
-    std::vector<unsigned char> ns;
-    guid = uuid.FromMd5(ns, md5);
+    guid = CreateCmakeGeneratedGuidFromComponentId(componentId);
   }
   return guid;
 }
 
+std::string cmWIXSourceWriter::CreateCmakeGeneratedGuidFromComponentId(
+  std::string const& componentId)
+{
+  cmCryptoHash hasher(cmCryptoHash::AlgoMD5);
+  std::string md5 = hasher.HashString(componentId);
+  cmUuid uuid;
+  std::vector<unsigned char> ns;
+  return uuid.FromMd5(ns, md5);
+}
+
 void cmWIXSourceWriter::WriteXMLDeclaration()
 {
   File << R"(<?xml version="1.0" encoding="UTF-8"?>)" << std::endl;
diff --git a/Source/CPack/WiX/cmWIXSourceWriter.h b/Source/CPack/WiX/cmWIXSourceWriter.h
index 5e1150d..8243275 100644
--- a/Source/CPack/WiX/cmWIXSourceWriter.h
+++ b/Source/CPack/WiX/cmWIXSourceWriter.h
@@ -5,6 +5,8 @@
 #include <string>
 #include <vector>
 
+#include <cm/optional>
+
 #include "cmsys/FStream.hxx"
 
 #include "cmCPackLog.h"
@@ -52,6 +54,12 @@
 
   std::string CreateGuidFromComponentId(std::string const& componentId);
 
+  // In most cases CreateGuidFromComponentId should be used instead, since it
+  // takes ComponentGuidType into consideration. This function always generates
+  // an explicit GUID.
+  static std::string CreateCmakeGeneratedGuidFromComponentId(
+    std::string const& componentId);
+
   static std::string EscapeAttributeValue(std::string const& value);
 
 protected:
diff --git a/Source/CPack/cmCPackAppImageGenerator.cxx b/Source/CPack/cmCPackAppImageGenerator.cxx
index c6d4d8a..03dffab 100644
--- a/Source/CPack/cmCPackAppImageGenerator.cxx
+++ b/Source/CPack/cmCPackAppImageGenerator.cxx
@@ -4,7 +4,6 @@
 #include "cmCPackAppImageGenerator.h"
 
 #include <algorithm>
-#include <cctype>
 #include <cstddef>
 #include <utility>
 #include <vector>
@@ -14,6 +13,7 @@
 #include <sys/types.h>
 
 #include "cmsys/FStream.hxx"
+#include "cmsys/String.h"
 
 #include "cmCPackLog.h"
 #include "cmELF.h"
@@ -340,11 +340,9 @@
 // Trim leading and trailing whitespace from a string
 std::string trim(std::string const& str)
 {
-  auto start = std::find_if_not(
-    str.begin(), str.end(), [](unsigned char c) { return std::isspace(c); });
-  auto end = std::find_if_not(str.rbegin(), str.rend(), [](unsigned char c) {
-               return std::isspace(c);
-             }).base();
+  auto start = std::find_if_not(str.begin(), str.end(), cmsysString_isspace);
+  auto end =
+    std::find_if_not(str.rbegin(), str.rend(), cmsysString_isspace).base();
   return (start < end) ? std::string(start, end) : std::string();
 }
 } // namespace
diff --git a/Source/CPack/cmCPackInnoSetupGenerator.cxx b/Source/CPack/cmCPackInnoSetupGenerator.cxx
index 9522e86..4b8533b 100644
--- a/Source/CPack/cmCPackInnoSetupGenerator.cxx
+++ b/Source/CPack/cmCPackInnoSetupGenerator.cxx
@@ -4,12 +4,12 @@
 #include "cmCPackInnoSetupGenerator.h"
 
 #include <algorithm>
-#include <cctype>
 #include <cstdlib>
 #include <ostream>
 #include <utility>
 
 #include "cmsys/RegularExpression.hxx"
+#include "cmsys/String.h"
 
 #include "cmCPackComponentGroup.h"
 #include "cmCPackLog.h"
@@ -116,7 +116,7 @@
     if (cmSystemTools::LowerCase(i) == "english") {
       params["MessagesFile"] = "\"compiler:Default.isl\"";
     } else {
-      i[0] = static_cast<char>(std::toupper(static_cast<unsigned char>(i[0])));
+      i[0] = static_cast<char>(cmsysString_toupper(i[0]));
       params["MessagesFile"] = cmStrCat("\"compiler:Languages\\", i, ".isl\"");
     }
 
diff --git a/Source/CPack/cmCPackRPMGenerator.cxx b/Source/CPack/cmCPackRPMGenerator.cxx
index 19cbee1..2bc60c2 100644
--- a/Source/CPack/cmCPackRPMGenerator.cxx
+++ b/Source/CPack/cmCPackRPMGenerator.cxx
@@ -3,12 +3,13 @@
 #include "cmCPackRPMGenerator.h"
 
 #include <algorithm>
-#include <cctype>
 #include <map>
 #include <ostream>
 #include <utility>
 #include <vector>
 
+#include "cmsys/String.h"
+
 #include "cmCPackComponentGroup.h"
 #include "cmCPackGenerator.h"
 #include "cmCPackLog.h"
@@ -143,7 +144,7 @@
            ++compIt) {
         std::string component(compIt->first);
         std::transform(component.begin(), component.end(), component.begin(),
-                       [](unsigned char c) { return std::toupper(c); });
+                       cmsysString_toupper);
 
         if (this->IsOn("CPACK_RPM_" + compIt->first + "_DEBUGINFO_PACKAGE") ||
             this->IsOn("CPACK_RPM_" + component + "_DEBUGINFO_PACKAGE")) {
@@ -157,7 +158,7 @@
            compGIt != this->ComponentGroups.end(); ++compGIt) {
         std::string component(compGIt->first);
         std::transform(component.begin(), component.end(), component.begin(),
-                       [](unsigned char c) { return std::toupper(c); });
+                       cmsysString_toupper);
 
         if (this->IsOn("CPACK_RPM_" + compGIt->first + "_DEBUGINFO_PACKAGE") ||
             this->IsOn("CPACK_RPM_" + component + "_DEBUGINFO_PACKAGE")) {
@@ -174,8 +175,7 @@
           if (!compIt->second.Group) {
             std::string component(compIt->first);
             std::transform(component.begin(), component.end(),
-                           component.begin(),
-                           [](unsigned char c) { return std::toupper(c); });
+                           component.begin(), cmsysString_toupper);
 
             if (this->IsOn("CPACK_RPM_" + compIt->first +
                            "_DEBUGINFO_PACKAGE") ||
@@ -207,8 +207,7 @@
 
     std::string mainComponentUpper(mainComponent);
     std::transform(mainComponentUpper.begin(), mainComponentUpper.end(),
-                   mainComponentUpper.begin(),
-                   [](unsigned char c) { return std::toupper(c); });
+                   mainComponentUpper.begin(), cmsysString_toupper);
 
     // The default behavior is to have one package by component group
     // unless CPACK_COMPONENTS_IGNORE_GROUP is specified.
@@ -220,7 +219,7 @@
            compGIt != this->ComponentGroups.end(); ++compGIt) {
         std::string component(compGIt->first);
         std::transform(component.begin(), component.end(), component.begin(),
-                       [](unsigned char c) { return std::toupper(c); });
+                       cmsysString_toupper);
 
         if (mainComponentUpper == component) {
           // main component will be handled last
@@ -242,7 +241,7 @@
         if (!compIt->second.Group) {
           std::string component(compIt->first);
           std::transform(component.begin(), component.end(), component.begin(),
-                         [](unsigned char c) { return std::toupper(c); });
+                         cmsysString_toupper);
 
           if (mainComponentUpper == component) {
             // main component will be handled last
@@ -285,7 +284,7 @@
            ++compIt) {
         std::string component(compIt->first);
         std::transform(component.begin(), component.end(), component.begin(),
-                       [](unsigned char c) { return std::toupper(c); });
+                       cmsysString_toupper);
 
         if (mainComponentUpper == component) {
           // main component will be handled last
diff --git a/Source/CTest/cmCTestGIT.cxx b/Source/CTest/cmCTestGIT.cxx
index 52adedd..fdb0bb7 100644
--- a/Source/CTest/cmCTestGIT.cxx
+++ b/Source/CTest/cmCTestGIT.cxx
@@ -11,6 +11,7 @@
 #include <cmext/algorithm>
 
 #include "cmsys/FStream.hxx"
+#include "cmsys/String.h"
 
 #include "cmCTest.h"
 #include "cmCTestVC.h"
@@ -412,14 +413,14 @@
 
   char const* ConsumeSpace(char const* c)
   {
-    while (*c && cmIsSpace(*c)) {
+    while (*c && cmsysString_isspace(*c)) {
       ++c;
     }
     return c;
   }
   char const* ConsumeField(char const* c)
   {
-    while (*c && !cmIsSpace(*c)) {
+    while (*c && !cmsysString_isspace(*c)) {
       ++c;
     }
     return c;
@@ -479,7 +480,7 @@
   {
     // Person Name <person@domain.com> 1234567890 +0000
     char const* c = str;
-    while (*c && cmIsSpace(*c)) {
+    while (*c && cmsysString_isspace(*c)) {
       ++c;
     }
 
@@ -488,7 +489,7 @@
       ++c;
     }
     char const* name_last = c;
-    while (name_last != name_first && cmIsSpace(*(name_last - 1))) {
+    while (name_last != name_first && cmsysString_isspace(*(name_last - 1))) {
       --name_last;
     }
     person.Name.assign(name_first, name_last - name_first);
diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx
index de8651c..40db404 100644
--- a/Source/CTest/cmCTestRunTest.cxx
+++ b/Source/CTest/cmCTestRunTest.cxx
@@ -365,6 +365,9 @@
     if (!skipped) {
       this->TestResult.CompletionStatus = "Completed";
     }
+    this->TestResult.StartTestTime =
+      std::chrono::duration_cast<std::chrono::milliseconds>(
+        this->TestProcess->GetSystemStartTime().time_since_epoch());
     this->TestResult.ExecutionTime = this->TestProcess->GetTotalTime();
     this->MemCheckPostProcess();
     this->ComputeWeightedCost();
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
index d8b90e3..5f442cb 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -1525,6 +1525,7 @@
   xml.Element("Path", this->CTest->GetShortPathToFile(result.Path));
   xml.Element("FullName", this->CTest->GetShortPathToFile(testPath));
   xml.Element("FullCommandLine", result.FullCommandLine);
+  xml.Element("StartTestTime", result.StartTestTime);
 }
 
 void cmCTestTestHandler::WriteTestResultFooter(cmXMLWriter& xml,
diff --git a/Source/CTest/cmCTestTestHandler.h b/Source/CTest/cmCTestTestHandler.h
index e57bc10..f2c8e79 100644
--- a/Source/CTest/cmCTestTestHandler.h
+++ b/Source/CTest/cmCTestTestHandler.h
@@ -194,6 +194,7 @@
     std::string TestMeasurementsOutput;
     std::string InstrumentationFile;
     int TestCount = 0;
+    std::chrono::milliseconds StartTestTime;
     cmCTestTestProperties* Properties = nullptr;
   };
 
diff --git a/Source/CursesDialog/cmCursesColor.cxx b/Source/CursesDialog/cmCursesColor.cxx
index c9add4f..a9e5ff6 100644
--- a/Source/CursesDialog/cmCursesColor.cxx
+++ b/Source/CursesDialog/cmCursesColor.cxx
@@ -2,12 +2,13 @@
    file LICENSE.rst or https://cmake.org/licensing for details.  */
 #include "cmCursesColor.h"
 
-#include <cctype>
 #include <cstdlib>
 #include <cstring>
 #include <unordered_map>
 #include <utility>
 
+#include "cmsys/String.h"
+
 #include "cmCursesStandardIncludes.h"
 
 bool cmCursesColor::HasColors()
@@ -42,7 +43,7 @@
   if (!initialized) {
     if (auto* v = getenv("CCMAKE_COLORS")) {
       while (v[0] && v[1] && v[1] == '=') {
-        auto const n = std::toupper(static_cast<unsigned char>(*v));
+        char const n = cmsysString_toupper(*v);
 
         char buffer[12];
         memset(buffer, 0, sizeof(buffer));
diff --git a/Source/QtDialog/RegexExplorer.cxx b/Source/QtDialog/RegexExplorer.cxx
index 9065f66..b0333cf 100644
--- a/Source/QtDialog/RegexExplorer.cxx
+++ b/Source/QtDialog/RegexExplorer.cxx
@@ -2,6 +2,8 @@
    file LICENSE.rst or https://cmake.org/licensing for details.  */
 #include "RegexExplorer.h"
 
+#include "cmsys/String.h"
+
 RegexExplorer::RegexExplorer(QWidget* p)
   : QDialog(p)
   , m_matched(false)
@@ -147,7 +149,7 @@
       } else if (nextc == 'n') {
         result.append(1, '\n');
         in++;
-      } else if (isalnum(nextc) || nextc == '\0') {
+      } else if (cmsysString_isalnum(nextc) || nextc == '\0') {
         return false;
       } else {
         result.append(1, nextc);
diff --git a/Source/bindexplib.cxx b/Source/bindexplib.cxx
index bbcb0bc..59680aa 100644
--- a/Source/bindexplib.cxx
+++ b/Source/bindexplib.cxx
@@ -72,6 +72,7 @@
 #  include <windows.h>
 
 #  include "cmsys/Encoding.hxx"
+#  include "cmsys/String.h"
 #endif
 
 #include "cmsys/FStream.hxx"
@@ -261,7 +262,7 @@
           }
 
           // clear out any leading spaces
-          while (isspace(symbol[0]))
+          while (cmsysString_isspace(symbol[0]))
             symbol.erase(0, 1);
           // if it starts with _ and has an @ then it is a __cdecl
           // so remove the @ stuff for the export
diff --git a/Source/cmArchiveWrite.cxx b/Source/cmArchiveWrite.cxx
index ab7e624..0adcefd 100644
--- a/Source/cmArchiveWrite.cxx
+++ b/Source/cmArchiveWrite.cxx
@@ -24,7 +24,6 @@
 
 #include "cm_parse_date.h"
 
-#include "cmLocale.h"
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 
@@ -449,9 +448,6 @@
   }
   char const* out = file + skip;
 
-  cmLocaleRAII localeRAII;
-  static_cast<void>(localeRAII);
-
   // Meta-data.
   std::string dest = cmStrCat(prefix ? prefix : "", out);
   if (this->Verbose) {
diff --git a/Source/cmCMakeHostSystemInformationCommand.cxx b/Source/cmCMakeHostSystemInformationCommand.cxx
index 9674c52..55e93ee 100644
--- a/Source/cmCMakeHostSystemInformationCommand.cxx
+++ b/Source/cmCMakeHostSystemInformationCommand.cxx
@@ -4,7 +4,6 @@
 
 #include <algorithm>
 #include <cassert>
-#include <cctype>
 #include <cstddef>
 #include <initializer_list>
 #include <map>
@@ -16,8 +15,13 @@
 #include <cm/type_traits>
 #include <cmext/string_view>
 
+#if !defined(_WIN32)
+#  include <langinfo.h>
+#endif
+
 #include "cmsys/FStream.hxx"
 #include "cmsys/Glob.hxx"
+#include "cmsys/String.h"
 #include "cmsys/SystemInformation.hxx"
 
 #include "cmArgumentParser.h"
@@ -74,6 +78,22 @@
   if (key == "FQDN"_s) {
     return ValueToString(info.GetFullyQualifiedDomainName());
   }
+  if (key == "LOCALE_CHARSET"_s) {
+#if defined(_WIN32)
+    // On Windows we always use UTF-8.
+    return ValueToString("UTF-8");
+#else
+    // On non-Windows platforms we use the locale's encoding.
+    if (char const* charset = nl_langinfo(CODESET)) {
+      if (cmsysString_strcasecmp(charset, "utf-8") == 0 ||
+          cmsysString_strcasecmp(charset, "utf8") == 0) {
+        charset = "UTF-8";
+      }
+      return ValueToString(charset);
+    }
+    return ValueToString("");
+#endif
+  }
   if (key == "TOTAL_VIRTUAL_MEMORY"_s) {
     return ValueToString(info.GetTotalVirtualMemory());
   }
@@ -218,10 +238,10 @@
   for (auto ch : line) {
     switch (state) {
       case PARSE_KEY_1ST:
-        if (std::isalpha(ch) || ch == '_') {
+        if (cmsysString_isalpha(ch) || ch == '_') {
           key += ch;
           state = PARSE_KEY;
-        } else if (!cmIsSpace(ch)) {
+        } else if (!cmsysString_isspace(ch)) {
           state = IGNORE_REST;
         }
         break;
@@ -229,7 +249,7 @@
       case PARSE_KEY:
         if (ch == '=') {
           state = FOUND_EQ;
-        } else if (std::isalnum(ch) || ch == '_') {
+        } else if (cmsysString_isalnum(ch) || ch == '_') {
           key += ch;
         } else {
           state = IGNORE_REST;
@@ -281,7 +301,7 @@
         break;
 
       case PARSE_VALUE:
-        if (ch == '#' || cmIsSpace(ch)) {
+        if (ch == '#' || cmsysString_isspace(ch)) {
           state = IGNORE_REST;
         } else {
           value += ch;
@@ -355,8 +375,8 @@
     auto const& filename = cmSystemTools::GetFilenameName(filepath);
     // NOTE Minimum filename length expected:
     //   NNN-<at-least-one-char-name>.cmake  --> 11
-    return (filename.size() < 11) || !std::isdigit(filename[0]) ||
-      !std::isdigit(filename[1]) || !std::isdigit(filename[2]) ||
+    return (filename.size() < 11) || !cmsysString_isdigit(filename[0]) ||
+      !cmsysString_isdigit(filename[1]) || !cmsysString_isdigit(filename[2]) ||
       filename[3] != '-';
   };
   scripts.erase(std::remove_if(scripts.begin(), scripts.end(), checkName),
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index f503e93..ed1516f 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -3,7 +3,6 @@
 #include "cmCTest.h"
 
 #include <algorithm>
-#include <cctype>
 #include <chrono>
 #include <cstdint>
 #include <cstdio>
@@ -34,6 +33,7 @@
 #include "cmsys/Directory.hxx"
 #include "cmsys/FStream.hxx"
 #include "cmsys/RegularExpression.hxx"
+#include "cmsys/String.h"
 #include "cmsys/SystemInformation.hxx"
 #ifndef _WIN32
 #  include <unistd.h> // IWYU pragma: keep
@@ -299,7 +299,8 @@
 {
   std::string out;
   for (char const* c = in.c_str(); *c; ++c) {
-    if (*c == '%' && isxdigit(*(c + 1)) && isxdigit(*(c + 2))) {
+    if (*c == '%' && cmsysString_isxdigit(*(c + 1)) &&
+        cmsysString_isxdigit(*(c + 2))) {
       char buf[3] = { *(c + 1), *(c + 2), 0 };
       out.append(1, static_cast<char>(strtoul(buf, nullptr, 16)));
       c += 2;
@@ -3702,8 +3703,7 @@
   bool generating_test_xml = root["role"] == "test";
   if (!generating_test_xml) {
     std::string element_name = root["role"].asString();
-    element_name[0] = static_cast<char>(
-      std::toupper(static_cast<unsigned char>(element_name[0])));
+    element_name[0] = static_cast<char>(cmsysString_toupper(element_name[0]));
     xml.StartElement(element_name);
     std::vector<std::string> keys = root.getMemberNames();
     for (auto const& key : keys) {
@@ -3735,8 +3735,8 @@
   std::vector<std::string> keys = dynamic_information.getMemberNames();
   for (auto const& key : keys) {
     std::string measurement_name = key;
-    measurement_name[0] = static_cast<char>(
-      std::toupper(static_cast<unsigned char>(measurement_name[0])));
+    measurement_name[0] =
+      static_cast<char>(cmsysString_toupper(measurement_name[0]));
 
     xml.StartElement("NamedMeasurement");
     xml.Attribute("type", "numeric/double");
diff --git a/Source/cmCommandLineArgument.h b/Source/cmCommandLineArgument.h
index f11d1fb..4c88f23 100644
--- a/Source/cmCommandLineArgument.h
+++ b/Source/cmCommandLineArgument.h
@@ -2,11 +2,11 @@
    file LICENSE.rst or https://cmake.org/licensing for details.  */
 #pragma once
 
-#include <cctype>
-
 #include <cm/optional>
 #include <cm/string_view>
 
+#include "cmsys/String.h"
+
 #include "cmStringAlgorithms.h"
 #include "cmSystemTools.h"
 
@@ -288,6 +288,6 @@
   static bool IsFlag(cm::string_view arg)
   {
     return !arg.empty() && arg[0] == '-' &&
-      !(arg.size() >= 2 && std::isdigit(arg[1]));
+      !(arg.size() >= 2 && cmsysString_isdigit(arg[1]));
   }
 };
diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx
index baa1198..6db6767 100644
--- a/Source/cmCommonTargetGenerator.cxx
+++ b/Source/cmCommonTargetGenerator.cxx
@@ -180,35 +180,90 @@
 
   if (cmComputeLinkInformation* cli =
         this->GeneratorTarget->GetLinkInformation(config)) {
-    auto addLinkedTarget =
-      [this, &lang, &config, &dirs, &direct_emitted, &forward_emitted,
-       gg](cmGeneratorTarget const* linkee, Forwarding forward) {
-        if (linkee &&
-            !linkee->IsImported()
-            // Skip targets that build after this one in a static lib cycle.
-            && gg->TargetOrderIndexLess(linkee, this->GeneratorTarget)
-            // We can ignore the INTERFACE_LIBRARY items because
-            // Target->GetLinkInformation already processed their
-            // link interface and they don't have any output themselves.
-            && (linkee->GetType() != cmStateEnums::INTERFACE_LIBRARY
-                // Synthesized targets may have relevant rules.
-                || linkee->IsSynthetic()) &&
-            ((lang == "CXX"_s && linkee->HaveCxx20ModuleSources()) ||
-             (lang == "Fortran"_s && linkee->HaveFortranSources(config)))) {
-          cmLocalGenerator* lg = linkee->GetLocalGenerator();
-          std::string di = linkee->GetSupportDirectory();
-          if (lg->GetGlobalGenerator()->IsMultiConfig()) {
-            di = cmStrCat(di, '/', config);
-          }
-          if (forward == Forwarding::Yes &&
-              forward_emitted.insert(linkee).second) {
-            dirs.Forward.push_back(di);
-          }
-          if (direct_emitted.insert(linkee).second) {
-            dirs.Direct.emplace_back(di);
+
+    auto findSyntheticTarget =
+      [this,
+       &config](cmGeneratorTarget const* linkee) -> cmGeneratorTarget const* {
+      if (!linkee) {
+        return nullptr;
+      }
+
+      // Check the map of direct synthetic dependencies for a substitute
+      auto const& synthDeps = this->GeneratorTarget->GetSyntheticDeps(config);
+      auto it = synthDeps.find(linkee);
+      if (it != synthDeps.end() && !it->second.empty()) {
+        return it->second.front();
+      }
+
+      // Check linked targets to finding synthetic targets for transitive deps
+      std::vector<cmGeneratorTarget const*> pending;
+      std::set<cmGeneratorTarget const*> visited;
+      for (auto const& dep : synthDeps) {
+        for (auto const* synth : dep.second) {
+          if (synth && visited.insert(synth).second) {
+            pending.push_back(synth);
           }
         }
-      };
+      }
+
+      while (!pending.empty()) {
+        auto const* current = pending.back();
+        pending.pop_back();
+        auto const& transitiveSynthDeps = current->GetSyntheticDeps(config);
+        auto itLinkeeSynth = transitiveSynthDeps.find(linkee);
+        if (itLinkeeSynth != transitiveSynthDeps.end() &&
+            !itLinkeeSynth->second.empty()) {
+          return itLinkeeSynth->second.front();
+        }
+        for (auto const& entry : transitiveSynthDeps) {
+          for (auto const* synth : entry.second) {
+            if (synth && visited.insert(synth).second) {
+              pending.push_back(synth);
+            }
+          }
+        }
+      }
+
+      return nullptr;
+    };
+
+    auto addLinkedTarget = [this, &lang, &config, &dirs, &direct_emitted,
+                            &forward_emitted, &findSyntheticTarget,
+                            gg](cmGeneratorTarget const* linkee,
+                                Forwarding forward) {
+      // Check if the linkee has a synthetic target to use for importing
+      cmGeneratorTarget const* mappedLinkee = linkee;
+      if (auto const* synth = findSyntheticTarget(linkee)) {
+        mappedLinkee = synth;
+      }
+
+      if (mappedLinkee &&
+          !mappedLinkee->IsImported()
+          // Skip targets that build after this one in a static lib cycle.
+          && gg->TargetOrderIndexLess(mappedLinkee, this->GeneratorTarget)
+          // We can ignore the INTERFACE_LIBRARY items because
+          // Target->GetLinkInformation already processed their
+          // link interface and they don't have any output themselves.
+          && (mappedLinkee->GetType() != cmStateEnums::INTERFACE_LIBRARY
+              // Synthesized targets may have relevant rules.
+              || mappedLinkee->IsSynthetic()) &&
+          ((lang == "CXX"_s && mappedLinkee->HaveCxx20ModuleSources()) ||
+           (lang == "Fortran"_s &&
+            mappedLinkee->HaveFortranSources(config)))) {
+        cmLocalGenerator* lg = mappedLinkee->GetLocalGenerator();
+        std::string di = mappedLinkee->GetSupportDirectory();
+        if (lg->GetGlobalGenerator()->IsMultiConfig()) {
+          di = cmStrCat(di, '/', config);
+        }
+        if (forward == Forwarding::Yes &&
+            forward_emitted.insert(mappedLinkee).second) {
+          dirs.Forward.push_back(di);
+        }
+        if (direct_emitted.insert(mappedLinkee).second) {
+          dirs.Direct.emplace_back(di);
+        }
+      }
+    };
     for (auto const& item : cli->GetItems()) {
       if (item.Target) {
         addLinkedTarget(item.Target, Forwarding::No);
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index 324ff30..5ff8784 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -3,7 +3,6 @@
 #include "cmComputeLinkInformation.h"
 
 #include <algorithm>
-#include <cctype>
 #include <sstream>
 #include <utility>
 
@@ -13,6 +12,8 @@
 #include <cmext/algorithm>
 #include <cmext/string_view>
 
+#include "cmsys/String.h"
+
 #include "cmComputeLinkDepends.h"
 #include "cmGeneratorTarget.h"
 #include "cmGlobalGenerator.h"
@@ -1556,8 +1557,8 @@
       ret += c;
     } else {
       ret += '[';
-      ret += static_cast<char>(tolower(static_cast<unsigned char>(c)));
-      ret += static_cast<char>(toupper(static_cast<unsigned char>(c)));
+      ret += static_cast<char>(cmsysString_tolower(c));
+      ret += static_cast<char>(cmsysString_toupper(c));
       ret += ']';
     }
   }
diff --git a/Source/cmCurl.cxx b/Source/cmCurl.cxx
index 484ac1f..ab30dc6 100644
--- a/Source/cmCurl.cxx
+++ b/Source/cmCurl.cxx
@@ -227,38 +227,6 @@
   return e;
 }
 
-std::string cmCurlFixFileURL(std::string url)
-{
-  if (!cmHasLiteralPrefix(url, "file://")) {
-    return url;
-  }
-
-  // libcurl 7.77 and below accidentally allowed spaces in URLs in some cases.
-  // One such case was file:// URLs, which CMake has long accepted as a result.
-  // Explicitly encode spaces for a URL.
-  cmSystemTools::ReplaceString(url, " ", "%20");
-
-#if defined(_WIN32)
-  // libcurl doesn't support file:// urls for unicode filenames on Windows.
-  // Convert string from UTF-8 to ACP if this is a file:// URL.
-  std::wstring wurl = cmsys::Encoding::ToWide(url);
-  if (!wurl.empty()) {
-    int mblen = WideCharToMultiByte(CP_ACP, 0, wurl.c_str(), -1, nullptr, 0,
-                                    nullptr, nullptr);
-    if (mblen > 0) {
-      std::vector<char> chars(mblen);
-      mblen = WideCharToMultiByte(CP_ACP, 0, wurl.c_str(), -1, &chars[0],
-                                  mblen, nullptr, nullptr);
-      if (mblen > 0) {
-        url = &chars[0];
-      }
-    }
-  }
-#endif
-
-  return url;
-}
-
 ::CURL* cm_curl_easy_init()
 {
   ::CURL* curl = curl_easy_init();
diff --git a/Source/cmCurl.h b/Source/cmCurl.h
index 3d60671..321ef5a 100644
--- a/Source/cmCurl.h
+++ b/Source/cmCurl.h
@@ -21,7 +21,6 @@
 std::string cmCurlSetCAInfo(::CURL* curl, std::string const& cafile = {});
 std::string cmCurlSetNETRCOption(::CURL* curl, std::string const& netrc_level,
                                  std::string const& netrc_file);
-std::string cmCurlFixFileURL(std::string url);
 
 ::CURLcode cm_curl_global_init(long flags);
 ::CURL* cm_curl_easy_init();
diff --git a/Source/cmCxxModuleUsageEffects.cxx b/Source/cmCxxModuleUsageEffects.cxx
index aa1a13f..8985a58 100644
--- a/Source/cmCxxModuleUsageEffects.cxx
+++ b/Source/cmCxxModuleUsageEffects.cxx
@@ -2,17 +2,28 @@
    file LICENSE.rst or https://cmake.org/licensing for details.  */
 #include "cmCxxModuleUsageEffects.h"
 
-cmCxxModuleUsageEffects::cmCxxModuleUsageEffects(
-  cmGeneratorTarget const* /*gt*/)
-  : Hash("0000000000000000000000000000000000000000")
+#include <cm/optional>
+
+#include "cmCryptoHash.h"
+#include "cmGeneratorTarget.h"
+#include "cmTarget.h"
+
+cmCxxModuleUsageEffects::cmCxxModuleUsageEffects(cmGeneratorTarget const* gt)
 {
-  // TODO: collect information from the generator target as to what might
-  // affect module consumption.
+  cmCryptoHash hasher(cmCryptoHash::AlgoSHA3_512);
+  this->Hash = hasher.HashString(gt->GetName());
+
+  // Collect compile features from the consuming target.
+  for (auto const& feature : gt->Target->GetCompileFeaturesEntries()) {
+    this->CompileFeatures.emplace_back(feature);
+  }
 }
 
-void cmCxxModuleUsageEffects::ApplyToTarget(cmTarget* /*tgt*/)
+void cmCxxModuleUsageEffects::ApplyToTarget(cmTarget* tgt)
 {
-  // TODO: apply the information collected in the constructor
+  for (auto const& feature : this->CompileFeatures) {
+    tgt->AppendProperty("COMPILE_FEATURES", feature.Value, feature.Backtrace);
+  }
 }
 
 std::string const& cmCxxModuleUsageEffects::GetHash() const
diff --git a/Source/cmCxxModuleUsageEffects.h b/Source/cmCxxModuleUsageEffects.h
index 1c3933c..56a85b9 100644
--- a/Source/cmCxxModuleUsageEffects.h
+++ b/Source/cmCxxModuleUsageEffects.h
@@ -5,6 +5,9 @@
 #include "cmConfigure.h" // IWYU pragma: keep
 
 #include <string>
+#include <vector>
+
+#include "cmListFileCache.h"
 
 class cmGeneratorTarget;
 class cmTarget;
@@ -19,4 +22,5 @@
 
 private:
   std::string Hash;
+  std::vector<BT<std::string>> CompileFeatures;
 };
diff --git a/Source/cmDocumentation.cxx b/Source/cmDocumentation.cxx
index 35cf9e4..66e3730 100644
--- a/Source/cmDocumentation.cxx
+++ b/Source/cmDocumentation.cxx
@@ -3,13 +3,13 @@
 #include "cmDocumentation.h"
 
 #include <algorithm>
-#include <cctype>
 #include <cstring>
 #include <utility>
 
 #include "cmsys/FStream.hxx"
 #include "cmsys/Glob.hxx"
 #include "cmsys/RegularExpression.hxx"
+#include "cmsys/String.h"
 
 #if !defined(CMAKE_BOOTSTRAP)
 #  include <memory>
@@ -516,7 +516,7 @@
     std::string line;
     cmsys::ifstream fin(f.c_str());
     while (fin && cmSystemTools::GetLineFromStream(fin, line)) {
-      if (!line.empty() && (isalnum(line[0]) || line[0] == '<')) {
+      if (!line.empty() && (cmsysString_isalnum(line[0]) || line[0] == '<')) {
         names.push_back(line);
         break;
       }
diff --git a/Source/cmDyndepCollation.cxx b/Source/cmDyndepCollation.cxx
index 2a17925..3122722 100644
--- a/Source/cmDyndepCollation.cxx
+++ b/Source/cmDyndepCollation.cxx
@@ -108,6 +108,11 @@
     if (fs_type != "CXX_MODULES"_s) {
       continue;
     }
+    // Synthetic (BMI-only) targets do not build private C++ modules.
+    if (tgt->IsSynthetic() &&
+        file_set->GetVisibility() == cmFileSetVisibility::Private) {
+      continue;
+    }
 
     auto fileEntries = file_set->CompileFileEntries();
     auto directoryEntries = file_set->CompileDirectoryEntries();
diff --git a/Source/cmExecuteProcessCommand.cxx b/Source/cmExecuteProcessCommand.cxx
index 7050f0d..63dcb60 100644
--- a/Source/cmExecuteProcessCommand.cxx
+++ b/Source/cmExecuteProcessCommand.cxx
@@ -24,6 +24,8 @@
 #  include "cm_fileno.hxx"
 #endif
 
+#include "cmsys/String.h"
+
 #include "cmArgumentParser.h"
 #include "cmExecutionStatus.h"
 #include "cmList.h"
@@ -40,7 +42,7 @@
 namespace {
 bool cmExecuteProcessCommandIsWhitespace(char c)
 {
-  return (cmIsSpace(c) || c == '\n' || c == '\r');
+  return (cmsysString_isspace(c) || c == '\n' || c == '\r');
 }
 
 FILE* FopenCLOEXEC(std::string const& path, char const* mode)
diff --git a/Source/cmExperimental.cxx b/Source/cmExperimental.cxx
index 60e3aea..3d022d7 100644
--- a/Source/cmExperimental.cxx
+++ b/Source/cmExperimental.cxx
@@ -29,24 +29,6 @@
     "only for experimentation and feedback to CMake developers.",
     {},
     cmExperimental::TryCompileCondition::Always },
-  // ImportPackageInfo
-  { "ImportPackageInfo",
-    "e82e467b-f997-4464-8ace-b00808fff261",
-    "CMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES",
-    "CMake's support for importing package information in the Common Package "
-    "Specification format (via find_package) is experimental. It is meant "
-    "only for experimentation and feedback to CMake developers.",
-    {},
-    cmExperimental::TryCompileCondition::Always },
-  // ExportPackageInfo
-  { "ExportPackageInfo",
-    "7fa7d13b-8308-4dc7-af39-9e450456d68f",
-    "CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO",
-    "CMake's support for exporting package information in the Common Package "
-    "Specification format is experimental. It is meant only for "
-    "experimentation and feedback to CMake developers.",
-    {},
-    cmExperimental::TryCompileCondition::Always },
   // MappedPackageInfo
   { "MappedPackageInfo",
     "ababa1b5-7099-495f-a9cd-e22d38f274f2",
diff --git a/Source/cmExperimental.h b/Source/cmExperimental.h
index 2b465a0..79dbd5f 100644
--- a/Source/cmExperimental.h
+++ b/Source/cmExperimental.h
@@ -18,8 +18,6 @@
   enum class Feature
   {
     ExportPackageDependencies,
-    ImportPackageInfo,
-    ExportPackageInfo,
     MappedPackageInfo,
     ExportBuildDatabase,
     GenerateSbom,
diff --git a/Source/cmExportCommand.cxx b/Source/cmExportCommand.cxx
index 65f1b12..38c2458 100644
--- a/Source/cmExportCommand.cxx
+++ b/Source/cmExportCommand.cxx
@@ -401,12 +401,6 @@
 static bool HandlePackageInfoMode(std::vector<std::string> const& args,
                                   cmExecutionStatus& status)
 {
-  if (!cmExperimental::HasSupportEnabled(
-        status.GetMakefile(), cmExperimental::Feature::ExportPackageInfo)) {
-    status.SetError("does not recognize sub-command PACKAGE_INFO");
-    return false;
-  }
-
   using arg_t = cmPackageInfoArguments;
   using gen_t = cmExportBuildPackageInfoGenerator;
   return HandleSpecialExportMode<arg_t, gen_t>(args, status);
diff --git a/Source/cmExportPackageInfoGenerator.cxx b/Source/cmExportPackageInfoGenerator.cxx
index 20c1978..a30b0b0 100644
--- a/Source/cmExportPackageInfoGenerator.cxx
+++ b/Source/cmExportPackageInfoGenerator.cxx
@@ -30,7 +30,7 @@
 #include "cmSystemTools.h"
 #include "cmTarget.h"
 
-static std::string const kCPS_VERSION_STR = "0.14.0";
+static std::string const kCPS_VERSION_STR = "0.14.1";
 
 cmExportPackageInfoGenerator::cmExportPackageInfoGenerator(
   cmPackageInfoArguments arguments)
@@ -386,6 +386,28 @@
   return false;
 }
 
+std::vector<std::string> cmExportPackageInfoGenerator::ExtractRequirements(
+  std::vector<std::string> const& names, bool& result,
+  std::vector<std::string>& libraryPaths) const
+{
+  std::vector<std::string> output;
+
+  for (auto const& name : names) {
+    auto const& ti = this->LinkTargets.find(name);
+    if (ti != this->LinkTargets.end()) {
+      if (ti->second.empty()) {
+        result = false;
+      } else {
+        output.emplace_back(ti->second);
+      }
+    } else {
+      libraryPaths.emplace_back(name);
+    }
+  }
+
+  return output;
+}
+
 void cmExportPackageInfoGenerator::GenerateInterfaceLinkProperties(
   bool& result, Json::Value& component, cmGeneratorTarget const* target,
   ImportPropertyMap const& properties) const
@@ -397,43 +419,26 @@
 
   // Extract any $<LINK_ONLY:...> from the link libraries, and assert that no
   // other generator expressions are present.
-  std::map<std::string, std::vector<std::string>> allowList = {
-    { "COMPILE_ONLY", {} },
-    { "LINK_ONLY", {} },
-  };
+  std::map<std::string, std::vector<std::string>>
+    allowedGeneratorExpressions = {
+      { "COMPILE_ONLY", {} },
+      { "LINK_ONLY", {} },
+    };
   std::string interfaceLinkLibraries;
   if (!cmGeneratorExpression::ForbidGeneratorExpressions(
         target, iter->first, iter->second, interfaceLinkLibraries,
-        allowList)) {
+        allowedGeneratorExpressions)) {
     result = false;
     return;
   }
 
-  std::vector<std::string> buildRequires;
-  std::vector<std::string> compileRequires;
-  std::vector<std::string> linkRequires;
   std::vector<std::string> linkLibraries;
-
-  auto addLibraries = [this, &linkLibraries,
-                       &result](std::vector<std::string> const& names,
-                                std::vector<std::string>& output) -> void {
-    for (auto const& name : names) {
-      auto const& ti = this->LinkTargets.find(name);
-      if (ti != this->LinkTargets.end()) {
-        if (ti->second.empty()) {
-          result = false;
-        } else {
-          output.emplace_back(ti->second);
-        }
-      } else {
-        linkLibraries.emplace_back(name);
-      }
-    }
-  };
-
-  addLibraries(allowList["COMPILE_ONLY"], compileRequires);
-  addLibraries(allowList["LINK_ONLY"], linkRequires);
-  addLibraries(cmList{ interfaceLinkLibraries }, buildRequires);
+  std::vector<std::string> buildRequires = this->ExtractRequirements(
+    cmList{ interfaceLinkLibraries }, result, linkLibraries);
+  std::vector<std::string> compileRequires = this->ExtractRequirements(
+    allowedGeneratorExpressions["COMPILE_ONLY"], result, linkLibraries);
+  std::vector<std::string> linkRequires = this->ExtractRequirements(
+    allowedGeneratorExpressions["LINK_ONLY"], result, linkLibraries);
 
   BuildArray(component, "requires", buildRequires);
   BuildArray(component, "link_requires", linkRequires);
@@ -560,6 +565,22 @@
       component["location"] = p.second;
     } else if (prop == "IMPLIB") {
       component["link_location"] = p.second;
+    } else if (prop == "LINK_DEPENDENT_LIBRARIES") {
+      bool result;
+      std::vector<std::string> libraries;
+      std::vector<std::string> components =
+        this->ExtractRequirements(cmList{ p.second }, result, libraries);
+      BuildArray(component, "dyld_requires", components);
+      if (!libraries.empty()) {
+        // In theory this can never happen?
+        this->IssueMessage(
+          MessageType::AUTHOR_WARNING,
+          cmStrCat("Package \""_s, this->GetPackageName(),
+                   "\" has IMPORTED_LINK_DEPENDENT_LIBRARIES \""_s,
+                   cmJoin(libraries, ";"_s), this->PackageVersionSchema,
+                   "\". These cannot be exported. "
+                   "Consumers may encounter link errors."_s));
+      }
     } else if (prop == "LINK_INTERFACE_LANGUAGES") {
       std::vector<std::string> languages;
       for (auto const& lang : cmList{ p.second }) {
diff --git a/Source/cmExportPackageInfoGenerator.h b/Source/cmExportPackageInfoGenerator.h
index c5d1f75..d7eeba2 100644
--- a/Source/cmExportPackageInfoGenerator.h
+++ b/Source/cmExportPackageInfoGenerator.h
@@ -94,6 +94,10 @@
   bool CheckVersion() const;
   bool CheckDefaultTargets() const;
 
+  std::vector<std::string> ExtractRequirements(
+    std::vector<std::string> const& names, bool& result,
+    std::vector<std::string>& libraryPaths) const;
+
   void GenerateInterfaceLinkProperties(
     bool& result, Json::Value& component, cmGeneratorTarget const* target,
     ImportPropertyMap const& properties) const;
diff --git a/Source/cmFastbuildNormalTargetGenerator.cxx b/Source/cmFastbuildNormalTargetGenerator.cxx
index cc21591..f9acd33 100644
--- a/Source/cmFastbuildNormalTargetGenerator.cxx
+++ b/Source/cmFastbuildNormalTargetGenerator.cxx
@@ -1399,9 +1399,11 @@
 
     cmSourceFile const& srcFile = *source;
     std::string const pathToFile = srcFile.GetFullPath();
+    bool fileUsesUnity = useUnity;
     if (useUnity) {
       // Check if the source should be added to "UnityInputIsolatedFiles".
       if (srcFile.GetPropertyAsBool(SKIP_UNITY_BUILD_INCLUSION)) {
+        fileUsesUnity = false;
         isolatedFromUnity.emplace(pathToFile);
       }
       std::string const perFileUnityGroup =
@@ -1441,11 +1443,17 @@
 
       // If object should be placed in some subdir in the output
       // path. Tested in "SourceGroups" test.
-      auto const subdir = cmSystemTools::GetFilenamePath(
-        this->GeneratorTarget->GetObjectName(source));
-      if (!subdir.empty()) {
-        objOutDirWithPossibleSubdir += "/";
-        objOutDirWithPossibleSubdir += subdir;
+      // Not necessary for files in unity buckets because they are
+      // built into a single unity object file. Executing this logic
+      // for unity bucketed files prevents buckets from containing
+      // source files in different subdirectories.
+      if (!fileUsesUnity) {
+        auto const subdir = cmSystemTools::GetFilenamePath(
+          this->GeneratorTarget->GetObjectName(source));
+        if (!subdir.empty()) {
+          objOutDirWithPossibleSubdir += "/";
+          objOutDirWithPossibleSubdir += subdir;
+        }
       }
 
       std::string const objectListHash = hash.HashString(cmStrCat(
diff --git a/Source/cmFileAPICommand.cxx b/Source/cmFileAPICommand.cxx
index dbd8f05..091fbc8 100644
--- a/Source/cmFileAPICommand.cxx
+++ b/Source/cmFileAPICommand.cxx
@@ -4,13 +4,14 @@
 
 #include <algorithm>
 #include <array>
-#include <cctype>
 #include <cstdlib>
 #include <utility>
 
 #include <cm/string_view>
 #include <cmext/string_view>
 
+#include "cmsys/String.h"
+
 #include "cmArgumentParser.h"
 #include "cmArgumentParserTypes.h"
 #include "cmExecutionStatus.h"
@@ -23,11 +24,6 @@
 
 namespace {
 
-bool isCharDigit(char ch)
-{
-  return std::isdigit(static_cast<unsigned char>(ch));
-}
-
 std::string processObjectKindVersions(cmFileAPI& fileApi,
                                       cmFileAPI::ObjectKind objectKind,
                                       cm::string_view keyword,
@@ -103,7 +99,7 @@
   }
 
   if (!std::all_of(arguments.ApiVersion.begin(), arguments.ApiVersion.end(),
-                   isCharDigit)) {
+                   cmsysString_isdigit)) {
     status.SetError("QUERY given non-integer API_VERSION.");
     return false;
   }
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index f964367..16cd19b 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -4,7 +4,6 @@
 
 #include <algorithm>
 #include <cassert>
-#include <cctype>
 #include <cmath>
 #include <cstdio>
 #include <cstdlib>
@@ -26,6 +25,7 @@
 #include "cmsys/FStream.hxx"
 #include "cmsys/Glob.hxx"
 #include "cmsys/RegularExpression.hxx"
+#include "cmsys/String.h"
 
 #include "cm_sys_stat.h"
 
@@ -519,7 +519,8 @@
     }
 
     if (c >= 0 && c <= 0xFF &&
-        (isprint(c) || c == '\t' || (c == '\n' && newline_consume))) {
+        (cmsysString_isprint(static_cast<char>(c)) || c == '\t' ||
+         (c == '\n' && newline_consume))) {
       // This is an ASCII character that may be part of a string.
       // Cast added to avoid compiler warning. Cast is ok because
       // c is guaranteed to fit in char by the above if...
@@ -1698,6 +1699,16 @@
 // Stuff for curl download/upload
 using cmFileCommandVectorOfChar = std::vector<char>;
 
+std::string CurlCompatFileURL(std::string url)
+{
+  if (cmHasLiteralPrefix(url, "file://")) {
+    // libcurl 7.77 and below accidentally allowed spaces in file:// URLs,
+    // which CMake has long accepted as a result.  Explicitly encode spaces.
+    cmSystemTools::ReplaceString(url, " ", "%20");
+  }
+  return url;
+}
+
 size_t cmWriteToFileCallback(void* ptr, size_t size, size_t nmemb, void* data)
 {
   int realsize = static_cast<int>(size * nmemb);
@@ -2139,7 +2150,7 @@
     }
   }
 
-  url = cmCurlFixFileURL(url);
+  url = CurlCompatFileURL(url);
 
   ::CURL* curl;
   cm_curl_global_init(CURL_GLOBAL_DEFAULT);
@@ -2541,7 +2552,7 @@
 
   unsigned long file_size = cmsys::SystemTools::FileLength(filename);
 
-  url = cmCurlFixFileURL(url);
+  url = CurlCompatFileURL(url);
 
   ::CURL* curl;
   cm_curl_global_init(CURL_GLOBAL_DEFAULT);
@@ -3757,7 +3768,7 @@
 
   if (!parsedArgs.CompressionLevel.empty()) {
     if (parsedArgs.CompressionLevel.size() != 1 &&
-        !std::isdigit(parsedArgs.CompressionLevel[0])) {
+        !cmsysString_isdigit(parsedArgs.CompressionLevel[0])) {
       status.SetError(
         cmStrCat("compression level ", parsedArgs.CompressionLevel, " for ",
                  parsedArgs.Compression, " should be in range ",
@@ -3790,7 +3801,7 @@
   constexpr int minThreads = 0;
   if (!parsedArgs.Threads.empty()) {
     if (parsedArgs.Threads.size() != 1 &&
-        !std::isdigit(parsedArgs.Threads[0])) {
+        !cmsysString_isdigit(parsedArgs.Threads[0])) {
       status.SetError(cmStrCat("number of threads ", parsedArgs.Threads,
                                " should be at least ", minThreads));
       cmSystemTools::SetFatalErrorOccurred();
diff --git a/Source/cmFindLibraryCommand.cxx b/Source/cmFindLibraryCommand.cxx
index ad36c4a..57d2a41 100644
--- a/Source/cmFindLibraryCommand.cxx
+++ b/Source/cmFindLibraryCommand.cxx
@@ -3,7 +3,6 @@
 #include "cmFindLibraryCommand.h"
 
 #include <algorithm>
-#include <cctype>
 #include <cstdio>
 #include <cstring>
 #include <set>
@@ -13,6 +12,7 @@
 #include <cm/optional>
 
 #include "cmsys/RegularExpression.hxx"
+#include "cmsys/String.h"
 
 #include "cmFindCommon.h"
 #include "cmGlobalGenerator.h"
@@ -349,7 +349,7 @@
       out += "\\";
     }
     if (dirCase == cmSystemTools::DirCase::Insensitive) {
-      out += static_cast<char>(tolower(static_cast<unsigned char>(ch)));
+      out += static_cast<char>(cmsysString_tolower(ch));
     } else {
       out += ch;
     }
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index dd8c580..cf6184b 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -27,7 +27,6 @@
 #include "cmConfigureLog.h"
 #include "cmDependencyProvider.h"
 #include "cmExecutionStatus.h"
-#include "cmExperimental.h"
 #include "cmFindPackageStack.h"
 #include "cmList.h"
 #include "cmListFileCache.h"
@@ -926,9 +925,7 @@
   // Check and eliminate search modes not allowed by the args provided
   this->UseFindModules = configArgs.empty();
   this->UseConfigFiles = moduleArgs.empty();
-  if (this->UseConfigFiles &&
-      cmExperimental::HasSupportEnabled(
-        *this->Makefile, cmExperimental::Feature::ImportPackageInfo)) {
+  if (this->UseConfigFiles) {
     this->UseCpsFiles = this->Configs.empty();
   } else {
     this->UseCpsFiles = false;
diff --git a/Source/cmGccDepfileLexerHelper.cxx b/Source/cmGccDepfileLexerHelper.cxx
index 3136f69..478a93d 100644
--- a/Source/cmGccDepfileLexerHelper.cxx
+++ b/Source/cmGccDepfileLexerHelper.cxx
@@ -12,9 +12,8 @@
 #include "LexerParser/cmGccDepfileLexer.h"
 
 #ifdef _WIN32
-#  include <cctype>
-
 #  include "cmsys/Encoding.h"
+#  include "cmsys/String.h"
 #endif
 
 bool cmGccDepfileLexerHelper::readFile(char const* filePath)
@@ -128,8 +127,7 @@
         // Some versions of GNU compilers can escape this character.
         // c\:\path must be transformed to c:\path
         if (pit->size() >= 3) {
-          auto pit0 = static_cast<char>(
-            std::toupper(static_cast<unsigned char>((*pit)[0])));
+          auto pit0 = static_cast<char>(cmsysString_toupper((*pit)[0]));
           if (pit0 >= 'A' && pit0 <= 'Z' && (*pit)[1] == '\\' &&
               (*pit)[2] == ':') {
             pit->erase(1, 1);
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index c5f4e35..4799c78 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -5,7 +5,6 @@
 #include <algorithm>
 #include <array>
 #include <cassert>
-#include <cctype>
 #include <cstddef>
 #include <cstdio>
 #include <cstring>
@@ -20,6 +19,8 @@
 #include <cmext/algorithm>
 #include <cmext/string_view>
 
+#include "cmsys/String.h"
+
 #include "cmAlgorithms.h"
 #include "cmComputeLinkInformation.h" // IWYU pragma: keep
 #include "cmCryptoHash.h"
@@ -3953,8 +3954,7 @@
 
     if (linkerType != "DEFAULT"_s) {
       auto isCMakeLinkerType = [](std::string const& type) -> bool {
-        return std::all_of(type.cbegin(), type.cend(),
-                           [](char c) { return std::isupper(c); });
+        return std::all_of(type.cbegin(), type.cend(), cmsysString_isupper);
       };
       if (isCMakeLinkerType(linkerType)) {
         this->LocalGenerator->IssueMessage(
@@ -5309,118 +5309,135 @@
   return true;
 }
 
-bool cmGeneratorTarget::DiscoverSyntheticTargets(cmSyntheticTargetCache& cache,
-                                                 std::string const& config)
+bool cmGeneratorTarget::DiscoverSyntheticTargets(
+  cmSyntheticTargetCache& cache, std::string const& config,
+  cmGeneratorTarget const* bmiConsumer)
 {
   std::vector<std::string> allConfigs =
     this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
   cmOptionalLinkImplementation impl;
   this->ComputeLinkImplementationLibraries(config, impl, UseTo::Link);
 
-  cmCxxModuleUsageEffects usage(this);
+  if (!bmiConsumer) {
+    bmiConsumer = this;
+  }
+
+  cmCxxModuleUsageEffects usage(bmiConsumer);
 
   auto& SyntheticDeps = this->Configs[config].SyntheticDeps;
 
   for (auto const& entry : impl.Libraries) {
     auto const* gt = entry.Target;
-    if (!gt || !gt->IsImported()) {
+    if (!gt || !gt->HaveCxx20ModuleSources()) {
       continue;
     }
 
-    if (gt->HaveCxx20ModuleSources()) {
-      cmCryptoHash hasher(cmCryptoHash::AlgoSHA3_512);
-      constexpr size_t HASH_TRUNCATION = 12;
-      auto dirhash = hasher.HashString(
-        gt->GetLocalGenerator()->GetCurrentBinaryDirectory());
-      std::string safeName = gt->GetName();
-      cmSystemTools::ReplaceString(safeName, ":", "_");
-      auto targetIdent =
-        hasher.HashString(cmStrCat("@d_", dirhash, "@u_", usage.GetHash()));
-      std::string targetName =
-        cmStrCat(safeName, "@synth_", targetIdent.substr(0, HASH_TRUNCATION));
+    // Visual Studio generators do not currently support BMI-only compilation,
+    // so they can't generate synthetic targets. For consuming native modules,
+    // skip so that the native target is used directly. For imported modules,
+    // create the synth target anyway and diagnose later, in the VS generator.
+    if (!gt->IsImported() && this->GlobalGenerator->IsVisualStudio()) {
+      continue;
+    }
 
-      // Check the cache to see if this instance of the imported target has
-      // already been created.
-      auto cached = cache.CxxModuleTargets.find(targetName);
-      cmGeneratorTarget const* synthDep = nullptr;
-      if (cached == cache.CxxModuleTargets.end()) {
-        auto const* model = gt->Target;
-        auto* mf = gt->Makefile;
-        auto* lg = gt->GetLocalGenerator();
-        auto* tgt = mf->AddSynthesizedTarget(cmStateEnums::INTERFACE_LIBRARY,
-                                             targetName);
+    cmCryptoHash hasher(cmCryptoHash::AlgoSHA3_512);
+    constexpr size_t HASH_TRUNCATION = 12;
+    auto dirhash =
+      hasher.HashString(gt->GetLocalGenerator()->GetCurrentBinaryDirectory());
+    std::string safeName = gt->GetName();
+    cmSystemTools::ReplaceString(safeName, ":", "_");
+    auto targetIdent =
+      hasher.HashString(cmStrCat("@d_", dirhash, "@u_", usage.GetHash()));
+    std::string targetName =
+      cmStrCat(safeName, "@synth_", targetIdent.substr(0, HASH_TRUNCATION));
 
-        // Copy relevant information from the existing IMPORTED target.
+    // Check the cache to see if this instance of the target has
+    // already been created.
+    auto cached = cache.CxxModuleTargets.find(targetName);
+    cmGeneratorTarget const* synthDep = nullptr;
+    if (cached == cache.CxxModuleTargets.end()) {
+      auto const* model = gt->Target;
+      auto* mf = gt->Makefile;
+      auto* lg = gt->GetLocalGenerator();
+      auto* tgt =
+        mf->AddSynthesizedTarget(cmStateEnums::INTERFACE_LIBRARY, targetName);
 
-        // Copy policies to the target.
-        tgt->CopyPolicyStatuses(model);
+      // Copy relevant information from the existing target.
 
-        // Copy file sets.
-        {
-          auto fsNames = model->GetAllFileSetNames();
-          for (auto const& fsName : fsNames) {
-            auto const* fs = model->GetFileSet(fsName);
-            if (!fs) {
-              mf->IssueMessage(MessageType::INTERNAL_ERROR,
-                               cmStrCat("Failed to find file set named '",
-                                        fsName, "' on target '",
-                                        tgt->GetName(), '\''));
-              continue;
-            }
-            auto* newFs = tgt
-                            ->GetOrCreateFileSet(fs->GetName(), fs->GetType(),
-                                                 fs->GetVisibility())
-                            .first;
-            newFs->CopyEntries(fs);
+      // Copy policies to the target.
+      tgt->CopyPolicyStatuses(model);
+
+      // Copy file sets.
+      {
+        auto fsNames = model->GetAllFileSetNames();
+        for (auto const& fsName : fsNames) {
+          auto const* fs = model->GetFileSet(fsName);
+          if (!fs) {
+            mf->IssueMessage(MessageType::INTERNAL_ERROR,
+                             cmStrCat("Failed to find file set named '",
+                                      fsName, "' on target '", tgt->GetName(),
+                                      '\''));
+            continue;
           }
+          auto* newFs = tgt
+                          ->GetOrCreateFileSet(fs->GetName(), fs->GetType(),
+                                               fs->GetVisibility())
+                          .first;
+          newFs->CopyEntries(fs);
         }
-
-        // Copy imported C++ module properties.
-        tgt->CopyImportedCxxModulesEntries(model);
-
-        // Copy other properties which may affect the C++ module BMI
-        // generation.
-        tgt->CopyImportedCxxModulesProperties(model);
-
-        tgt->AddLinkLibrary(*mf,
-                            cmStrCat("$<COMPILE_ONLY:", model->GetName(), '>'),
-                            GENERAL_LibraryType);
-
-        // Apply usage requirements to the target.
-        usage.ApplyToTarget(tgt);
-
-        // Create the generator target and attach it to the local generator.
-        auto gtp = cm::make_unique<cmGeneratorTarget>(tgt, lg);
-
-        synthDep = gtp.get();
-        cache.CxxModuleTargets[targetName] = synthDep;
-
-        // See `localGen->ComputeTargetCompileFeatures()` call in
-        // `cmGlobalGenerator::Compute` for where non-synthetic targets resolve
-        // this.
-        for (auto const& innerConfig : allConfigs) {
-          gtp->ComputeCompileFeatures(innerConfig);
-        }
-        // See `cmGlobalGenerator::ApplyCXXStdTargets` in
-        // `cmGlobalGenerator::Compute` for non-synthetic target resolutions.
-        if (!gtp->ApplyCXXStdTargets()) {
-          return false;
-        }
-
-        gtp->DiscoverSyntheticTargets(cache, config);
-
-        lg->AddGeneratorTarget(std::move(gtp));
-      } else {
-        synthDep = cached->second;
       }
 
-      SyntheticDeps[gt].push_back(synthDep);
+      // Copy C++ module properties.
+      tgt->CopyCxxModulesEntries(model);
+
+      // Copy other properties which may affect the C++ module BMI
+      // generation.
+      tgt->CopyCxxModulesProperties(model);
+
+      tgt->AddLinkLibrary(*mf,
+                          cmStrCat("$<COMPILE_ONLY:", model->GetName(), '>'),
+                          GENERAL_LibraryType);
+
+      // Apply usage requirements to the target.
+      usage.ApplyToTarget(tgt);
+
+      // Create the generator target and attach it to the local generator.
+      auto gtp = cm::make_unique<cmGeneratorTarget>(tgt, lg);
+
+      synthDep = gtp.get();
+      cache.CxxModuleTargets[targetName] = synthDep;
+
+      // See `localGen->ComputeTargetCompileFeatures()` call in
+      // `cmGlobalGenerator::Compute` for where non-synthetic targets resolve
+      // this.
+      for (auto const& innerConfig : allConfigs) {
+        gtp->ComputeCompileFeatures(innerConfig);
+      }
+      // See `cmGlobalGenerator::ApplyCXXStdTargets` in
+      // `cmGlobalGenerator::Compute` for non-synthetic target resolutions.
+      if (!gtp->ApplyCXXStdTargets()) {
+        return false;
+      }
+
+      gtp->DiscoverSyntheticTargets(cache, config, bmiConsumer);
+
+      lg->AddGeneratorTarget(std::move(gtp));
+    } else {
+      synthDep = cached->second;
     }
+
+    SyntheticDeps[gt].push_back(synthDep);
   }
 
   return true;
 }
 
+cmGeneratorTarget::SyntheticDepsMap const& cmGeneratorTarget::GetSyntheticDeps(
+  std::string const& config) const
+{
+  return this->Configs[config].SyntheticDeps;
+}
+
 bool cmGeneratorTarget::HasPackageReferences() const
 {
   return this->IsInBuildSystem() &&
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index a32ecba..8c56a9b 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -1118,8 +1118,13 @@
   std::string GetImportedXcFrameworkPath(std::string const& config) const;
 
   bool ApplyCXXStdTargets();
-  bool DiscoverSyntheticTargets(cmSyntheticTargetCache& cache,
-                                std::string const& config);
+  bool DiscoverSyntheticTargets(
+    cmSyntheticTargetCache& cache, std::string const& config,
+    cmGeneratorTarget const* bmiConsumer = nullptr);
+
+  using SyntheticDepsMap =
+    std::map<cmGeneratorTarget const*, std::vector<cmGeneratorTarget const*>>;
+  SyntheticDepsMap const& GetSyntheticDeps(std::string const& config) const;
 
   class CustomTransitiveProperty : public TransitiveProperty
   {
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 46bb45e..f603fe2 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -4,7 +4,6 @@
 
 #include <algorithm>
 #include <cassert>
-#include <cctype>
 #include <cstdio>
 #include <functional>
 #include <iterator>
@@ -23,6 +22,7 @@
 #include <cm3p/json/writer.h>
 
 #include "cmsys/FStream.hxx"
+#include "cmsys/String.h"
 
 #include "cmCustomCommand.h"
 #include "cmCxxModuleMapper.h"
@@ -172,7 +172,7 @@
   // "." and all invalid characters as hexadecimal.
   std::string encoded;
   for (char i : name) {
-    if (isalnum(i) || i == '_' || i == '-') {
+    if (cmsysString_isalnum(i) || i == '_' || i == '-') {
       encoded += i;
     } else {
       char buf[16];
@@ -2587,8 +2587,8 @@
   std::string const& module_dir,
   std::vector<std::string> const& linked_target_dirs,
   std::vector<std::string> const& forward_modules_from_target_dirs,
-  std::string const& arg_lang, std::string const& arg_modmapfmt,
-  cmCxxModuleExportInfo const& export_info)
+  std::string const& native_target_dir, std::string const& arg_lang,
+  std::string const& arg_modmapfmt, cmCxxModuleExportInfo const& export_info)
 {
   // Setup path conversions.
   {
@@ -2748,6 +2748,47 @@
     }
   }
 
+  // If this is a synthetic target for a non-imported target, read PRIVATE
+  // module info from the native target
+  if (!native_target_dir.empty()) {
+    std::string const modules_info_path =
+      cmStrCat(native_target_dir, '/', arg_lang, "Modules.json");
+    Json::Value native_modules_info;
+    cmsys::ifstream modules_file(modules_info_path.c_str(),
+                                 std::ios::in | std::ios::binary);
+    if (!modules_file) {
+      cmSystemTools::Error(cmStrCat("-E cmake_ninja_dyndep failed to open ",
+                                    modules_info_path,
+                                    " for module information"));
+      return false;
+    }
+    Json::Reader reader;
+    if (!reader.parse(modules_file, native_modules_info, false)) {
+      cmSystemTools::Error(cmStrCat("-E cmake_ninja_dyndep failed to parse ",
+                                    modules_info_path,
+                                    reader.getFormattedErrorMessages()));
+      return false;
+    }
+    if (native_modules_info.isObject()) {
+      Json::Value const& native_target_modules =
+        native_modules_info["modules"];
+      if (native_target_modules.isObject()) {
+        for (auto i = native_target_modules.begin();
+             i != native_target_modules.end(); ++i) {
+          Json::Value const& visible_module = *i;
+          if (visible_module.isObject()) {
+            auto is_private = visible_module["is-private"].asBool();
+            // Only add private modules since others are discovered by the
+            // synthetic target's own scan rules
+            if (is_private) {
+              target_modules[i.key().asString()] = visible_module;
+            }
+          }
+        }
+      }
+    }
+  }
+
   cmGeneratedFileStream ddf(arg_dd);
   ddf << "ninja_dyndep_version = 1.0\n";
 
@@ -3041,6 +3082,7 @@
         tdi_forward_modules_from_target_dir.asString());
     }
   }
+  std::string const native_target_dir = tdi["native-target-dir"].asString();
   std::string const compilerId = tdi["compiler-id"].asString();
   std::string const simulateId = tdi["compiler-simulate-id"].asString();
   std::string const compilerFrontendVariant =
@@ -3064,8 +3106,9 @@
 #  endif
   return gg.WriteDyndepFile(dir_top_src, dir_top_bld, dir_cur_src, dir_cur_bld,
                             arg_dd, arg_ddis, module_dir, linked_target_dirs,
-                            forward_modules_from_target_dirs, arg_lang,
-                            arg_modmapfmt, *export_info)
+                            forward_modules_from_target_dirs,
+                            native_target_dir, arg_lang, arg_modmapfmt,
+                            *export_info)
     ? 0
     : 1;
 }
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index 152c45c..059dea8 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -433,7 +433,8 @@
     std::string const& module_dir,
     std::vector<std::string> const& linked_target_dirs,
     std::vector<std::string> const& forward_modules_from_target_dirs,
-    std::string const& arg_lang, std::string const& arg_modmapfmt,
+    std::string const& native_target_dir, std::string const& arg_lang,
+    std::string const& arg_modmapfmt,
     cmCxxModuleExportInfo const& export_info);
 
   virtual std::string BuildAlias(std::string const& alias,
diff --git a/Source/cmGraphVizWriter.cxx b/Source/cmGraphVizWriter.cxx
index 53c9659..baba225 100644
--- a/Source/cmGraphVizWriter.cxx
+++ b/Source/cmGraphVizWriter.cxx
@@ -3,7 +3,6 @@
 #include "cmGraphVizWriter.h"
 
 #include <algorithm>
-#include <cctype>
 #include <iostream>
 #include <memory>
 #include <set>
@@ -13,6 +12,7 @@
 #include <cm/memory>
 
 #include "cmsys/RegularExpression.hxx"
+#include "cmsys/String.h"
 
 #include "cmGeneratedFileStream.h"
 #include "cmGeneratorTarget.h"
@@ -602,7 +602,7 @@
   auto const extra_chars = std::set<char>{ '.', '-', '_' };
 
   for (char c : str) {
-    if (std::isalnum(c) || extra_chars.find(c) != extra_chars.cend()) {
+    if (cmsysString_isalnum(c) || extra_chars.find(c) != extra_chars.cend()) {
       pathSafeStr += c;
     }
   }
diff --git a/Source/cmHexFileConverter.cxx b/Source/cmHexFileConverter.cxx
index a028bb4..3036473 100644
--- a/Source/cmHexFileConverter.cxx
+++ b/Source/cmHexFileConverter.cxx
@@ -2,10 +2,11 @@
    file LICENSE.rst or https://cmake.org/licensing for details.  */
 #include "cmHexFileConverter.h"
 
-#include <cctype>
 #include <cstdio>
 #include <cstring>
 
+#include "cmsys/String.h"
+
 #include "cmSystemTools.h"
 
 #define INTEL_HEX_MIN_LINE_LENGTH (1 + 8 + 2)
@@ -163,7 +164,7 @@
   }
 
   for (unsigned int i = 1; i < slen; i++) {
-    if (!isxdigit(buf[i])) {
+    if (!cmsysString_isxdigit(buf[i])) {
       return Binary;
     }
   }
diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx
index 9ee87b1..1d37546 100644
--- a/Source/cmInstallCommand.cxx
+++ b/Source/cmInstallCommand.cxx
@@ -2286,8 +2286,6 @@
 #ifndef CMAKE_BOOTSTRAP
   // Check if PACKAGE_INFO export has been requested for this export set.
   if (cmExperimental::HasSupportEnabled(
-        status.GetMakefile(), cmExperimental::Feature::ExportPackageInfo) &&
-      cmExperimental::HasSupportEnabled(
         status.GetMakefile(), cmExperimental::Feature::MappedPackageInfo)) {
     if (cmValue const& piExports = helper.Makefile->GetDefinition(
           "CMAKE_INSTALL_EXPORTS_AS_PACKAGE_INFO")) {
@@ -2321,12 +2319,6 @@
                            cmExecutionStatus& status)
 {
 #ifndef CMAKE_BOOTSTRAP
-  if (!cmExperimental::HasSupportEnabled(
-        status.GetMakefile(), cmExperimental::Feature::ExportPackageInfo)) {
-    status.SetError("does not recognize sub-command PACKAGE_INFO");
-    return false;
-  }
-
   Helper helper(status);
 
   // This is the PACKAGE_INFO mode.
diff --git a/Source/cmInstrumentationCommand.cxx b/Source/cmInstrumentationCommand.cxx
index 182deca..0b0d0f8 100644
--- a/Source/cmInstrumentationCommand.cxx
+++ b/Source/cmInstrumentationCommand.cxx
@@ -3,7 +3,6 @@
 #include "cmInstrumentationCommand.h"
 
 #include <algorithm>
-#include <cctype>
 #include <cstdlib>
 #include <functional>
 #include <set>
@@ -14,6 +13,8 @@
 #include <cm3p/json/reader.h>
 #include <cm3p/json/value.h>
 
+#include "cmsys/String.h"
+
 #include "cmArgumentParser.h"
 #include "cmArgumentParserTypes.h"
 #include "cmExecutionStatus.h"
@@ -27,14 +28,11 @@
 
 namespace {
 
-bool isCharDigit(char ch)
-{
-  return std::isdigit(static_cast<unsigned char>(ch));
-}
 bool validateVersion(std::string const& key, std::string const& versionString,
                      int& version, cmExecutionStatus& status)
 {
-  if (!std::all_of(versionString.begin(), versionString.end(), isCharDigit)) {
+  if (!std::all_of(versionString.begin(), versionString.end(),
+                   cmsysString_isdigit)) {
     status.SetError(cmStrCat("given a non-integer ", key, '.'));
     return false;
   }
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 5ce0851..4a8c3d2 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -5,7 +5,6 @@
 #include <algorithm>
 #include <array>
 #include <cassert>
-#include <cctype>
 #include <cstdio>
 #include <cstdlib>
 #include <initializer_list>
@@ -23,6 +22,7 @@
 #include <cmext/string_view>
 
 #include "cmsys/RegularExpression.hxx"
+#include "cmsys/String.h"
 
 #include "cmAlgorithms.h"
 #include "cmCMakePath.h"
@@ -2556,7 +2556,8 @@
 void cmLocalGenerator::AppendFlags(std::string& flags,
                                    std::string const& newFlags) const
 {
-  bool allSpaces = std::all_of(newFlags.begin(), newFlags.end(), cmIsSpace);
+  bool allSpaces =
+    std::all_of(newFlags.begin(), newFlags.end(), cmsysString_isspace);
 
   if (!newFlags.empty() && !allSpaces) {
     if (!flags.empty()) {
@@ -3489,8 +3490,7 @@
     }
   } else if (linkerType != "DEFAULT"_s) {
     auto isCMakeLinkerType = [](std::string const& type) -> bool {
-      return std::all_of(type.cbegin(), type.cend(),
-                         [](char c) { return std::isupper(c); });
+      return std::all_of(type.cbegin(), type.cend(), cmsysString_isupper);
     };
     if (isCMakeLinkerType(linkerType)) {
       this->IssueMessage(
diff --git a/Source/cmLocale.h b/Source/cmLocale.h
deleted file mode 100644
index b0d1065..0000000
--- a/Source/cmLocale.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file LICENSE.rst or https://cmake.org/licensing for details.  */
-#pragma once
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include <clocale>
-#include <string>
-
-class cmLocaleRAII
-{
-public:
-  cmLocaleRAII()
-    : OldLocale(setlocale(LC_CTYPE, nullptr))
-  {
-    setlocale(LC_CTYPE, "");
-  }
-
-  ~cmLocaleRAII() { setlocale(LC_CTYPE, this->OldLocale.c_str()); }
-
-  cmLocaleRAII(cmLocaleRAII const&) = delete;
-  cmLocaleRAII& operator=(cmLocaleRAII const&) = delete;
-
-private:
-  std::string OldLocale;
-};
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index a78fc1e..6ff3489 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -6,7 +6,6 @@
 
 #include <algorithm>
 #include <cassert>
-#include <cctype>
 #include <cstdio>
 #include <cstdlib>
 #include <cstring>
@@ -28,6 +27,7 @@
 
 #include "cmsys/FStream.hxx"
 #include "cmsys/RegularExpression.hxx"
+#include "cmsys/String.h"
 
 #include "cmCustomCommand.h"
 #include "cmCustomCommandLines.h"
@@ -1299,8 +1299,8 @@
   for (std::string::size_type lpos = dflags.find(flag, 0);
        lpos != std::string::npos; lpos = dflags.find(flag, lpos)) {
     std::string::size_type rpos = lpos + len;
-    if ((lpos <= 0 || cmIsSpace(dflags[lpos - 1])) &&
-        (rpos >= dflags.size() || cmIsSpace(dflags[rpos]))) {
+    if ((lpos <= 0 || cmsysString_isspace(dflags[lpos - 1])) &&
+        (rpos >= dflags.size() || cmsysString_isspace(dflags[rpos]))) {
       dflags.erase(lpos, len);
     } else {
       ++lpos;
@@ -2705,7 +2705,7 @@
             last = next + 1;
           } else if (nextc == ';' && openstack.empty()) {
             // Handled in ExpandListArgument; pass the backslash literally.
-          } else if (isalnum(nextc) || nextc == '\0') {
+          } else if (cmsysString_isalnum(nextc) || nextc == '\0') {
             errorstr += "Invalid character escape '\\";
             if (nextc) {
               errorstr += nextc;
@@ -2773,8 +2773,8 @@
         CM_FALLTHROUGH;
       default: {
         if (!openstack.empty() &&
-            !(isalnum(inc) || inc == '_' || inc == '/' || inc == '.' ||
-              inc == '+' || inc == '-')) {
+            !(cmsysString_isalnum(inc) || inc == '_' || inc == '/' ||
+              inc == '.' || inc == '+' || inc == '-')) {
           errorstr += cmStrCat("Invalid character ('", inc);
           result.append(last, in - last);
           errorstr += cmStrCat("') in a variable name: '",
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index d833bbb..653466b 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -1228,6 +1228,23 @@
 
     this->WriteTargetDependInfo(language, config);
 
+    // Non-imported synthetic targets read module info from their native target
+    // Add as implicit dependency.
+    if (this->GeneratorTarget->IsSynthetic()) {
+      if (cmGeneratorTarget const* native_gt =
+            this->LocalGenerator->FindGeneratorTargetToUse(
+              this->GeneratorTarget->Target->GetTemplateName())) {
+        if (!native_gt->IsImported()) {
+          std::string native_dir = native_gt->GetSupportDirectory();
+          if (this->GetGlobalGenerator()->IsMultiConfig()) {
+            native_dir = cmStrCat(native_dir, '/', config);
+          }
+          build.ImplicitDeps.emplace_back(this->ConvertToNinjaPath(
+            cmStrCat(native_dir, '/', language, "Modules.json")));
+        }
+      }
+    }
+
     auto const linked_directories =
       this->GetLinkedTargetDirectories(language, config);
     for (std::string const& l : linked_directories.Direct) {
@@ -2155,6 +2172,22 @@
     tdi_forward_modules_from_target_dirs.append(l);
   }
 
+  // Record the native target support directory for non-imported synthetic
+  // targets
+  if (this->GeneratorTarget->IsSynthetic()) {
+    if (cmGeneratorTarget* nativeGT =
+          this->LocalGenerator->FindGeneratorTargetToUse(
+            this->GeneratorTarget->Target->GetTemplateName())) {
+      if (!nativeGT->IsImported()) {
+        std::string nativeDir = nativeGT->GetSupportDirectory();
+        if (this->GetGlobalGenerator()->IsMultiConfig()) {
+          nativeDir = cmStrCat(nativeDir, '/', config);
+        }
+        tdi["native-target-dir"] = nativeDir;
+      }
+    }
+  }
+
   cmDyndepGeneratorCallbacks cb;
   cb.ObjectFilePath = [this](cmSourceFile const* sf, std::string const& cnf) {
     return this->GetObjectFilePath(sf, cnf);
diff --git a/Source/cmOutputConverter.cxx b/Source/cmOutputConverter.cxx
index ddae68c..c72dbe4 100644
--- a/Source/cmOutputConverter.cxx
+++ b/Source/cmOutputConverter.cxx
@@ -4,7 +4,6 @@
 
 #include <algorithm>
 #include <cassert>
-#include <cctype>
 #include <set>
 #include <vector>
 
@@ -13,6 +12,8 @@
 #  include <utility>
 #endif
 
+#include "cmsys/String.h"
+
 #include "cmList.h"
 #include "cmState.h"
 #include "cmStateDirectory.h"
@@ -425,7 +426,7 @@
 
 static bool Shell_CharIsMakeVariableName(char c)
 {
-  return c && (c == '_' || isalpha((static_cast<int>(c))));
+  return c && (c == '_' || cmsysString_isalpha((static_cast<int>(c))));
 }
 
 bool cmOutputConverter::Shell_CharNeedsQuotes(char c, int flags)
diff --git a/Source/cmPackageInfoReader.cxx b/Source/cmPackageInfoReader.cxx
index 6817938..9bab7a7 100644
--- a/Source/cmPackageInfoReader.cxx
+++ b/Source/cmPackageInfoReader.cxx
@@ -250,6 +250,21 @@
   }
 }
 
+void AppendImportProperty(cmMakefile* makefile, cmTarget* target,
+                          cm::string_view property,
+                          cm::string_view configuration,
+                          std::string const& value)
+{
+  if (!configuration.empty()) {
+    std::string const fullprop = cmStrCat(
+      "IMPORTED_", property, '_', cmSystemTools::UpperCase(configuration));
+    target->AppendProperty(fullprop, value, makefile->GetBacktrace());
+  } else {
+    std::string const fullprop = cmStrCat("IMPORTED_", property);
+    target->AppendProperty(fullprop, value, makefile->GetBacktrace());
+  }
+}
+
 template <typename Transform>
 void AppendLanguageProperties(cmMakefile* makefile, cmTarget* target,
                               cm::string_view property,
@@ -781,6 +796,15 @@
     AppendProperty(makefile, target, "LINK_LIBRARIES"_s, configuration, lib);
   }
 
+  for (std::string const& dep : ReadList(data, "dyld_requires")) {
+    AppendImportProperty(makefile, target, "LINK_DEPENDENT_LIBRARIES"_s,
+                         configuration, NormalizeTargetName(dep, package));
+  }
+
+  for (std::string const& lib : ReadList(data, "link_libraries")) {
+    AppendProperty(makefile, target, "LINK_LIBRARIES"_s, configuration, lib);
+  }
+
   // TODO: Handle non-configuration modules
   // once IMPORTED_CXX_MODULES supports it
   if (!configuration.empty()) {
diff --git a/Source/cmPathResolver.cxx b/Source/cmPathResolver.cxx
index 67d63b9..f384dbf 100644
--- a/Source/cmPathResolver.cxx
+++ b/Source/cmPathResolver.cxx
@@ -13,9 +13,9 @@
 #include <cmext/string_view>
 
 #ifdef _WIN32
-#  include <cctype>
-
 #  include <windows.h>
+
+#  include <cmsys/String.h>
 #endif
 
 #define MAX_SYMBOLIC_LINKS 32
@@ -95,7 +95,7 @@
 Root ClassifyRoot(cm::string_view p)
 {
 #ifdef _WIN32
-  if (p.size() >= 2 && std::isalpha(p[0]) && p[1] == ':') {
+  if (p.size() >= 2 && cmsysString_isalpha(p[0]) && p[1] == ':') {
     return Root::Drive;
   }
   if (p.size() >= 3 && p[0] == '/' && p[1] == '/' && p[2] != '/') {
@@ -171,8 +171,7 @@
   std::string d = this->OS.GetWorkingDirectoryOnDrive(letter);
   std::replace(d.begin(), d.end(), '\\', '/');
   if (d.size() >= 3 &&
-      std::toupper(static_cast<unsigned char>(d[0])) ==
-        std::toupper(static_cast<unsigned char>(letter)) &&
+      cmsysString_toupper(d[0]) == cmsysString_toupper(letter) &&
       d[1] == ':' && d[2] == '/') {
     d[0] = letter;
     d.push_back('/');
@@ -182,8 +181,7 @@
   // Use the current working directory if the drive matches.
   d = this->OS.GetWorkingDirectory();
   if (d.size() >= 3 &&
-      std::toupper(static_cast<unsigned char>(d[0])) ==
-        std::toupper(static_cast<unsigned char>(letter)) &&
+      cmsysString_toupper(d[0]) == cmsysString_toupper(letter) &&
       d[1] == ':' && d[2] == '/') {
     d[0] = letter;
     d.push_back('/');
@@ -284,7 +282,7 @@
 
     if (Policy::ActualCase == Options::ActualCase::Yes) {
       // Normalize the drive letter to upper-case.
-      P[0] = static_cast<char>(std::toupper(static_cast<unsigned char>(P[0])));
+      P[0] = static_cast<char>(cmsysString_toupper(P[0]));
     }
 
     // The root is a drive letter.  The root '/' immediately follows.
diff --git a/Source/cmPkgConfigResolver.cxx b/Source/cmPkgConfigResolver.cxx
index 8be5f34..54598c8 100644
--- a/Source/cmPkgConfigResolver.cxx
+++ b/Source/cmPkgConfigResolver.cxx
@@ -4,7 +4,6 @@
 #include "cmPkgConfigResolver.h"
 
 #include <algorithm>
-#include <cctype>
 #include <cstring>
 #include <iterator>
 #include <string>
@@ -15,6 +14,8 @@
 #include <cm/optional>
 #include <cm/string_view>
 
+#include "cmsys/String.h"
+
 #include "cmPkgConfigParser.h"
 #include "cmStringAlgorithms.h"
 
@@ -24,7 +25,7 @@
 {
   if (!str.empty()) {
     auto it = str.end() - 1;
-    for (; std::isspace(*it); --it) {
+    for (; cmsysString_isspace(*it); --it) {
       if (it == str.begin()) {
         str.clear();
         return;
@@ -45,11 +46,11 @@
   auto begin = str.begin() + size;
   auto cur = str.end() - 1;
 
-  while (cur != begin && std::isspace(*cur)) {
+  while (cur != begin && cmsysString_isspace(*cur)) {
     --cur;
   }
 
-  if (std::isspace(*cur)) {
+  if (cmsysString_isspace(*cur)) {
     return {};
   }
 
@@ -59,7 +60,8 @@
 cm::string_view TrimFlag(cm::string_view flag)
 {
   std::size_t trim_size = 2;
-  for (auto c = flag.rbegin(); c != flag.rend() && std::isspace(*c); ++c) {
+  for (auto c = flag.rbegin(); c != flag.rend() && cmsysString_isspace(*c);
+       ++c) {
     ++trim_size;
   }
   return { flag.data() + 2, flag.size() - trim_size };
@@ -406,7 +408,7 @@
   std::vector<cm::string_view> result;
 
   auto it = flagline.begin();
-  while (it != flagline.end() && std::isspace(*it)) {
+  while (it != flagline.end() && cmsysString_isspace(*it)) {
     ++it;
   }
 
@@ -414,11 +416,11 @@
     char const* start = &(*it);
     std::size_t len = 0;
 
-    for (; it != flagline.end() && !std::isspace(*it); ++it) {
+    for (; it != flagline.end() && !cmsysString_isspace(*it); ++it) {
       ++len;
     }
 
-    for (; it != flagline.end() && std::isspace(*it); ++it) {
+    for (; it != flagline.end() && cmsysString_isspace(*it); ++it) {
       ++len;
     }
 
@@ -665,12 +667,12 @@
       return result;
     }
 
-    if (!std::isspace(*cur)) {
+    if (!cmsysString_isspace(*cur)) {
       break;
     }
   }
 
-  for (; cur != end && !std::isspace(*cur) && *cur != ','; ++cur) {
+  for (; cur != end && !cmsysString_isspace(*cur) && *cur != ','; ++cur) {
     result.Version += *cur;
   }
 
@@ -687,7 +689,7 @@
   auto end = deps.end();
 
   while (cur != end) {
-    while ((std::isspace(*cur) || *cur == ',')) {
+    while ((cmsysString_isspace(*cur) || *cur == ',')) {
       if (++cur == end) {
         return result;
       }
@@ -696,7 +698,7 @@
     result.emplace_back();
     auto& dep = result.back();
 
-    while (!std::isspace(*cur) && *cur != ',') {
+    while (!cmsysString_isspace(*cur) && *cur != ',') {
       dep.Name += *cur;
       if (++cur == end) {
         return result;
@@ -713,7 +715,7 @@
           return true;
         }
 
-        if (!std::isspace(*cur)) {
+        if (!cmsysString_isspace(*cur)) {
           return false;
         }
       }
@@ -769,11 +771,11 @@
   auto b_end = provided.end();
 
   while (a_cur != a_end && b_cur != b_end) {
-    while (a_cur != a_end && !std::isalnum(*a_cur) && *a_cur != '~') {
+    while (a_cur != a_end && !cmsysString_isalnum(*a_cur) && *a_cur != '~') {
       ++a_cur;
     }
 
-    while (b_cur != b_end && !std::isalnum(*b_cur) && *b_cur != '~') {
+    while (b_cur != b_end && !cmsysString_isalnum(*b_cur) && *b_cur != '~') {
       ++b_cur;
     }
 
@@ -799,23 +801,23 @@
     auto b_seg = b_cur;
     bool is_num;
 
-    if (std::isdigit(*a_cur)) {
+    if (cmsysString_isdigit(*a_cur)) {
       is_num = true;
-      while (a_cur != a_end && std::isdigit(*a_cur)) {
+      while (a_cur != a_end && cmsysString_isdigit(*a_cur)) {
         ++a_cur;
       }
 
-      while (b_cur != b_end && std::isdigit(*b_cur)) {
+      while (b_cur != b_end && cmsysString_isdigit(*b_cur)) {
         ++b_cur;
       }
 
     } else {
       is_num = false;
-      while (a_cur != a_end && std::isalpha(*a_cur)) {
+      while (a_cur != a_end && cmsysString_isalpha(*a_cur)) {
         ++a_cur;
       }
 
-      while (b_cur != b_end && std::isalpha(*b_cur)) {
+      while (b_cur != b_end && cmsysString_isalpha(*b_cur)) {
         ++b_cur;
       }
     }
diff --git a/Source/cmPlaceholderExpander.cxx b/Source/cmPlaceholderExpander.cxx
index f5dc544..aea427b 100644
--- a/Source/cmPlaceholderExpander.cxx
+++ b/Source/cmPlaceholderExpander.cxx
@@ -2,7 +2,7 @@
    file LICENSE.rst or https://cmake.org/licensing for details.  */
 #include "cmPlaceholderExpander.h"
 
-#include <cctype>
+#include "cmsys/String.h"
 
 std::string& cmPlaceholderExpander::ExpandVariables(std::string& s)
 {
@@ -23,7 +23,7 @@
     char c = s[start + 1];
     // if the next char after the < is not A-Za-z then
     // skip it and try to find the next < in the string
-    if (!isalpha(c)) {
+    if (!cmsysString_isalpha(c)) {
       start = s.find('<', start + 1);
     } else {
       // extract the var
diff --git a/Source/cmPolicies.cxx b/Source/cmPolicies.cxx
index 4583863..337f220 100644
--- a/Source/cmPolicies.cxx
+++ b/Source/cmPolicies.cxx
@@ -3,12 +3,13 @@
 #include "cmPolicies.h"
 
 #include <cassert>
-#include <cctype>
 #include <cstdio>
 #include <cstring>
 #include <sstream>
 #include <vector>
 
+#include "cmsys/String.h"
+
 #include "cmListFileCache.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
@@ -32,7 +33,7 @@
     return true;
   }
   for (int i = 3; i < 7; ++i) {
-    if (!isdigit(*(input + i))) {
+    if (!cmsysString_isdigit(*(input + i))) {
       return false;
     }
   }
diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx
index d00cae1..8551132 100644
--- a/Source/cmProjectCommand.cxx
+++ b/Source/cmProjectCommand.cxx
@@ -17,7 +17,6 @@
 #include "cmArgumentParser.h"
 #include "cmArgumentParserTypes.h"
 #include "cmExecutionStatus.h"
-#include "cmExperimental.h"
 #include "cmList.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
@@ -68,24 +67,18 @@
   parser.BindKeywordMissingValue(missingValueKeywords)
     .BindParsedKeywords(parsedKeywords)
     .Bind("VERSION"_s, prArgs.Version)
+    .Bind("COMPAT_VERSION"_s, prArgs.CompatVersion)
+    .Bind("SPDX_LICENSE"_s, prArgs.License)
     .Bind("DESCRIPTION"_s, prArgs.Description)
     .Bind("HOMEPAGE_URL"_s, prArgs.HomepageURL)
     .Bind("LANGUAGES"_s, prArgs.Languages);
 
-  cmMakefile& mf = status.GetMakefile();
-  bool enablePackageInfo = cmExperimental::HasSupportEnabled(
-    mf, cmExperimental::Feature::ExportPackageInfo);
-
-  if (enablePackageInfo) {
-    parser.Bind("COMPAT_VERSION"_s, prArgs.CompatVersion);
-    parser.Bind("SPDX_LICENSE"_s, prArgs.License);
-  }
-
   if (args.empty()) {
     status.SetError("PROJECT called with incorrect number of arguments");
     return false;
   }
 
+  cmMakefile& mf = status.GetMakefile();
   std::string const& projectName = args[0];
   if (parser.HasKeyword(projectName)) {
     mf.IssueMessage(
diff --git a/Source/cmRST.cxx b/Source/cmRST.cxx
index 51245d6..e490370 100644
--- a/Source/cmRST.cxx
+++ b/Source/cmRST.cxx
@@ -8,6 +8,7 @@
 #include <utility>
 
 #include "cmsys/FStream.hxx"
+#include "cmsys/String.h"
 
 #include "cmAlgorithms.h"
 #include "cmRange.h"
@@ -158,7 +159,7 @@
   // A line starting in .. is an explicit markup start.
   if (line == ".." ||
       (line.size() >= 3 && line[0] == '.' && line[1] == '.' &&
-       cmIsSpace(line[2]))) {
+       cmsysString_isspace(line[2]))) {
     this->Reset();
     this->MarkupType =
       (line.find_first_not_of(" \t", 2) == std::string::npos ? Markup::Empty
@@ -218,7 +219,7 @@
   }
   // Indented lines following an explicit markup start are explicit markup.
   else if (this->MarkupType != Markup::None &&
-           (line.empty() || cmIsSpace(line[0]))) {
+           (line.empty() || cmsysString_isspace(line[0]))) {
     this->MarkupType = Markup::Normal;
     // Record markup lines if the start line was recorded.
     if (!this->MarkupLines.empty()) {
diff --git a/Source/cmSbomArguments.cxx b/Source/cmSbomArguments.cxx
index b939448..76322ab 100644
--- a/Source/cmSbomArguments.cxx
+++ b/Source/cmSbomArguments.cxx
@@ -3,10 +3,11 @@
 #include "cmSbomArguments.h"
 
 #include <algorithm>
-#include <cctype>
 
 #include <cm/string_view>
 
+#include "cmsys/String.h"
+
 #include "cmExecutionStatus.h"
 #include "cmGeneratorExpression.h"
 #include "cmStringAlgorithms.h"
@@ -99,6 +100,6 @@
   std::string const pkgNameOnDisk = this->GetPackageDirName();
   std::string format = GetSbomFileExtension(this->GetFormat());
   std::transform(format.begin(), format.end(), format.begin(),
-                 [](unsigned char c) { return std::tolower(c); });
+                 cmsysString_tolower);
   return cmStrCat(pkgNameOnDisk, format);
 }
diff --git a/Source/cmScanDepFormat.cxx b/Source/cmScanDepFormat.cxx
index bd38273..0016544 100644
--- a/Source/cmScanDepFormat.cxx
+++ b/Source/cmScanDepFormat.cxx
@@ -3,7 +3,6 @@
 
 #include "cmScanDepFormat.h"
 
-#include <cctype>
 #include <cstdio>
 #include <utility>
 
@@ -16,6 +15,7 @@
 #include <cm3p/json/writer.h>
 
 #include "cmsys/FStream.hxx"
+#include "cmsys/String.h"
 
 #include "cmGeneratedFileStream.h"
 #include "cmStringAlgorithms.h"
@@ -38,7 +38,7 @@
   data.reserve(path.size());
 
   for (auto const& byte : path) {
-    if (std::iscntrl(byte)) {
+    if (cmsysString_iscntrl(byte)) {
       // Control characters.
       data.append("\\u");
       char buf[5];
diff --git a/Source/cmStdIoInit.cxx b/Source/cmStdIoInit.cxx
index 49f3187..0d7a3d0 100644
--- a/Source/cmStdIoInit.cxx
+++ b/Source/cmStdIoInit.cxx
@@ -3,6 +3,7 @@
 #include "cmStdIoInit.h"
 
 #include <cerrno>
+#include <clocale>
 #include <cstdio>
 #include <cstdlib>
 #include <iostream>
@@ -106,14 +107,19 @@
   static Globals& Get();
 };
 
-#ifdef _WIN32
 Globals::Globals()
 {
+#ifdef _WIN32
+  // On Windows, setlocale offers a ".<code-page>" syntax to select the
+  // user's locale with a specific character set.  We always use UTF-8.
+  std::setlocale(LC_CTYPE, ".UTF-8");
+
   SetConsoleCtrlHandler(CtrlHandler, TRUE);
-}
 #else
-Globals::Globals() = default;
+  // On non-Windows platforms, we select the user's locale.
+  std::setlocale(LC_CTYPE, "");
 #endif
+}
 
 Globals& Globals::Get()
 {
diff --git a/Source/cmStringAlgorithms.cxx b/Source/cmStringAlgorithms.cxx
index d46019b..e13c226 100644
--- a/Source/cmStringAlgorithms.cxx
+++ b/Source/cmStringAlgorithms.cxx
@@ -8,15 +8,17 @@
 #include <cstdio>
 #include <cstdlib>
 
+#include "cmsys/String.h"
+
 bool cmStrCaseEq(cm::string_view s1, cm::string_view s2)
 {
   if (s1.size() != s2.size()) {
     return false;
   }
 
-  return std::equal(
-    s1.begin(), s1.end(), s2.begin(),
-    [](unsigned char a, unsigned char b) { return tolower(a) == tolower(b); });
+  return std::equal(s1.begin(), s1.end(), s2.begin(), [](char a, char b) {
+    return cmsysString_tolower(a) == cmsysString_tolower(b);
+  });
 }
 
 std::string cmTrimWhitespace(cm::string_view str)
@@ -25,7 +27,7 @@
   // because the qualification of `auto` is platform-dependent.
   // NOLINTNEXTLINE(readability-qualified-auto)
   auto start = str.begin();
-  while (start != str.end() && cmIsSpace(*start)) {
+  while (start != str.end() && cmsysString_isspace(*start)) {
     ++start;
   }
   if (start == str.end()) {
@@ -33,7 +35,7 @@
   }
   // NOLINTNEXTLINE(readability-qualified-auto)
   auto stop = str.end() - 1;
-  while (cmIsSpace(*stop)) {
+  while (cmsysString_isspace(*stop)) {
     --stop;
   }
   return std::string(start, stop + 1);
@@ -44,14 +46,14 @@
   std::string::size_type const l = str.size();
 
   std::string::size_type s = 0;
-  while (s < l && cmIsSpace(str[s])) {
+  while (s < l && cmsysString_isspace(str[s])) {
     ++s;
   }
   if (s == l) {
     return cm::string_view{};
   }
   std::string::size_type e = l - 1;
-  while (cmIsSpace(str[e])) {
+  while (cmsysString_isspace(str[e])) {
     --e;
   }
   return str.substr(s, e + 1 - s);
@@ -196,7 +198,7 @@
 {
   errno = 0;
   char* endp;
-  while (cmIsSpace(*str)) {
+  while (cmsysString_isspace(*str)) {
     ++str;
   }
   if (*str == '-') {
@@ -228,7 +230,7 @@
 {
   errno = 0;
   char* endp;
-  while (cmIsSpace(*str)) {
+  while (cmsysString_isspace(*str)) {
     ++str;
   }
   if (*str == '-') {
diff --git a/Source/cmStringAlgorithms.h b/Source/cmStringAlgorithms.h
index d847ece..966091a 100644
--- a/Source/cmStringAlgorithms.h
+++ b/Source/cmStringAlgorithms.h
@@ -4,7 +4,6 @@
 
 #include "cmConfigure.h" // IWYU pragma: keep
 
-#include <cctype>
 #include <cstring>
 #include <initializer_list>
 #include <iterator>
@@ -50,15 +49,6 @@
  */
 bool cmStrCaseEq(cm::string_view a, cm::string_view b);
 
-/** Returns true if the character @a ch is a whitespace character.  **/
-inline bool cmIsSpace(char ch)
-{
-  // isspace takes 'int' but documents that the value must be representable
-  // by 'unsigned char', or be EOF.  Cast to 'unsigned char' to avoid sign
-  // extension while converting to 'int'.
-  return std::isspace(static_cast<unsigned char>(ch));
-}
-
 /** Returns a string that has whitespace removed from the start and the end. */
 std::string cmTrimWhitespace(cm::string_view str);
 
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 1d15b55..2329449 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -58,7 +58,6 @@
 #  include <cm3p/archive_entry.h>
 
 #  include "cmArchiveWrite.h"
-#  include "cmLocale.h"
 #  ifndef __LA_INT64_T
 #    define __LA_INT64_T la_int64_t
 #  endif
@@ -77,7 +76,6 @@
 
 #include <algorithm>
 #include <cassert>
-#include <cctype>
 #include <cerrno>
 #include <cstdint>
 #include <cstdio>
@@ -104,6 +102,7 @@
 #endif
 #include "cmsys/FStream.hxx"
 #include "cmsys/RegularExpression.hxx"
+#include "cmsys/String.h"
 #include "cmsys/System.h"
 
 #if defined(_WIN32)
@@ -574,7 +573,7 @@
     } else {
       arg.append(backslashes, '\\');
       backslashes = 0;
-      if (cmIsSpace(*c)) {
+      if (cmsysString_isspace(*c)) {
         if (in_quotes) {
           arg.append(1, *c);
         } else if (in_argument) {
@@ -733,7 +732,7 @@
   char const* c = command.c_str();
 
   // Skip leading whitespace.
-  while (cmIsSpace(*c)) {
+  while (cmsysString_isspace(*c)) {
     ++c;
   }
 
@@ -763,7 +762,7 @@
       in_double = true;
     } else if (*c == '\'') {
       in_single = true;
-    } else if (cmIsSpace(*c)) {
+    } else if (cmsysString_isspace(*c)) {
       break;
     } else {
       program += *c;
@@ -1340,7 +1339,7 @@
   }
   // Normalize to upper-case drive letter as cm::PathResolver does.
   if (resolved_path.size() > 1 && resolved_path[1] == ':') {
-    resolved_path[0] = toupper(static_cast<unsigned char>(resolved_path[0]));
+    resolved_path[0] = cmsysString_toupper(resolved_path[0]);
   }
   return resolved_path;
 #else
@@ -1362,12 +1361,10 @@
   // limitation to otherwise preserve susbt drives.
   if (resolved_path.size() >= 2 && resolved_path[1] == ':' &&
       path.size() >= 2 && path[1] == ':' &&
-      toupper(static_cast<unsigned char>(resolved_path[0])) !=
-        toupper(static_cast<unsigned char>(path[0]))) {
+      cmsysString_toupper(resolved_path[0]) != cmsysString_toupper(path[0])) {
     // FIXME: Add thread_local or mutex if we use threads.
     static std::map<char, std::string> substMap;
-    char const drive =
-      static_cast<char>(toupper(static_cast<unsigned char>(path[0])));
+    char const drive = static_cast<char>(cmsysString_toupper(path[0]));
     std::string maybe_subst = cmStrCat(drive, ":/");
     auto smi = substMap.find(drive);
     if (smi == substMap.end()) {
@@ -2626,8 +2623,6 @@
                  cmSystemTools::cmTarExtractTimestamps extractTimestamps,
                  bool extract)
 {
-  cmLocaleRAII localeRAII;
-  static_cast<void>(localeRAII);
   struct archive* a = archive_read_new();
   struct archive* ext = archive_write_disk_new();
   if (extract) {
@@ -3866,7 +3861,7 @@
 static size_t cm_strverscmp_find_digits_begin(char const* s, size_t i)
 {
   /* Step back until we are not preceded by a digit.  */
-  while (i > 0 && isdigit(s[i - 1])) {
+  while (i > 0 && cmsysString_isdigit(s[i - 1])) {
     --i;
   }
   return i;
@@ -3875,7 +3870,7 @@
 static size_t cm_strverscmp_find_digits_end(char const* s, size_t i)
 {
   /* Step forward over digits.  */
-  while (isdigit(s[i])) {
+  while (cmsysString_isdigit(s[i])) {
     ++i;
   }
   return i;
@@ -3885,7 +3880,7 @@
 {
   size_t i = b;
   /* Step forward over zeros that are followed by another digit.  */
-  while (s[i] == '0' && isdigit(s[i + 1])) {
+  while (s[i] == '0' && cmsysString_isdigit(s[i + 1])) {
     ++i;
   }
   return i - b;
@@ -3897,7 +3892,8 @@
   if (lhs[i] != rhs[i]) {
     /* The strings differ starting at 'i'.  Check for a digit sequence.  */
     size_t const b = cm_strverscmp_find_digits_begin(lhs, i);
-    if (b != i || (isdigit(lhs[i]) && isdigit(rhs[i]))) {
+    if (b != i ||
+        (cmsysString_isdigit(lhs[i]) && cmsysString_isdigit(rhs[i]))) {
       /* A digit sequence starts at 'b', preceding or at 'i'.  */
 
       /* Look for leading zeros, implying a leading decimal point.  */
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 296adf5..fe713a2 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -1721,37 +1721,52 @@
   assert(!this->IsNormal());
   // Imported targets cannot be the target of a copy.
   assert(!this->IsImported());
-  // Only imported targets can be the source of a copy.
-  assert(tgt->IsImported());
+
+  // Only imported or normal targets can be the source of a copy.
+  assert(tgt->IsImported() || tgt->IsNormal());
 
   this->impl->PolicyMap = tgt->impl->PolicyMap;
   this->impl->TemplateTarget = tgt;
 }
 
-void cmTarget::CopyImportedCxxModulesEntries(cmTarget const* tgt)
+void cmTarget::CopyCxxModulesEntries(cmTarget const* tgt)
 {
   // Normal targets cannot be the target of a copy.
   assert(!this->IsNormal());
   // Imported targets cannot be the target of a copy.
   assert(!this->IsImported());
-  // Only imported targets can be the source of a copy.
-  assert(tgt->IsImported());
+  // Only imported or normal targets can be the source of a copy.
+  assert(tgt->IsImported() || tgt->IsNormal());
 
   this->impl->IncludeDirectories.Entries.clear();
-  this->impl->IncludeDirectories.CopyFromEntries(
-    cmMakeRange(tgt->impl->ImportedCxxModulesIncludeDirectories.Entries));
   this->impl->CompileDefinitions.Entries.clear();
-  this->impl->CompileDefinitions.CopyFromEntries(
-    cmMakeRange(tgt->impl->ImportedCxxModulesCompileDefinitions.Entries));
   this->impl->CompileFeatures.Entries.clear();
-  this->impl->CompileFeatures.CopyFromEntries(
-    cmMakeRange(tgt->impl->ImportedCxxModulesCompileFeatures.Entries));
   this->impl->CompileOptions.Entries.clear();
-  this->impl->CompileOptions.CopyFromEntries(
-    cmMakeRange(tgt->impl->ImportedCxxModulesCompileOptions.Entries));
   this->impl->LinkLibraries.Entries.clear();
-  this->impl->LinkLibraries.CopyFromEntries(
-    cmMakeRange(tgt->impl->ImportedCxxModulesLinkLibraries.Entries));
+
+  if (tgt->IsImported()) {
+    this->impl->IncludeDirectories.CopyFromEntries(
+      cmMakeRange(tgt->impl->ImportedCxxModulesIncludeDirectories.Entries));
+    this->impl->CompileDefinitions.CopyFromEntries(
+      cmMakeRange(tgt->impl->ImportedCxxModulesCompileDefinitions.Entries));
+    this->impl->CompileFeatures.CopyFromEntries(
+      cmMakeRange(tgt->impl->ImportedCxxModulesCompileFeatures.Entries));
+    this->impl->CompileOptions.CopyFromEntries(
+      cmMakeRange(tgt->impl->ImportedCxxModulesCompileOptions.Entries));
+    this->impl->LinkLibraries.CopyFromEntries(
+      cmMakeRange(tgt->impl->ImportedCxxModulesLinkLibraries.Entries));
+  } else {
+    this->impl->IncludeDirectories.CopyFromEntries(
+      cmMakeRange(tgt->impl->IncludeDirectories.Entries));
+    this->impl->CompileDefinitions.CopyFromEntries(
+      cmMakeRange(tgt->impl->CompileDefinitions.Entries));
+    this->impl->CompileFeatures.CopyFromEntries(
+      cmMakeRange(tgt->impl->CompileFeatures.Entries));
+    this->impl->CompileOptions.CopyFromEntries(
+      cmMakeRange(tgt->impl->CompileOptions.Entries));
+    this->impl->LinkLibraries.CopyFromEntries(
+      cmMakeRange(tgt->impl->LinkLibraries.Entries));
+  }
 
   // Copy the C++ module fileset entries from `tgt`'s `INTERFACE` to this
   // target's `PRIVATE`.
@@ -1760,14 +1775,14 @@
     tgt->impl->CxxModulesFileSets.InterfaceEntries.Entries;
 }
 
-void cmTarget::CopyImportedCxxModulesProperties(cmTarget const* tgt)
+void cmTarget::CopyCxxModulesProperties(cmTarget const* tgt)
 {
   // Normal targets cannot be the target of a copy.
   assert(!this->IsNormal());
   // Imported targets cannot be the target of a copy.
   assert(!this->IsImported());
-  // Only imported targets can be the source of a copy.
-  assert(tgt->IsImported());
+  // Only imported or normal targets can be the source of a copy.
+  assert(tgt->IsImported() || tgt->IsNormal());
 
   // The list of properties that are relevant here include:
   // - compilation-specific properties for any language or platform
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index b275e47..ad3a9c0 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -321,8 +321,8 @@
   cmBTStringRange GetLinkInterfaceDirectExcludeEntries() const;
 
   void CopyPolicyStatuses(cmTarget const* tgt);
-  void CopyImportedCxxModulesEntries(cmTarget const* tgt);
-  void CopyImportedCxxModulesProperties(cmTarget const* tgt);
+  void CopyCxxModulesEntries(cmTarget const* tgt);
+  void CopyCxxModulesProperties(cmTarget const* tgt);
 
   cmBTStringRange GetHeaderSetsEntries() const;
   cmBTStringRange GetCxxModuleSetsEntries() const;
diff --git a/Source/cmVSSetupHelper.cxx b/Source/cmVSSetupHelper.cxx
index 54b301b..342b4f7 100644
--- a/Source/cmVSSetupHelper.cxx
+++ b/Source/cmVSSetupHelper.cxx
@@ -54,6 +54,8 @@
 #endif
 
 namespace {
+const WCHAR* Win11SDKComponent =
+  L"Microsoft.VisualStudio.Component.Windows11SDK";
 const WCHAR* Win10SDKComponent =
   L"Microsoft.VisualStudio.Component.Windows10SDK";
 const WCHAR* Win81SDKComponent =
@@ -156,10 +158,9 @@
   std::wstring id = std::wstring(bstrId);
   std::wstring type = std::wstring(bstrType);
 
-  // Checks for any version of Win10 SDK. The version is appended at the end of
-  // the
-  // component name ex: Microsoft.VisualStudio.Component.Windows10SDK.10240
-  if (id.find(Win10SDKComponent) != std::wstring::npos &&
+  // Check for any version of Win10 or Win11 SDK.
+  // The component name may have a `.<version>` suffix.  Accept any.
+  if ((id.find(Win11SDKComponent) == 0 || id.find(Win10SDKComponent) == 0) &&
       type == ComponentType) {
     bWin10SDK = true;
     ret = true;
@@ -526,25 +527,25 @@
 
   unsigned int chosenIndex = 0;
   for (unsigned int i = 1; i < vecVSInstances.size(); i++) {
-    // If the current has Win10 SDK but not the chosen one, then choose the
-    // current VS instance
+    // If the current instance has Win10 SDK, but the chosen one does not,
+    // then choose the current VS instance.
     if (!vecVSInstances[chosenIndex].IsWin10SDKInstalled &&
         vecVSInstances[i].IsWin10SDKInstalled) {
       chosenIndex = i;
       continue;
     }
 
-    // If the chosen one has Win10 SDK but the current one is not, then look at
-    // the next VS instance even the current
-    // instance version may be higher
+    // If the chosen instance has Win10 SDK, but the current one does not,
+    // then look at the next VS instance even if the current instance version
+    // may be higher.
     if (vecVSInstances[chosenIndex].IsWin10SDKInstalled &&
         !vecVSInstances[i].IsWin10SDKInstalled) {
       continue;
     }
 
-    // If both chosen one and current one doesn't have Win10 SDK but the
-    // current one has Win8.1 SDK installed,
-    // then choose the current one
+    // If both chosen instance and current instance do not have Win10 SDK,
+    // but the current one has Win8.1 SDK installed, then choose the current
+    // one.
     if (!vecVSInstances[chosenIndex].IsWin10SDKInstalled &&
         !vecVSInstances[i].IsWin10SDKInstalled &&
         !vecVSInstances[chosenIndex].IsWin81SDKInstalled &&
diff --git a/Source/cmWindowsRegistry.cxx b/Source/cmWindowsRegistry.cxx
index 9d9de8c..ecce2f5 100644
--- a/Source/cmWindowsRegistry.cxx
+++ b/Source/cmWindowsRegistry.cxx
@@ -4,7 +4,6 @@
 
 #include "cmWindowsRegistry.h"
 
-#include <cctype>
 #include <cstddef>
 #include <type_traits>
 #include <unordered_map>
@@ -13,6 +12,7 @@
 #include <cmext/string_view>
 
 #include "cmsys/RegularExpression.hxx"
+#include "cmsys/String.h"
 
 #if defined(_WIN32) && !defined(__CYGWIN__)
 #  include <algorithm>
@@ -47,8 +47,8 @@
   cm::string_view::size_type ri = 0;
 
   do {
-    lc = std::tolower(static_cast<unsigned char>(l[li++]));
-    rc = std::tolower(static_cast<unsigned char>(r[ri++]));
+    lc = cmsysString_tolower(l[li++]);
+    rc = cmsysString_tolower(r[ri++]);
   } while (lc == rc && li < l.size() && ri < r.size());
 
   return lc == rc ? static_cast<int>(l.size() - r.size()) : lc - rc;
diff --git a/Source/cmXMLWriter.h b/Source/cmXMLWriter.h
index e15542d..bad1bc1 100644
--- a/Source/cmXMLWriter.h
+++ b/Source/cmXMLWriter.h
@@ -113,6 +113,11 @@
     return std::chrono::system_clock::to_time_t(value);
   }
 
+  static long long SafeContent(std::chrono::milliseconds value)
+  {
+    return value.count();
+  }
+
   template <typename T>
   static T SafeContent(T value)
   {
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index 42fe88a..35346af 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -5,7 +5,6 @@
 
 #include <algorithm>
 #include <cassert>
-#include <cctype>
 #include <climits>
 #include <cstring>
 #include <functional>
@@ -20,6 +19,8 @@
 
 #include <cm3p/uv.h>
 
+#include "cmsys/String.h"
+
 #include "cmBuildArgs.h"
 #include "cmBuildOptions.h"
 #include "cmCommandLineArgument.h"
@@ -500,8 +501,7 @@
   };
   auto resolvePackagesLambda = [&](std::string const& value) -> bool {
     std::string v = value;
-    std::transform(v.begin(), v.end(), v.begin(),
-                   [](unsigned char c) { return std::tolower(c); });
+    std::transform(v.begin(), v.end(), v.begin(), cmsysString_tolower);
     if (v == "on") {
       resolveMode = PackageResolveMode::Force;
     } else if (v == "only") {
diff --git a/Source/kwsys/CMakeLists.txt b/Source/kwsys/CMakeLists.txt
index 08494b9..68e122e 100644
--- a/Source/kwsys/CMakeLists.txt
+++ b/Source/kwsys/CMakeLists.txt
@@ -159,6 +159,7 @@
   set(KWSYS_USE_FStream 1)
   set(KWSYS_USE_Encoding 1)
   set(KWSYS_USE_Status 1)
+  set(KWSYS_USE_String 1)
 endif()
 if(KWSYS_USE_Glob)
   set(KWSYS_USE_Directory 1)
@@ -166,6 +167,7 @@
   set(KWSYS_USE_RegularExpression 1)
   set(KWSYS_USE_FStream 1)
   set(KWSYS_USE_Encoding 1)
+  set(KWSYS_USE_String 1)
 endif()
 if(KWSYS_USE_Process)
   set(KWSYS_USE_System 1)
@@ -179,6 +181,7 @@
 endif()
 if(KWSYS_USE_System)
   set(KWSYS_USE_Encoding 1)
+  set(KWSYS_USE_String 1)
 endif()
 if(KWSYS_USE_Directory)
   set(KWSYS_USE_Encoding 1)
@@ -913,6 +916,7 @@
     # C tests
     set(KWSYS_C_TESTS
       testEncode.c
+      testString.c
       )
     if(KWSYS_STANDALONE)
       set(KWSYS_C_TESTS ${KWSYS_C_TESTS} testFail.c)
diff --git a/Source/kwsys/EncodingCXX.cxx b/Source/kwsys/EncodingCXX.cxx
index 7bf4681..885a1f7 100644
--- a/Source/kwsys/EncodingCXX.cxx
+++ b/Source/kwsys/EncodingCXX.cxx
@@ -9,12 +9,14 @@
 #include "kwsysPrivate.h"
 #include KWSYS_HEADER(Encoding.hxx)
 #include KWSYS_HEADER(Encoding.h)
+#include KWSYS_HEADER(String.h)
 
 // Work-around CMake dependency scanning limitation.  This must
 // duplicate the above list of headers.
 #if 0
 #  include "Encoding.h.in"
 #  include "Encoding.hxx.in"
+#  include "String.h"
 #endif
 
 #include <cstdlib>
@@ -29,7 +31,6 @@
 #if defined(_WIN32)
 #  include <windows.h>
 
-#  include <ctype.h>
 #  include <shellapi.h>
 #endif
 
@@ -248,7 +249,7 @@
    * previous size workaround. */
   wfull_len = static_cast<DWORD>(wcslen(&wfull[0]));
 
-  if (wfull_len >= 2 && isalpha(wfull[0]) &&
+  if (wfull_len >= 2 && kwsysString_isalpha(wfull[0]) &&
       wfull[1] == L':') { /* C:\Foo\bar\FooBar.txt */
     return L"\\\\?\\" + std::wstring(&wfull[0]);
   } else if (wfull_len >= 2 && wfull[0] == L'\\' &&
@@ -259,7 +260,7 @@
           wfull[6] == L'C' &&
           wfull[7] == L'\\') { /* \\?\UNC\Foo\bar\FooBar.txt */
         return std::wstring(&wfull[0]);
-      } else if (wfull_len >= 6 && isalpha(wfull[4]) &&
+      } else if (wfull_len >= 6 && kwsysString_isalpha(wfull[4]) &&
                  wfull[5] == L':') { /* \\?\C:\Foo\bar\FooBar.txt */
         return std::wstring(&wfull[0]);
       } else if (wfull_len >= 5) { /* \\?\Foo\bar\FooBar.txt */
@@ -267,7 +268,7 @@
       }
     } else if (wfull_len >= 4 && wfull[2] == L'.' &&
                wfull[3] == L'\\') { /* Starts with \\.\ a device name */
-      if (wfull_len >= 6 && isalpha(wfull[4]) &&
+      if (wfull_len >= 6 && kwsysString_isalpha(wfull[4]) &&
           wfull[5] == L':') { /* \\.\C:\Foo\bar\FooBar.txt */
         return L"\\\\?\\" + std::wstring(&wfull[4]);
       } else if (wfull_len >=
diff --git a/Source/kwsys/Glob.cxx b/Source/kwsys/Glob.cxx
index 90970ea..3ac75f6 100644
--- a/Source/kwsys/Glob.cxx
+++ b/Source/kwsys/Glob.cxx
@@ -8,6 +8,7 @@
 #include KWSYS_HEADER(RegularExpression.hxx)
 #include KWSYS_HEADER(SystemTools.hxx)
 #include KWSYS_HEADER(Directory.hxx)
+#include KWSYS_HEADER(String.h)
 
 // Work-around CMake dependency scanning limitation.  This must
 // duplicate the above list of headers.
@@ -16,6 +17,7 @@
 #  include "Directory.hxx.in"
 #  include "Glob.hxx.in"
 #  include "RegularExpression.hxx.in"
+#  include "String.h.in"
 #  include "SystemTools.hxx.in"
 #endif
 
@@ -23,7 +25,6 @@
 #include <string>
 #include <vector>
 
-#include <cctype>
 #include <cstdio>
 #include <cstring>
 namespace KWSYS_NAMESPACE {
@@ -162,7 +163,7 @@
         // On case-insensitive systems file names are converted to lower
         // case before matching.
         if (!preserve_case) {
-          ch = tolower(static_cast<unsigned char>(ch));
+          ch = kwsysString_tolower(ch);
         }
       }
 #endif
diff --git a/Source/kwsys/ProcessUNIX.c b/Source/kwsys/ProcessUNIX.c
index 01dc039..8c22b4e 100644
--- a/Source/kwsys/ProcessUNIX.c
+++ b/Source/kwsys/ProcessUNIX.c
@@ -54,7 +54,6 @@
 #endif
 
 #include <assert.h>    /* assert */
-#include <ctype.h>     /* isspace */
 #include <dirent.h>    /* DIR, dirent */
 #include <errno.h>     /* errno */
 #include <fcntl.h>     /* fcntl */
diff --git a/Source/kwsys/String.c b/Source/kwsys/String.c
index 7fd159b..0ccf38d 100644
--- a/Source/kwsys/String.c
+++ b/Source/kwsys/String.c
@@ -17,84 +17,130 @@
 #    include "String.h.in"
 #  endif
 
-/* Select an implementation for strcasecmp.  */
-#  if defined(_MSC_VER)
-#    define KWSYS_STRING_USE_STRICMP
-#    include <string.h>
-#  elif defined(__GNUC__)
-#    define KWSYS_STRING_USE_STRCASECMP
-#    include <strings.h>
-#  else
-/* Table to convert upper case letters to lower case and leave all
-   other characters alone.  */
-static char kwsysString_strcasecmp_tolower[] = {
-  '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', '\010',
-  '\011', '\012', '\013', '\014', '\015', '\016', '\017', '\020', '\021',
-  '\022', '\023', '\024', '\025', '\026', '\027', '\030', '\031', '\032',
-  '\033', '\034', '\035', '\036', '\037', '\040', '\041', '\042', '\043',
-  '\044', '\045', '\046', '\047', '\050', '\051', '\052', '\053', '\054',
-  '\055', '\056', '\057', '\060', '\061', '\062', '\063', '\064', '\065',
-  '\066', '\067', '\070', '\071', '\072', '\073', '\074', '\075', '\076',
-  '\077', '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
-  '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', '\160',
-  '\161', '\162', '\163', '\164', '\165', '\166', '\167', '\170', '\171',
-  '\172', '\133', '\134', '\135', '\136', '\137', '\140', '\141', '\142',
-  '\143', '\144', '\145', '\146', '\147', '\150', '\151', '\152', '\153',
-  '\154', '\155', '\156', '\157', '\160', '\161', '\162', '\163', '\164',
-  '\165', '\166', '\167', '\170', '\171', '\172', '\173', '\174', '\175',
-  '\176', '\177', '\200', '\201', '\202', '\203', '\204', '\205', '\206',
-  '\207', '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
-  '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227', '\230',
-  '\231', '\232', '\233', '\234', '\235', '\236', '\237', '\240', '\241',
-  '\242', '\243', '\244', '\245', '\246', '\247', '\250', '\251', '\252',
-  '\253', '\254', '\255', '\256', '\257', '\260', '\261', '\262', '\263',
-  '\264', '\265', '\266', '\267', '\270', '\271', '\272', '\273', '\274',
-  '\275', '\276', '\277', '\300', '\301', '\302', '\303', '\304', '\305',
-  '\306', '\307', '\310', '\311', '\312', '\313', '\314', '\315', '\316',
-  '\317', '\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327',
-  '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337', '\340',
-  '\341', '\342', '\343', '\344', '\345', '\346', '\347', '\350', '\351',
-  '\352', '\353', '\354', '\355', '\356', '\357', '\360', '\361', '\362',
-  '\363', '\364', '\365', '\366', '\367', '\370', '\371', '\372', '\373',
-  '\374', '\375', '\376', '\377'
-};
-#  endif
+#  include <ctype.h>
 
-/*--------------------------------------------------------------------------*/
-int kwsysString_strcasecmp(char const* lhs, char const* rhs)
+int kwsysString_isalnum(char c)
 {
-#  if defined(KWSYS_STRING_USE_STRICMP)
-  return _stricmp(lhs, rhs);
-#  elif defined(KWSYS_STRING_USE_STRCASECMP)
-  return strcasecmp(lhs, rhs);
-#  else
-  char const* const lower = kwsysString_strcasecmp_tolower;
-  unsigned char const* us1 = (unsigned char const*)lhs;
-  unsigned char const* us2 = (unsigned char const*)rhs;
-  int result;
-  while ((result = lower[*us1] - lower[*us2++], result == 0) && *us1++) {
-  }
-  return result;
-#  endif
+  return (kwsysString_isalpha(c) | /* bitwise-or to avoid branching.  */
+          kwsysString_isdigit(c));
 }
 
-/*--------------------------------------------------------------------------*/
+int kwsysString_isalpha(char c)
+{
+  return (kwsysString_islower(c) | /* bitwise-or to avoid branching.  */
+          kwsysString_isupper(c));
+}
+
+int kwsysString_isascii(char c)
+{
+  unsigned char const uc = (unsigned char)c;
+  return (uc & 0x80) ^ 0x80;
+}
+
+int kwsysString_isblank(char c)
+{
+  unsigned char const uc = (unsigned char)c;
+  return uc < 0x80 && isblank(uc);
+}
+
+int kwsysString_iscntrl(char c)
+{
+  unsigned char const uc = (unsigned char)c;
+  return uc < 0x80 && iscntrl(uc);
+}
+
+int kwsysString_isdigit(char c)
+{
+  unsigned char const uc = (unsigned char)c;
+  /* Push '0-9' to 246-255 so integer division by 246 is 1 only for them.  */
+  return ((uc + 246 - '0') & 0xFF) / 246;
+}
+
+int kwsysString_isgraph(char c)
+{
+  unsigned char const uc = (unsigned char)c;
+  return uc < 0x80 && isgraph(uc);
+}
+
+int kwsysString_islower(char c)
+{
+  unsigned char const uc = (unsigned char)c;
+  /* Push 'a-z' to 230-255 so integer division by 230 is 1 only for them.  */
+  return ((uc + 230 - 'a') & 0xFF) / 230;
+}
+
+int kwsysString_isprint(char c)
+{
+  unsigned char const uc = (unsigned char)c;
+  /* Push 32-126 to 161-255 so integer division by 161 is 1 only for them.  */
+  return ((uc + 161 - ' ') & 0xFF) / 161;
+}
+
+int kwsysString_ispunct(char c)
+{
+  unsigned char const uc = (unsigned char)c;
+  return uc < 0x80 && ispunct(uc);
+}
+
+int kwsysString_isspace(char c)
+{
+  unsigned char const uc = (unsigned char)c;
+  return uc < 0x80 && isspace(uc);
+}
+
+int kwsysString_isupper(char c)
+{
+  unsigned char const uc = (unsigned char)c;
+  /* Push 'A-Z' to 230-255 so integer division by 230 is 1 only for them.  */
+  return ((uc + 230 - 'A') & 0xFF) / 230;
+}
+
+int kwsysString_isxdigit(char c)
+{
+  unsigned char const uc = (unsigned char)c;
+  return (
+    /* Push '0-9' to 246-255 so integer division by 246 is 1 only for them.  */
+    (((uc + 246 - '0') & 0xFF) / 246) | /* bitwise-or to avoid branching.    */
+    /* Push 'A-F' to 250-255 so integer division by 250 is 1 only for them.  */
+    (((uc + 250 - 'A') & 0xFF) / 250) | /* bitwise-or to avoid branching.    */
+    /* Push 'a-f' to 250-255 so integer division by 250 is 1 only for them.  */
+    (((uc + 250 - 'a') & 0xFF) / 250));
+}
+
+unsigned char kwsysString_tolower(char c)
+{
+  unsigned char const uc = (unsigned char)c;
+  /* Push 'A-Z' to 230-255 so integer division by 230 is 1 only for them.  */
+  return (unsigned char)(uc ^ ((((uc + 230 - 'A') & 0xFF) / 230) << 5));
+}
+
+unsigned char kwsysString_toupper(char c)
+{
+  unsigned char const uc = (unsigned char)c;
+  /* Push 'a-z' to 230-255 so integer division by 230 is 1 only for them.  */
+  return (unsigned char)(uc ^ ((((uc + 230 - 'a') & 0xFF) / 230) << 5));
+}
+
+int kwsysString_strcasecmp(char const* lhs, char const* rhs)
+{
+  int result;
+  while ((result = kwsysString_tolower(*lhs) - kwsysString_tolower(*rhs++)) ==
+           0 &&
+         *lhs++) {
+  }
+  return result;
+}
+
 int kwsysString_strncasecmp(char const* lhs, char const* rhs, size_t n)
 {
-#  if defined(KWSYS_STRING_USE_STRICMP)
-  return _strnicmp(lhs, rhs, n);
-#  elif defined(KWSYS_STRING_USE_STRCASECMP)
-  return strncasecmp(lhs, rhs, n);
-#  else
-  char const* const lower = kwsysString_strcasecmp_tolower;
-  unsigned char const* us1 = (unsigned char const*)lhs;
-  unsigned char const* us2 = (unsigned char const*)rhs;
   int result = 0;
-  while (n && (result = lower[*us1] - lower[*us2++], result == 0) && *us1++) {
+  while (n &&
+         (result = kwsysString_tolower(*lhs) - kwsysString_tolower(*rhs++)) ==
+           0 &&
+         *lhs++) {
     --n;
   }
   return result;
-#  endif
 }
 
 #endif /* KWSYS_STRING_C */
diff --git a/Source/kwsys/String.h.in b/Source/kwsys/String.h.in
index 6931051..abc74a6 100644
--- a/Source/kwsys/String.h.in
+++ b/Source/kwsys/String.h.in
@@ -16,6 +16,21 @@
 #  define kwsysEXPORT @KWSYS_NAMESPACE@_EXPORT
 #endif
 #if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
+#  define kwsysString_isalnum kwsys_ns(String_isalnum)
+#  define kwsysString_isalpha kwsys_ns(String_isalpha)
+#  define kwsysString_isascii kwsys_ns(String_isascii)
+#  define kwsysString_isblank kwsys_ns(String_isblank)
+#  define kwsysString_iscntrl kwsys_ns(String_iscntrl)
+#  define kwsysString_isdigit kwsys_ns(String_isdigit)
+#  define kwsysString_isgraph kwsys_ns(String_isgraph)
+#  define kwsysString_islower kwsys_ns(String_islower)
+#  define kwsysString_isprint kwsys_ns(String_isprint)
+#  define kwsysString_ispunct kwsys_ns(String_ispunct)
+#  define kwsysString_isspace kwsys_ns(String_isspace)
+#  define kwsysString_isupper kwsys_ns(String_isupper)
+#  define kwsysString_isxdigit kwsys_ns(String_isxdigit)
+#  define kwsysString_tolower kwsys_ns(String_tolower)
+#  define kwsysString_toupper kwsys_ns(String_toupper)
 #  define kwsysString_strcasecmp kwsys_ns(String_strcasecmp)
 #  define kwsysString_strncasecmp kwsys_ns(String_strncasecmp)
 #endif
@@ -24,6 +39,51 @@
 extern "C" {
 #endif
 
+/** Locale-independent ASCII isalnum.  */
+kwsysEXPORT int kwsysString_isalnum(char c);
+
+/** Locale-independent ASCII isalpha.  */
+kwsysEXPORT int kwsysString_isalpha(char c);
+
+/** Locale-independent ASCII isascii.  */
+kwsysEXPORT int kwsysString_isascii(char c);
+
+/** Locale-independent ASCII isblank.  */
+kwsysEXPORT int kwsysString_isblank(char c);
+
+/** Locale-independent ASCII iscntrl.  */
+kwsysEXPORT int kwsysString_iscntrl(char c);
+
+/** Locale-independent ASCII isdigit.  */
+kwsysEXPORT int kwsysString_isdigit(char c);
+
+/** Locale-independent ASCII isgraph.  */
+kwsysEXPORT int kwsysString_isgraph(char c);
+
+/** Locale-independent ASCII islower.  */
+kwsysEXPORT int kwsysString_islower(char c);
+
+/** Locale-independent ASCII isprint.  */
+kwsysEXPORT int kwsysString_isprint(char c);
+
+/** Locale-independent ASCII ispunct.  */
+kwsysEXPORT int kwsysString_ispunct(char c);
+
+/** Locale-independent ASCII isspace.  */
+kwsysEXPORT int kwsysString_isspace(char c);
+
+/** Locale-independent ASCII isupper.  */
+kwsysEXPORT int kwsysString_isupper(char c);
+
+/** Locale-independent ASCII isxdigit.  */
+kwsysEXPORT int kwsysString_isxdigit(char c);
+
+/** Locale-independent ASCII tolower.  */
+kwsysEXPORT unsigned char kwsysString_tolower(char c);
+
+/** Locale-independent ASCII toupper.  */
+kwsysEXPORT unsigned char kwsysString_toupper(char c);
+
 /**
  * Compare two strings ignoring the case of the characters.  The
  * integer returned is negative, zero, or positive if the first string
@@ -49,6 +109,21 @@
 #  undef kwsys_ns
 #  undef kwsysEXPORT
 #  if !@KWSYS_NAMESPACE@_NAME_IS_KWSYS
+#    undef kwsysString_isalnum
+#    undef kwsysString_isalpha
+#    undef kwsysString_isascii
+#    undef kwsysString_isblank
+#    undef kwsysString_iscntrl
+#    undef kwsysString_isdigit
+#    undef kwsysString_isgraph
+#    undef kwsysString_islower
+#    undef kwsysString_isprint
+#    undef kwsysString_ispunct
+#    undef kwsysString_isspace
+#    undef kwsysString_isupper
+#    undef kwsysString_isxdigit
+#    undef kwsysString_tolower
+#    undef kwsysString_toupper
 #    undef kwsysString_strcasecmp
 #    undef kwsysString_strncasecmp
 #  endif
diff --git a/Source/kwsys/System.c b/Source/kwsys/System.c
index 11257cd..cb7fc2d 100644
--- a/Source/kwsys/System.c
+++ b/Source/kwsys/System.c
@@ -1,15 +1,16 @@
 /* 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(String.h)
 #include KWSYS_HEADER(System.h)
 
 /* Work-around CMake dependency scanning limitation.  This must
    duplicate the above list of headers.  */
 #if 0
+#  include "String.h.in"
 #  include "System.h.in"
 #endif
 
-#include <ctype.h>  /* isspace */
 #include <stddef.h> /* ptrdiff_t */
 #include <stdlib.h> /* malloc, free */
 #include <string.h> /* memcpy */
@@ -148,7 +149,7 @@
           in_argument = 1;
         }
       }
-    } else if (isspace((unsigned char)*c)) {
+    } else if (kwsysString_isspace(*c)) {
       if (in_argument) {
         if (in_single || in_double) {
           /* This space belongs to a quoted argument.  */
diff --git a/Source/kwsys/SystemInformation.cxx b/Source/kwsys/SystemInformation.cxx
index 5f67f16..0a472d3 100644
--- a/Source/kwsys/SystemInformation.cxx
+++ b/Source/kwsys/SystemInformation.cxx
@@ -28,6 +28,7 @@
 // https://msdn.microsoft.com/en-us/library/ms683219(VS.85).aspx
 
 #include "kwsysPrivate.h"
+#include KWSYS_HEADER(String.h)
 #include KWSYS_HEADER(SystemInformation.hxx)
 #include KWSYS_HEADER(Process.h)
 
@@ -35,6 +36,7 @@
 // duplicate the above list of headers.
 #if 0
 #  include "Process.h.in"
+#  include "String.h.in"
 #  include "SystemInformation.hxx.in"
 #endif
 
@@ -165,7 +167,6 @@
 #  undef KWSYS_SYSTEMINFORMATION_HAS_SYMBOL_LOOKUP
 #endif
 
-#include <cctype> // int isdigit(int c);
 #include <cstdio>
 #include <cstdlib>
 #include <cstring>
@@ -4167,11 +4168,11 @@
     char majorChar = unameInfo.release[0];
     char minorChar = unameInfo.release[2];
 
-    if (isdigit(majorChar)) {
+    if (kwsysString_isdigit(majorChar)) {
       linuxMajor = majorChar - '0';
     }
 
-    if (isdigit(minorChar)) {
+    if (kwsysString_isdigit(minorChar)) {
       linuxMinor = minorChar - '0';
     }
   }
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
index 2bedcbd..7e23c16 100644
--- a/Source/kwsys/SystemTools.cxx
+++ b/Source/kwsys/SystemTools.cxx
@@ -25,9 +25,9 @@
 #include KWSYS_HEADER(FStream.hxx)
 #include KWSYS_HEADER(Encoding.h)
 #include KWSYS_HEADER(Encoding.hxx)
+#include KWSYS_HEADER(String.h)
 
 #include <algorithm>
-#include <cctype>
 #include <fstream>
 #include <iostream>
 #include <set>
@@ -44,9 +44,11 @@
 // duplicate the above list of headers.
 #if 0
 #  include "Directory.hxx.in"
+#  include "Encoding.h.in"
 #  include "Encoding.hxx.in"
 #  include "FStream.hxx.in"
 #  include "RegularExpression.hxx.in"
+#  include "String.h.in"
 #  include "SystemTools.hxx.in"
 #endif
 
@@ -58,7 +60,6 @@
 #  pragma set woff 1375 /* base class destructor not virtual */
 #endif
 
-#include <cctype>
 #include <cerrno>
 #include <cstdio>
 #include <cstdlib>
@@ -321,8 +322,7 @@
     if (nlen < len) {
       // make sure the drive letter is capital
       if (nlen > 1 && buf[1] == ':') {
-        buf[0] =
-          static_cast<char>(toupper(static_cast<unsigned char>(buf[0])));
+        buf[0] = kwsysString_toupper(buf[0]);
       }
       return buf;
     }
@@ -554,8 +554,7 @@
   casePath = path_components[idx++];
   // make sure drive letter is always upper case
   if (casePath.size() > 1 && casePath[1] == ':') {
-    casePath[0] = static_cast<std::string::value_type>(
-      toupper(static_cast<unsigned char>(casePath[0])));
+    casePath[0] = kwsysString_toupper(casePath[0]);
   }
   char const* sep = "";
 
@@ -1659,11 +1658,9 @@
     return n;
   }
   n.resize(s.size());
-  n[0] = static_cast<std::string::value_type>(
-    toupper(static_cast<unsigned char>(s[0])));
+  n[0] = static_cast<std::string::value_type>(kwsysString_toupper(s[0]));
   for (size_t i = 1; i < s.size(); i++) {
-    n[i] = static_cast<std::string::value_type>(
-      tolower(static_cast<unsigned char>(s[i])));
+    n[i] = static_cast<std::string::value_type>(kwsysString_tolower(s[i]));
   }
   return n;
 }
@@ -1673,17 +1670,9 @@
 {
   std::string n(s);
   for (size_t i = 0; i < s.size(); i++) {
-#if defined(_MSC_VER) && defined(_MT) && defined(_DEBUG)
-    // MS has an assert that will fail if s[i] < 0; setting
-    // LC_CTYPE using setlocale() does *not* help. Painful.
-    if ((int)s[i] >= 0 && isalpha(s[i]) &&
-        (i == 0 || ((int)s[i - 1] >= 0 && isspace(s[i - 1]))))
-#else
-    if (isalpha(s[i]) && (i == 0 || isspace(s[i - 1])))
-#endif
-    {
-      n[i] = static_cast<std::string::value_type>(
-        toupper(static_cast<unsigned char>(s[i])));
+    if (kwsysString_isalpha(s[i]) &&
+        (i == 0 || kwsysString_isspace(s[i - 1]))) {
+      n[i] = static_cast<std::string::value_type>(kwsysString_toupper(s[i]));
     }
   }
   return n;
@@ -1694,17 +1683,9 @@
 {
   std::string n(s);
   for (size_t i = 0; i < s.size(); i++) {
-#if defined(_MSC_VER) && defined(_MT) && defined(_DEBUG)
-    // MS has an assert that will fail if s[i] < 0; setting
-    // LC_CTYPE using setlocale() does *not* help. Painful.
-    if ((int)s[i] >= 0 && isalpha(s[i]) &&
-        (i == 0 || ((int)s[i - 1] >= 0 && isspace(s[i - 1]))))
-#else
-    if (isalpha(s[i]) && (i == 0 || isspace(s[i - 1])))
-#endif
-    {
-      n[i] = static_cast<std::string::value_type>(
-        tolower(static_cast<unsigned char>(s[i])));
+    if (kwsysString_isalpha(s[i]) &&
+        (i == 0 || kwsysString_isspace(s[i - 1]))) {
+      n[i] = static_cast<std::string::value_type>(kwsysString_tolower(s[i]));
     }
   }
   return n;
@@ -1718,7 +1699,8 @@
     n.reserve(s.size());
     n += s[0];
     for (size_t i = 1; i < s.size(); i++) {
-      if (isupper(s[i]) && !isspace(s[i - 1]) && !isupper(s[i - 1])) {
+      if (kwsysString_isupper(s[i]) && !kwsysString_isspace(s[i - 1]) &&
+          !kwsysString_isupper(s[i - 1])) {
         n += ' ';
       }
       n += s[i];
@@ -1771,15 +1753,13 @@
 
 std::string SystemTools::LowerCase(std::string s)
 {
-  std::transform(s.begin(), s.end(), s.begin(),
-                 [](unsigned char c) { return std::tolower(c); });
+  std::transform(s.begin(), s.end(), s.begin(), kwsysString_tolower);
   return s;
 }
 
 std::string SystemTools::UpperCase(std::string s)
 {
-  std::transform(s.begin(), s.end(), s.begin(),
-                 [](unsigned char c) { return std::toupper(c); });
+  std::transform(s.begin(), s.end(), s.begin(), kwsysString_toupper);
   return s;
 }
 
@@ -2004,7 +1984,7 @@
     if (*cur++ == '%') {
       // Skip "%%" since it doesn't correspond to a va_arg.
       if (*cur != '%') {
-        while (!int(isalpha(*cur))) {
+        while (!kwsysString_isalpha(*cur)) {
           ++cur;
         }
         switch (*cur) {
@@ -2742,8 +2722,8 @@
   int lc;
   int rc;
   do {
-    lc = tolower(static_cast<unsigned char>(*l++));
-    rc = tolower(static_cast<unsigned char>(*r++));
+    lc = kwsysString_tolower(*l++);
+    rc = kwsysString_tolower(*r++);
   } while (lc == rc && lc);
   return lc - rc;
 }
diff --git a/Source/kwsys/testString.c b/Source/kwsys/testString.c
new file mode 100644
index 0000000..b6a1e84
--- /dev/null
+++ b/Source/kwsys/testString.c
@@ -0,0 +1,134 @@
+/* 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(String.h)
+
+/* Work-around CMake dependency scanning limitation.  This must
+   duplicate the above list of headers.  */
+#if 0
+#  include "String.h.in"
+#endif
+
+#include <ctype.h>
+#include <locale.h>
+#include <stdio.h>
+
+#ifdef _WIN32
+static int isprint_posix(int c)
+{
+  return isprint(c) && c != '\t';
+}
+#  define isprint isprint_posix
+#endif
+
+#define MAKE_testString_(isXXXXX)                                             \
+  static int testString_##isXXXXX(void)                                       \
+  {                                                                           \
+    int i = 0;                                                                \
+    for (; i < 128; ++i) {                                                    \
+      if (!!isXXXXX(i) != !!kwsysString_##isXXXXX((char)i)) {                 \
+        printf(#isXXXXX "(%d) failed: %d\n", i,                               \
+               kwsysString_##isXXXXX((char)i));                               \
+        return 1;                                                             \
+      }                                                                       \
+    }                                                                         \
+    for (; i < 256; ++i) {                                                    \
+      if (kwsysString_##isXXXXX((char)i)) {                                   \
+        printf(#isXXXXX "(%d) failed: %d\n", i,                               \
+               kwsysString_##isXXXXX((char)i));                               \
+        return 1;                                                             \
+      }                                                                       \
+    }                                                                         \
+    return 0;                                                                 \
+  }                                                                           \
+  static int testString_##isXXXXX(void)
+
+MAKE_testString_(isalnum);
+MAKE_testString_(isalpha);
+MAKE_testString_(isascii);
+MAKE_testString_(isblank);
+MAKE_testString_(iscntrl);
+MAKE_testString_(isdigit);
+MAKE_testString_(isgraph);
+MAKE_testString_(islower);
+MAKE_testString_(isprint);
+MAKE_testString_(ispunct);
+MAKE_testString_(isspace);
+MAKE_testString_(isupper);
+MAKE_testString_(isxdigit);
+
+static int testString_tolower(void)
+{
+  int i = 0;
+  int j;
+  for (; i < 'A'; ++i) {
+    if ((j = kwsysString_tolower((char)i)) != i) {
+      printf("tolower(%d) failed: %d\n", i, j);
+      return 1;
+    }
+  }
+  for (; i <= 'Z'; ++i) {
+    if ((j = kwsysString_tolower((char)i)) != i + 32) {
+      printf("tolower(%d) failed: %d\n", i, j);
+      return 1;
+    }
+  }
+  for (; i < 256; ++i) {
+    if ((j = kwsysString_tolower((char)i)) != i) {
+      printf("tolower(%d) failed: %d\n", i, j);
+      return 1;
+    }
+  }
+  return 0;
+}
+
+static int testString_toupper(void)
+{
+  int i = 0;
+  int j;
+  for (; i < 'a'; ++i) {
+    if ((j = kwsysString_toupper((char)i)) != i) {
+      printf("toupper(%d) failed: %d\n", i, j);
+      return 1;
+    }
+  }
+  for (; i <= 'z'; ++i) {
+    if ((j = kwsysString_toupper((char)i)) != i - 32) {
+      printf("toupper(%d) failed: %d\n", i, j);
+      return 1;
+    }
+  }
+  for (; i < 256; ++i) {
+    if ((j = kwsysString_toupper((char)i)) != i) {
+      printf("toupper(%d) failed: %d\n", i, j);
+      return 1;
+    }
+  }
+  return 0;
+}
+
+int testString(int argc, char* argv[])
+{
+  int result = 0;
+  (void)argc;
+  (void)argv;
+  setlocale(LC_CTYPE, "");
+
+  result |= testString_isalnum();
+  result |= testString_isalpha();
+  result |= testString_isascii();
+  result |= testString_isblank();
+  result |= testString_iscntrl();
+  result |= testString_isdigit();
+  result |= testString_isgraph();
+  result |= testString_islower();
+  result |= testString_isprint();
+  result |= testString_ispunct();
+  result |= testString_isspace();
+  result |= testString_isupper();
+  result |= testString_isxdigit();
+  result |= testString_tolower();
+  result |= testString_toupper();
+
+  return result;
+}
diff --git a/Tests/CMakeLib/testPathResolver.cxx b/Tests/CMakeLib/testPathResolver.cxx
index 6a38c31..ce759e5 100644
--- a/Tests/CMakeLib/testPathResolver.cxx
+++ b/Tests/CMakeLib/testPathResolver.cxx
@@ -9,7 +9,7 @@
 #include <utility>
 
 #ifdef _WIN32
-#  include <cctype>
+#  include <cmsys/String.h>
 #endif
 
 #include <cmsys/Status.hxx>
@@ -92,8 +92,7 @@
   std::string GetWorkingDirectoryOnDrive(char letter) override
   {
     std::string result;
-    auto i = this->WorkDirOnDrive.find(
-      std::tolower(static_cast<unsigned char>(letter)));
+    auto i = this->WorkDirOnDrive.find(cmsysString_tolower(letter));
     if (i != this->WorkDirOnDrive.end()) {
       result = i->second;
     }
diff --git a/Tests/CMakeLib/testUVProcessChainHelper.cxx b/Tests/CMakeLib/testUVProcessChainHelper.cxx
index ea843d9..50ad761 100644
--- a/Tests/CMakeLib/testUVProcessChainHelper.cxx
+++ b/Tests/CMakeLib/testUVProcessChainHelper.cxx
@@ -1,4 +1,3 @@
-#include <cctype>
 #include <chrono>
 #include <cstdlib>
 #include <iostream>
@@ -7,6 +6,7 @@
 #include <string>
 #include <thread>
 
+#include "cmsys/String.h"
 #include "cmsys/SystemTools.hxx"
 
 #ifdef _WIN32
@@ -41,7 +41,7 @@
     std::this_thread::sleep_for(std::chrono::milliseconds(12000));
     std::string input = getStdin();
     for (auto& c : input) {
-      c = static_cast<char>(std::toupper(static_cast<unsigned char>(c)));
+      c = static_cast<char>(cmsysString_toupper(c));
     }
     std::cout << input << std::flush;
     std::cerr << "2" << std::flush;
diff --git a/Tests/FindPackageCpsTest/CMakeLists.txt b/Tests/FindPackageCpsTest/CMakeLists.txt
index 3c762fd..232c7d8 100644
--- a/Tests/FindPackageCpsTest/CMakeLists.txt
+++ b/Tests/FindPackageCpsTest/CMakeLists.txt
@@ -1,8 +1,6 @@
 cmake_minimum_required(VERSION 3.31)
 project(FindPackageCpsTest)
 
-set(CMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES "e82e467b-f997-4464-8ace-b00808fff261")
-
 # Protect tests from running inside the default install prefix.
 set(CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/NotDefaultPrefix")
 
@@ -29,6 +27,13 @@
   endif()
 endfunction()
 
+function(expect_property TARGET PROPERTY DESCRIPTION EXPECTED)
+  get_target_property(actual ${TARGET} ${PROPERTY})
+  if(NOT "${actual}" STREQUAL "${EXPECTED}")
+    message(SEND_ERROR "${TARGET} has wrong ${DESCRIPTION} '${actual}' !")
+  endif()
+endfunction()
+
 function(test_version PACKAGE LITERAL COUNT MAJOR MINOR PATCH TWEAK)
   if(NOT ${PACKAGE}_FOUND)
     message(SEND_ERROR "${PACKAGE} not found !")
@@ -47,7 +52,7 @@
   test_version(${PACKAGE} "${VERSION}" 0 0 0 0 0)
 endfunction()
 
-function(test_global TARGET VALUE)
+function(expect_global TARGET VALUE)
   get_target_property(global "${TARGET}" IMPORTED_GLOBAL)
   if((VALUE AND NOT global) OR (NOT VALUE AND global))
     message(SEND_ERROR "${TARGET} has wrong IMPORTED_GLOBAL '${global}' !")
@@ -78,6 +83,7 @@
 
 ###############################################################################
 # Test finding a package whose CPS file is in the package prefix root.
+
 set(RootTest_DIR "${CMAKE_CURRENT_SOURCE_DIR}/RootTest")
 find_package(RootTest)
 if(NOT RootTest_FOUND)
@@ -166,21 +172,15 @@
 elseif(NOT TARGET Foo::Empty)
   message(SEND_ERROR "Foo::Empty missing !")
 else()
-  get_property(pt_includes
-    TARGET Foo::PrefixTest PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
-  if(NOT "${pt_includes}" STREQUAL "$<$<CONFIG:default>:${CMAKE_CURRENT_SOURCE_DIR}/include>" )
-    message(SEND_ERROR "Foo::PrefixTest has wrong includes '${pt_includes}' !")
-  endif()
-  set(pt_includes)
+  expect_property(
+    Foo::PrefixTest INTERFACE_INCLUDE_DIRECTORIES "includes"
+    "$<$<CONFIG:default>:${CMAKE_CURRENT_SOURCE_DIR}/include>")
 
-  get_property(rt_includes
-    TARGET Foo::RelativeTest PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
-  if(NOT "${rt_includes}" STREQUAL "$<$<CONFIG:default>:${CMAKE_CURRENT_SOURCE_DIR}/cps/../include>")
-    message(SEND_ERROR "Foo::RelativeTest has wrong includes '${rt_includes}' !")
-  endif()
-  set(rt_includes)
+  expect_property(
+    Foo::RelativeTest INTERFACE_INCLUDE_DIRECTORIES "includes"
+    "$<$<CONFIG:default>:${CMAKE_CURRENT_SOURCE_DIR}/cps/../include>")
 
-  test_global(Foo::Empty FALSE)
+  expect_global(Foo::Empty FALSE)
 endif()
 
 ###############################################################################
@@ -192,7 +192,7 @@
 elseif(NOT TARGET Global::Target)
   message(SEND_ERROR "Global::Target missing !")
 else()
-  test_global(Foo::Empty FALSE)
+  expect_global(Foo::Empty FALSE)
 endif()
 
 ###############################################################################
@@ -223,6 +223,18 @@
 add_executable(requires-test-compile_only requires-test.cxx)
 target_link_libraries(requires-test-compile_only RequiresTest::CompileOnly)
 
+expect_property(
+  RequiresTest::Other INTERFACE_LINK_LIBRARIES
+  "link libraries" "every-config;$<$<CONFIG:test>:test-config>")
+
+expect_property(
+  RequiresTest::Other IMPORTED_LINK_DEPENDENT_LIBRARIES
+  "dyld requirements (any config)" "RequiresTest::Private1")
+
+expect_property(
+  RequiresTest::Other IMPORTED_LINK_DEPENDENT_LIBRARIES_TEST
+  "dyld requirements ('TEST' config)" "RequiresTest::Private2")
+
 ###############################################################################
 # Test importing of (language-specific) include paths.
 
@@ -343,16 +355,10 @@
 elseif(NOT TARGET DefaultConfigurationsTest::Target2)
   message(SEND_ERROR "DefaultConfigurationsTest::Target2 missing !")
 else()
-  get_property(dct1_configs
-    TARGET DefaultConfigurationsTest::Target1 PROPERTY IMPORTED_CONFIGURATIONS)
-  if(NOT "${dct1_configs}" STREQUAL "DEFAULT;TEST")
-    message(SEND_ERROR "DefaultConfigurationsTest::Target1 has wrong configurations '${dct1_configs}' !")
-  endif()
-  get_property(dct2_configs
-    TARGET DefaultConfigurationsTest::Target2 PROPERTY IMPORTED_CONFIGURATIONS)
-  if(NOT "${dct2_configs}" STREQUAL "TEST")
-    message(SEND_ERROR "DefaultConfigurationsTest::Target2 has wrong configurations '${dct2_configs}' !")
-  endif()
-  set(dct1_configs)
-  set(dct2_configs)
+  expect_property(
+    DefaultConfigurationsTest::Target1 IMPORTED_CONFIGURATIONS
+    "configurations" "DEFAULT;TEST")
+  expect_property(
+    DefaultConfigurationsTest::Target2 IMPORTED_CONFIGURATIONS
+    "configurations" "TEST")
 endif()
diff --git a/Tests/FindPackageCpsTest/cps/RequiresTest.cps b/Tests/FindPackageCpsTest/cps/RequiresTest.cps
index cf2c522..3a6affb 100644
--- a/Tests/FindPackageCpsTest/cps/RequiresTest.cps
+++ b/Tests/FindPackageCpsTest/cps/RequiresTest.cps
@@ -27,6 +27,23 @@
           "ANSWER": 42
         }
       }
+    },
+    "Private1": {
+      "type": "dylib"
+    },
+    "Private2": {
+      "type": "dylib"
+    },
+    "Other": {
+      "type": "dylib",
+      "link_libraries": [ "every-config" ],
+      "dyld_requires": [ ":Private1" ],
+      "configurations": {
+        "test": {
+          "link_libraries": [ "test-config" ],
+          "dyld_requires": [ ":Private2" ]
+        }
+      }
     }
   }
 }
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 2fc19c7..6d23fc8 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -685,6 +685,9 @@
 endif()
 add_RunCMake_test(execute_process)
 add_RunCMake_test(export)
+if(DEFINED CMake_TEST_LOCALE_CHARSET)
+  list(APPEND cmake_host_system_information_ARGS -DCMake_TEST_LOCALE_CHARSET=${CMake_TEST_LOCALE_CHARSET})
+endif()
 if(CMake_TEST_MSYSTEM_PREFIX)
   list(APPEND cmake_host_system_information_ARGS -DCMake_TEST_MSYSTEM_PREFIX=${CMake_TEST_MSYSTEM_PREFIX})
 endif()
diff --git a/Tests/RunCMake/CPack_WIX/3-AppWiX-perUser-cpack-WIX-check.cmake b/Tests/RunCMake/CPack_WIX/3-AppWiX-perUser-cpack-WIX-check.cmake
new file mode 100644
index 0000000..a7a28ae
--- /dev/null
+++ b/Tests/RunCMake/CPack_WIX/3-AppWiX-perUser-cpack-WIX-check.cmake
@@ -0,0 +1 @@
+include(${RunCMake_SOURCE_DIR}/cpack-check-common.cmake)
diff --git a/Tests/RunCMake/CPack_WIX/3-AppWiX-perUser-verify-stdout.txt b/Tests/RunCMake/CPack_WIX/3-AppWiX-perUser-verify-stdout.txt
new file mode 100644
index 0000000..2c625fb
--- /dev/null
+++ b/Tests/RunCMake/CPack_WIX/3-AppWiX-perUser-verify-stdout.txt
@@ -0,0 +1,40 @@
+-- MyLib-1\.0\.0-(win64|windows-arm64)\.msi
+Component: 'INSTALL_ROOT_RemoveFolderComponent' 'INSTALL_ROOT'
+Component: 'CM_DP_applications\.bin_RemoveFolderComponent' 'CM_DP_applications\.bin'
+Component: 'CM_DP_applications2\.bin_RemoveFolderComponent' 'CM_DP_applications2\.bin'
+Component: 'CM_DP_extras\.extras_RemoveFolderComponent' 'CM_DP_extras\.extras'
+Component: 'CM_DP_extras\.extras\.empty_RemoveFolderComponent' 'CM_DP_extras\.extras\.empty'
+Component: 'CM_DP_headers\.include_RemoveFolderComponent' 'CM_DP_headers\.include'
+Component: 'CM_DP_libraries\.lib_RemoveFolderComponent' 'CM_DP_libraries\.lib'
+Component: 'CM_CP_applications\.bin\.my_libapp\.exe' 'CM_DP_applications\.bin'
+Component: 'CM_SHORTCUT_applications' 'PROGRAM_MENU_FOLDER'
+Component: 'CM_SHORTCUT_DESKTOP_applications' 'DesktopFolder'
+Component: 'CM_CP_applications2\.bin\.my_other_app\.exe' 'CM_DP_applications2\.bin'
+Component: 'CM_SHORTCUT_applications2' 'PROGRAM_MENU_FOLDER'
+Component: 'CM_SHORTCUT_DESKTOP_applications2' 'DesktopFolder'
+Component: 'CM_C_EMPTY_CM_DP_extras\.extras\.empty' 'CM_DP_extras\.extras\.empty'
+Component: 'CM_CP_headers\.include\.file_with_spaces\.h' 'CM_DP_headers\.include'
+Component: 'CM_CP_headers\.include\.mylib\.h' 'CM_DP_headers\.include'
+Component: 'CM_CP_libraries\.lib\.mylib\.lib' 'CM_DP_libraries\.lib'
+Directory: 'INSTALL_ROOT' 'LocalAppDataFolder' '[^']*\|CPack Component Example'
+Directory: 'CM_DP_applications\.bin' 'INSTALL_ROOT' 'bin'
+Directory: 'CM_DP_applications2\.bin' 'INSTALL_ROOT' 'bin'
+Directory: 'CM_DP_extras\.extras' 'INSTALL_ROOT' 'extras'
+Directory: 'CM_DP_extras\.extras\.empty' 'CM_DP_extras\.extras' 'empty'
+Directory: 'CM_DP_headers\.include' 'INSTALL_ROOT' 'include'
+Directory: 'CM_DP_libraries\.lib' 'INSTALL_ROOT' 'lib'
+Directory: 'PROGRAM_MENU_FOLDER' 'ProgramMenuFolder' 'MyLib'
+Directory: 'DesktopFolder' 'TARGETDIR' 'Desktop'
+Directory: 'LocalAppDataFolder' 'TARGETDIR' '\.'
+Directory: 'TARGETDIR' '' 'SourceDir'
+Directory: 'ProgramMenuFolder' 'TARGETDIR' '\.'
+File: 'CM_FP_applications\.bin\.my_libapp\.exe' 'CM_CP_applications\.bin\.my_libapp\.exe' '[^']*\|my-libapp\.exe'
+File: 'CM_FP_applications2\.bin\.my_other_app\.exe' 'CM_CP_applications2\.bin\.my_other_app\.exe' '[^']*\|my-other-app\.exe'
+File: 'CM_FP_headers\.include\.file_with_spaces\.h' 'CM_CP_headers\.include\.file_with_spaces\.h' '[^']*\|file with spaces\.h'
+File: 'CM_FP_headers\.include\.mylib\.h' 'CM_CP_headers\.include\.mylib\.h' 'mylib\.h'
+File: 'CM_FP_libraries\.lib\.mylib\.lib' 'CM_CP_libraries\.lib\.mylib\.lib' 'mylib\.lib'
+Shortcut: 'CM_SP_applications\.bin\.my_libapp\.exe' 'PROGRAM_MENU_FOLDER' '[^']*\|CPack WiX Test' 'CM_SHORTCUT_applications'
+Shortcut: 'CM_DSP_applications\.bin\.my_libapp\.exe' 'DesktopFolder' '[^']*\|CPack WiX Test' 'CM_SHORTCUT_DESKTOP_applications'
+Shortcut: 'CM_SP_applications2\.bin\.my_other_app\.exe' 'PROGRAM_MENU_FOLDER' '[^']*\|Second CPack WiX Test' 'CM_SHORTCUT_applications2'
+Shortcut: 'CM_DSP_applications2\.bin\.my_other_app\.exe' 'DesktopFolder' '[^']*\|Second CPack WiX Test' 'CM_SHORTCUT_DESKTOP_applications2'
+--
diff --git a/Tests/RunCMake/CPack_WIX/4-AppWiX-perUser-cpack-WIX-check.cmake b/Tests/RunCMake/CPack_WIX/4-AppWiX-perUser-cpack-WIX-check.cmake
new file mode 100644
index 0000000..a7a28ae
--- /dev/null
+++ b/Tests/RunCMake/CPack_WIX/4-AppWiX-perUser-cpack-WIX-check.cmake
@@ -0,0 +1 @@
+include(${RunCMake_SOURCE_DIR}/cpack-check-common.cmake)
diff --git a/Tests/RunCMake/CPack_WIX/4-AppWiX-perUser-cpack-WIX-stdout.txt b/Tests/RunCMake/CPack_WIX/4-AppWiX-perUser-cpack-WIX-stdout.txt
new file mode 100644
index 0000000..80e0e3a
--- /dev/null
+++ b/Tests/RunCMake/CPack_WIX/4-AppWiX-perUser-cpack-WIX-stdout.txt
@@ -0,0 +1,13 @@
+CPack: Create package using WIX
+CPack: Install projects
+CPack: - Install project: CPackWiXGenerator \[Release\]
+CPack: -   Install component: applications
+CPack: -   Install component: applications2
+CPack: -   Install component: empty1
+CPack: -   Install component: empty2
+CPack: -   Install component: extras
+CPack: -   Install component: headers
+CPack: -   Install component: libraries
+CPack: Create package
+CPack: - package: [^
+]*/Tests/RunCMake/CPack_WIX/4-AppWiX-perUser-build/MyLib-1\.0\.0-(win64|windows-arm64)\.msi generated\.
diff --git a/Tests/RunCMake/CPack_WIX/4-AppWiX-perUser-verify-stdout.txt b/Tests/RunCMake/CPack_WIX/4-AppWiX-perUser-verify-stdout.txt
new file mode 100644
index 0000000..bbd9fbe
--- /dev/null
+++ b/Tests/RunCMake/CPack_WIX/4-AppWiX-perUser-verify-stdout.txt
@@ -0,0 +1,40 @@
+-- MyLib-1\.0\.0-(win64|windows-arm64)\.msi
+Component: 'INSTALL_ROOT_RemoveFolderComponent' 'INSTALL_ROOT'
+Component: 'CM_DP_applications\.bin_RemoveFolderComponent' 'CM_DP_applications\.bin'
+Component: 'CM_CP_applications\.bin\.my_libapp\.exe' 'CM_DP_applications\.bin'
+Component: 'CM_SHORTCUT_applications' 'PROGRAM_MENU_FOLDER'
+Component: 'CM_SHORTCUT_DESKTOP_applications' 'DesktopFolder'
+Component: 'CM_DP_applications2\.bin_RemoveFolderComponent' 'CM_DP_applications2\.bin'
+Component: 'CM_CP_applications2\.bin\.my_other_app\.exe' 'CM_DP_applications2\.bin'
+Component: 'CM_SHORTCUT_applications2' 'PROGRAM_MENU_FOLDER'
+Component: 'CM_SHORTCUT_DESKTOP_applications2' 'DesktopFolder'
+Component: 'CM_DP_extras\.extras_RemoveFolderComponent' 'CM_DP_extras\.extras'
+Component: 'CM_DP_extras\.extras\.empty_RemoveFolderComponent' 'CM_DP_extras\.extras\.empty'
+Component: 'CM_C_EMPTY_CM_DP_extras\.extras\.empty' 'CM_DP_extras\.extras\.empty'
+Component: 'CM_DP_headers\.include_RemoveFolderComponent' 'CM_DP_headers\.include'
+Component: 'CM_CP_headers\.include\.file_with_spaces\.h' 'CM_DP_headers\.include'
+Component: 'CM_CP_headers\.include\.mylib\.h' 'CM_DP_headers\.include'
+Component: 'CM_DP_libraries\.lib_RemoveFolderComponent' 'CM_DP_libraries\.lib'
+Component: 'CM_CP_libraries\.lib\.mylib\.lib' 'CM_DP_libraries\.lib'
+Directory: 'INSTALL_ROOT' 'LocalAppDataFolder' '[^']*\|CPack Component Example'
+Directory: 'CM_DP_applications\.bin' 'INSTALL_ROOT' 'bin'
+Directory: 'CM_DP_applications2\.bin' 'INSTALL_ROOT' 'bin'
+Directory: 'CM_DP_extras\.extras' 'INSTALL_ROOT' 'extras'
+Directory: 'CM_DP_extras\.extras\.empty' 'CM_DP_extras\.extras' 'empty'
+Directory: 'CM_DP_headers\.include' 'INSTALL_ROOT' 'include'
+Directory: 'CM_DP_libraries\.lib' 'INSTALL_ROOT' 'lib'
+Directory: 'PROGRAM_MENU_FOLDER' 'ProgramMenuFolder' 'MyLib'
+Directory: 'DesktopFolder' 'TARGETDIR' 'Desktop'
+Directory: 'LocalAppDataFolder' 'TARGETDIR' 'LocalApp'
+Directory: 'ProgramMenuFolder' 'TARGETDIR' 'PMenu'
+Directory: 'TARGETDIR' '' 'SourceDir'
+File: 'CM_FP_applications\.bin\.my_libapp\.exe' 'CM_CP_applications\.bin\.my_libapp\.exe' '[^']*\|my-libapp\.exe'
+File: 'CM_FP_applications2\.bin\.my_other_app\.exe' 'CM_CP_applications2\.bin\.my_other_app\.exe' '[^']*\|my-other-app\.exe'
+File: 'CM_FP_headers\.include\.file_with_spaces\.h' 'CM_CP_headers\.include\.file_with_spaces\.h' '[^']*\|file with spaces\.h'
+File: 'CM_FP_headers\.include\.mylib\.h' 'CM_CP_headers\.include\.mylib\.h' 'mylib\.h'
+File: 'CM_FP_libraries\.lib\.mylib\.lib' 'CM_CP_libraries\.lib\.mylib\.lib' 'mylib\.lib'
+Shortcut: 'CM_SP_applications\.bin\.my_libapp\.exe' 'PROGRAM_MENU_FOLDER' '[^']*\|CPack WiX Test' 'CM_SHORTCUT_applications'
+Shortcut: 'CM_DSP_applications\.bin\.my_libapp\.exe' 'DesktopFolder' '[^']*\|CPack WiX Test' 'CM_SHORTCUT_DESKTOP_applications'
+Shortcut: 'CM_SP_applications2\.bin\.my_other_app\.exe' 'PROGRAM_MENU_FOLDER' '[^']*\|Second CPack WiX Test' 'CM_SHORTCUT_applications2'
+Shortcut: 'CM_DSP_applications2\.bin\.my_other_app\.exe' 'DesktopFolder' '[^']*\|Second CPack WiX Test' 'CM_SHORTCUT_DESKTOP_applications2'
+--
diff --git a/Tests/RunCMake/CPack_WIX/RunCMakeTest.cmake b/Tests/RunCMake/CPack_WIX/RunCMakeTest.cmake
index bb34321..486271b 100644
--- a/Tests/RunCMake/CPack_WIX/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CPack_WIX/RunCMakeTest.cmake
@@ -11,14 +11,21 @@
   run_cpack(${v}-AppWiX SAMPLE AppWiX BUILD)
 endfunction()
 
+function(run_cpack_wix_peruser v)
+  set(RunCMake_TEST_OPTIONS -DCPACK_WIX_VERSION=${v} -DCPACK_WIX_INSTALL_SCOPE=perUser)
+  run_cpack(${v}-AppWiX-perUser SAMPLE AppWiX BUILD)
+endfunction()
+
 if(CMake_TEST_CPACK_WIX3)
   set(ENV{PATH} "${CMake_TEST_CPACK_WIX3};${env_PATH}")
   run_cpack_wix(3)
+  run_cpack_wix_peruser(3)
 endif()
 
 if(CMake_TEST_CPACK_WIX4)
   set(ENV{PATH} "${CMake_TEST_CPACK_WIX4};${env_PATH}")
   set(ENV{WIX_EXTENSIONS} "${CMake_TEST_CPACK_WIX4}")
   run_cpack_wix(4)
+  run_cpack_wix_peruser(4)
   unset(ENV{WIX_EXTENSIONS})
 endif()
diff --git a/Tests/RunCMake/CXXModules/NoCXX23TargetUnset.cmake b/Tests/RunCMake/CXXModules/NoCXX23TargetUnset.cmake
index 8f6a656..be9c632 100644
--- a/Tests/RunCMake/CXXModules/NoCXX23TargetUnset.cmake
+++ b/Tests/RunCMake/CXXModules/NoCXX23TargetUnset.cmake
@@ -3,7 +3,7 @@
 
 # TODO(cxxmodules): Add instances of this test which test the policy
 # of the property's unset behavior.
-# set(CMAKE_CXX_MODULE_STD …)
+# set(CMAKE_CXX_MODULE_STD ...)
 
 add_library(nocxx23target)
 target_sources(nocxx23target
diff --git a/Tests/RunCMake/CXXModules/NoCXX26TargetUnset.cmake b/Tests/RunCMake/CXXModules/NoCXX26TargetUnset.cmake
index 85108ff..c725490 100644
--- a/Tests/RunCMake/CXXModules/NoCXX26TargetUnset.cmake
+++ b/Tests/RunCMake/CXXModules/NoCXX26TargetUnset.cmake
@@ -3,7 +3,7 @@
 
 # TODO(cxxmodules): Add instances of this test which test the policy
 # of the property's unset behavior.
-# set(CMAKE_CXX_MODULE_STD …)
+# set(CMAKE_CXX_MODULE_STD ...)
 
 add_library(nocxx26target)
 target_sources(nocxx26target
diff --git a/Tests/RunCMake/CXXModulesCompile/RunCMakeTest.cmake b/Tests/RunCMake/CXXModulesCompile/RunCMakeTest.cmake
index de3f027..663f9ca 100644
--- a/Tests/RunCMake/CXXModulesCompile/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CXXModulesCompile/RunCMakeTest.cmake
@@ -177,6 +177,13 @@
   run_cxx_module_test(scan_props)
   run_cxx_module_test(target-objects)
 
+  # mixed-bmi-compatibility requires a generator that implements per-importer
+  # BMI generation
+  if ("cxx_std_23" IN_LIST CMAKE_CXX_COMPILE_FEATURES AND
+      RunCMake_GENERATOR MATCHES "Ninja")
+    run_cxx_module_test(mixed-bmi-compatibility)
+  endif()
+
   if ("cxx_std_23" IN_LIST CMAKE_CXX_COMPILE_FEATURES AND
       "import_std23" IN_LIST CMake_TEST_MODULE_COMPILATION)
     run_cxx_module_test(imp-std)
@@ -251,6 +258,7 @@
 # Tests which use named modules in shared libraries.
 if ("shared" IN_LIST CMake_TEST_MODULE_COMPILATION)
   run_cxx_module_test(library library-shared -DBUILD_SHARED_LIBS=ON)
+  run_cxx_module_test(shared-library-symbol-visibility)
 endif ()
 
 # Tests which use partitions.
@@ -274,22 +282,19 @@
   run_cxx_module_test(imp-mods "imp-mods-${name}" "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/${name}-${type}" ${ARGN})
 endfunction ()
 
-set(export_cps "-DCMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO=7fa7d13b-8308-4dc7-af39-9e450456d68f")
-set(import_cps "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES=e82e467b-f997-4464-8ace-b00808fff261")
-
 # Tests which install BMIs
 if ("export_bmi" IN_LIST CMake_TEST_MODULE_COMPILATION)
   run_cxx_module_test(exp-iface-no-props-build)
-  run_cxx_module_test(exp-iface-build exp-iface-build ${export_cps})
-  run_cxx_module_test(exp-incdirs-build exp-incdirs-build ${export_cps})
+  run_cxx_module_test(exp-iface-build)
+  run_cxx_module_test(exp-incdirs-build)
   run_cxx_module_test(exp-incdirs-old-cmake-build)
   run_cxx_module_test(exp-usage-build)
   run_cxx_module_test(exp-bmi-and-iface-build)
-  run_cxx_module_test(exp-command-sepdir-build exp-command-sepdir-build ${export_cps})
+  run_cxx_module_test(exp-command-sepdir-build)
   run_cxx_module_test(exp-trans-targets-build)
-  run_cxx_module_test(exp-trans-mods1-build exp-trans-mods1-build ${export_cps})
-  run_cxx_module_test(exp-trans-mods-build exp-trans-mods-build "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/exp-trans-mods1-build-build" "-Dexport_transitive_modules1_cps_DIR=${RunCMake_BINARY_DIR}/exp-trans-mods1-build-build" ${export_cps} ${import_cps})
-  run_cxx_module_test(exp-with-headers-build exp-with-headers-build ${export_cps})
+  run_cxx_module_test(exp-trans-mods1-build)
+  run_cxx_module_test(exp-trans-mods-build exp-trans-mods-build "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/exp-trans-mods1-build-build" "-Dexport_transitive_modules1_cps_DIR=${RunCMake_BINARY_DIR}/exp-trans-mods1-build-build")
+  run_cxx_module_test(exp-with-headers-build)
 
   if ("collation" IN_LIST CMake_TEST_MODULE_COMPILATION AND
       "bmionly" IN_LIST CMake_TEST_MODULE_COMPILATION)
@@ -322,16 +327,16 @@
 
   if ("export_bmi" IN_LIST CMake_TEST_MODULE_COMPILATION)
     run_cxx_module_test(exp-iface-no-props-install)
-    run_cxx_module_test(exp-iface-install exp-iface-install ${export_cps})
-    run_cxx_module_test(exp-incdirs-install exp-incdirs-install ${export_cps})
+    run_cxx_module_test(exp-iface-install)
+    run_cxx_module_test(exp-incdirs-install)
     run_cxx_module_test(exp-incdirs-old-cmake-install)
     run_cxx_module_test(exp-usage-install)
     run_cxx_module_test(exp-bmi-and-iface-install)
-    run_cxx_module_test(exp-command-sepdir-install exp-command-sepdir-install ${export_cps})
+    run_cxx_module_test(exp-command-sepdir-install)
     run_cxx_module_test(exp-trans-targets-install)
-    run_cxx_module_test(exp-trans-mods1-install exp-trans-mods1-install ${export_cps})
-    run_cxx_module_test(exp-trans-mods-install exp-trans-mods-install "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/exp-trans-mods1-install-install" "-Dexport_transitive_modules1_cps_DIR=${RunCMake_BINARY_DIR}/exp-trans-mods1-install-install/lib/cmake/export_transitive_modules1_cps" ${export_cps} ${import_cps})
-    run_cxx_module_test(exp-with-headers-install exp-with-headers-install ${export_cps})
+    run_cxx_module_test(exp-trans-mods1-install)
+    run_cxx_module_test(exp-trans-mods-install exp-trans-mods-install "-DCMAKE_PREFIX_PATH=${RunCMake_BINARY_DIR}/exp-trans-mods1-install-install" "-Dexport_transitive_modules1_cps_DIR=${RunCMake_BINARY_DIR}/exp-trans-mods1-install-install/lib/cmake/export_transitive_modules1_cps")
+    run_cxx_module_test(exp-with-headers-install)
 
     if ("collation" IN_LIST CMake_TEST_MODULE_COMPILATION AND
         "bmionly" IN_LIST CMake_TEST_MODULE_COMPILATION)
diff --git a/Tests/RunCMake/CXXModulesCompile/depchain-mods-json-file-rebuild-check.cmake b/Tests/RunCMake/CXXModulesCompile/depchain-mods-json-file-rebuild-check.cmake
index 94e833a..4568873 100644
--- a/Tests/RunCMake/CXXModulesCompile/depchain-mods-json-file-rebuild-check.cmake
+++ b/Tests/RunCMake/CXXModulesCompile/depchain-mods-json-file-rebuild-check.cmake
@@ -1,12 +1,27 @@
-if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
-  set(dep_modules_json_path "CMakeFiles/depchain_modules_json_file.dir/Debug/CXX.dd")
-  set(modules_json_path "CMakeFiles/depchain_with_modules_json_file.dir/Debug/CXXModules.json")
-else ()
-  set(dep_modules_json_path "CMakeFiles/depchain_modules_json_file.dir/CXX.dd")
-  set(modules_json_path "CMakeFiles/depchain_with_modules_json_file.dir/CXXModules.json")
+file(GLOB synth_dirs
+  "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/depchain_with_modules_json_file@synth_*.dir")
+
+list(LENGTH synth_dirs synth_dirs_len)
+if (NOT synth_dirs_len EQUAL 1)
+  list(APPEND RunCMake_TEST_FAILED
+    "Expected exactly one synthetic target for consuming 'depchain_with_modules_json_file' but found ${synth_dirs_len}: ${synth_dirs}")
 endif ()
 
-if ("${RunCMake_TEST_BINARY_DIR}/${modules_json_path}" IS_NEWER_THAN "${RunCMake_TEST_BINARY_DIR}/${dep_modules_json_path}")
+list(GET synth_dirs 0 synth_dir)
+
+if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
+  set(dep_modules_json_path "CMakeFiles/depchain_modules_json_file.dir/Debug/CXX.dd")
+  set(modules_json_path "${synth_dir}/Debug/CXXModules.json")
+else ()
+  set(dep_modules_json_path "CMakeFiles/depchain_modules_json_file.dir/CXX.dd")
+  set(modules_json_path "${synth_dir}/CXXModules.json")
+endif ()
+
+
+if ("${modules_json_path}" IS_NEWER_THAN "${RunCMake_TEST_BINARY_DIR}/${dep_modules_json_path}")
+  cmake_path(RELATIVE_PATH modules_json_path
+    BASE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
   list(APPEND RunCMake_TEST_FAILED
     "Object '${dep_modules_json_path}' should have recompiled if '${modules_json_path}' changed.")
 endif ()
diff --git a/Tests/RunCMake/CXXModulesCompile/depchain-mods-json-file/pre-rebuild.cmake b/Tests/RunCMake/CXXModulesCompile/depchain-mods-json-file/pre-rebuild.cmake
index 9c3f2ff..2b2ce92 100644
--- a/Tests/RunCMake/CXXModulesCompile/depchain-mods-json-file/pre-rebuild.cmake
+++ b/Tests/RunCMake/CXXModulesCompile/depchain-mods-json-file/pre-rebuild.cmake
@@ -1,7 +1,17 @@
+file(GLOB synth_dirs
+  "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/depchain_with_modules_json_file@synth_*.dir")
+
+list(LENGTH synth_dirs synth_dirs_len)
+if (NOT synth_dirs_len EQUAL 1)
+  return()
+endif()
+
+list(GET synth_dirs 0 synth_dir)
+
 if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
-  set(modules_json_path "CMakeFiles/depchain_with_modules_json_file.dir/Debug/CXXModules.json")
+  set(modules_json_path "${synth_dir}/Debug/CXXModules.json")
 else ()
-  set(modules_json_path "CMakeFiles/depchain_with_modules_json_file.dir/CXXModules.json")
+  set(modules_json_path "${synth_dir}/CXXModules.json")
 endif ()
 
-file(TOUCH_NOCREATE "${RunCMake_TEST_BINARY_DIR}/${modules_json_path}")
+file(TOUCH_NOCREATE "${modules_json_path}")
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-build-stderr.txt b/Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-build-stderr.txt
deleted file mode 100644
index 4397b15..0000000
--- a/Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-build-stderr.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-CMake Warning \(dev\) at CMakeLists\.txt:[0-9]+ \(project\):
-  CMake's support for exporting package information in the Common Package
-  Specification format is experimental\.  It is meant only for experimentation
-  and feedback to CMake developers\.
-This warning is for project developers\.  Use -Wno-dev to suppress it
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-build/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-build/CMakeLists.txt
index 6a7a48b..2fe8960 100644
--- a/Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-build/CMakeLists.txt
+++ b/Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-build/CMakeLists.txt
@@ -36,7 +36,6 @@
     "-Dexpected_dir=${CMAKE_CURRENT_SOURCE_DIR}"
     "-Dexport_sepdir_DIR=${CMAKE_CURRENT_BINARY_DIR}"
     "-Dexport_sepdir_cps_DIR=${CMAKE_CURRENT_BINARY_DIR}"
-    "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES=e82e467b-f997-4464-8ace-b00808fff261"
     ${generator}
     -S "${CMAKE_CURRENT_SOURCE_DIR}/test"
     -B "${CMAKE_CURRENT_BINARY_DIR}/test")
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-install-stderr.txt b/Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-install-stderr.txt
deleted file mode 100644
index 4397b15..0000000
--- a/Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-install-stderr.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-CMake Warning \(dev\) at CMakeLists\.txt:[0-9]+ \(project\):
-  CMake's support for exporting package information in the Common Package
-  Specification format is experimental\.  It is meant only for experimentation
-  and feedback to CMake developers\.
-This warning is for project developers\.  Use -Wno-dev to suppress it
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-install/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-install/CMakeLists.txt
index f41720e..928be0b 100644
--- a/Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-install/CMakeLists.txt
+++ b/Tests/RunCMake/CXXModulesCompile/exp-command-sepdir-install/CMakeLists.txt
@@ -40,7 +40,6 @@
     "-Dexpected_dir=${CMAKE_INSTALL_PREFIX}/lib/cxx/miu"
     "-Dexport_sepdir_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/export_sepdir"
     "-Dexport_sepdir_cps_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/export_sepdir_cps"
-    "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES=e82e467b-f997-4464-8ace-b00808fff261"
     ${generator}
     -S "${CMAKE_CURRENT_SOURCE_DIR}/test"
     -B "${CMAKE_CURRENT_BINARY_DIR}/test")
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-iface-build-stderr.txt b/Tests/RunCMake/CXXModulesCompile/exp-iface-build-stderr.txt
deleted file mode 100644
index 4397b15..0000000
--- a/Tests/RunCMake/CXXModulesCompile/exp-iface-build-stderr.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-CMake Warning \(dev\) at CMakeLists\.txt:[0-9]+ \(project\):
-  CMake's support for exporting package information in the Common Package
-  Specification format is experimental\.  It is meant only for experimentation
-  and feedback to CMake developers\.
-This warning is for project developers\.  Use -Wno-dev to suppress it
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-iface-build/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-iface-build/CMakeLists.txt
index 3d21eff..80db2e9 100644
--- a/Tests/RunCMake/CXXModulesCompile/exp-iface-build/CMakeLists.txt
+++ b/Tests/RunCMake/CXXModulesCompile/exp-iface-build/CMakeLists.txt
@@ -58,7 +58,6 @@
     "-Dexpected_binary_dir=${CMAKE_CURRENT_BINARY_DIR}"
     "-Dexport_interfaces_DIR=${CMAKE_CURRENT_BINARY_DIR}"
     "-Dexport_interfaces_cps_DIR=${CMAKE_CURRENT_BINARY_DIR}"
-    "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES=e82e467b-f997-4464-8ace-b00808fff261"
     ${generator}
     -S "${CMAKE_CURRENT_SOURCE_DIR}/test"
     -B "${CMAKE_CURRENT_BINARY_DIR}/test")
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-iface-install-stderr.txt b/Tests/RunCMake/CXXModulesCompile/exp-iface-install-stderr.txt
deleted file mode 100644
index 4397b15..0000000
--- a/Tests/RunCMake/CXXModulesCompile/exp-iface-install-stderr.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-CMake Warning \(dev\) at CMakeLists\.txt:[0-9]+ \(project\):
-  CMake's support for exporting package information in the Common Package
-  Specification format is experimental\.  It is meant only for experimentation
-  and feedback to CMake developers\.
-This warning is for project developers\.  Use -Wno-dev to suppress it
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-iface-install/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-iface-install/CMakeLists.txt
index a48ce85..b31033b 100644
--- a/Tests/RunCMake/CXXModulesCompile/exp-iface-install/CMakeLists.txt
+++ b/Tests/RunCMake/CXXModulesCompile/exp-iface-install/CMakeLists.txt
@@ -62,7 +62,6 @@
     "-Dexpected_binary_dir=${CMAKE_INSTALL_PREFIX}/lib/cxx/bmi"
     "-Dexport_interfaces_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/export_interfaces"
     "-Dexport_interfaces_cps_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/export_interfaces_cps"
-    "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES=e82e467b-f997-4464-8ace-b00808fff261"
     ${generator}
     -S "${CMAKE_CURRENT_SOURCE_DIR}/test"
     -B "${CMAKE_CURRENT_BINARY_DIR}/test")
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-incdirs-build-stderr.txt b/Tests/RunCMake/CXXModulesCompile/exp-incdirs-build-stderr.txt
deleted file mode 100644
index 4397b15..0000000
--- a/Tests/RunCMake/CXXModulesCompile/exp-incdirs-build-stderr.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-CMake Warning \(dev\) at CMakeLists\.txt:[0-9]+ \(project\):
-  CMake's support for exporting package information in the Common Package
-  Specification format is experimental\.  It is meant only for experimentation
-  and feedback to CMake developers\.
-This warning is for project developers\.  Use -Wno-dev to suppress it
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-incdirs-build/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-incdirs-build/CMakeLists.txt
index 5caee96..a1607e4 100644
--- a/Tests/RunCMake/CXXModulesCompile/exp-incdirs-build/CMakeLists.txt
+++ b/Tests/RunCMake/CXXModulesCompile/exp-incdirs-build/CMakeLists.txt
@@ -64,7 +64,6 @@
     "-Dexpected_binary_dir=${CMAKE_CURRENT_BINARY_DIR}"
     "-Dexport_include_directories_DIR=${CMAKE_CURRENT_BINARY_DIR}"
     "-Dexport_include_directories_cps_DIR=${CMAKE_CURRENT_BINARY_DIR}"
-    "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES=e82e467b-f997-4464-8ace-b00808fff261"
     ${generator}
     -S "${CMAKE_CURRENT_SOURCE_DIR}/test"
     -B "${CMAKE_CURRENT_BINARY_DIR}/test")
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-incdirs-install-stderr.txt b/Tests/RunCMake/CXXModulesCompile/exp-incdirs-install-stderr.txt
deleted file mode 100644
index 4397b15..0000000
--- a/Tests/RunCMake/CXXModulesCompile/exp-incdirs-install-stderr.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-CMake Warning \(dev\) at CMakeLists\.txt:[0-9]+ \(project\):
-  CMake's support for exporting package information in the Common Package
-  Specification format is experimental\.  It is meant only for experimentation
-  and feedback to CMake developers\.
-This warning is for project developers\.  Use -Wno-dev to suppress it
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-incdirs-install/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-incdirs-install/CMakeLists.txt
index 7ce17c0..afda611 100644
--- a/Tests/RunCMake/CXXModulesCompile/exp-incdirs-install/CMakeLists.txt
+++ b/Tests/RunCMake/CXXModulesCompile/exp-incdirs-install/CMakeLists.txt
@@ -74,7 +74,6 @@
     "-Dexpected_binary_dir=${CMAKE_INSTALL_PREFIX}/lib/cxx/bmi"
     "-Dexport_include_directories_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/export_include_directories"
     "-Dexport_include_directories_cps_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/export_include_directories_cps"
-    "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES=e82e467b-f997-4464-8ace-b00808fff261"
     ${generator}
     -S "${CMAKE_CURRENT_SOURCE_DIR}/test"
     -B "${CMAKE_CURRENT_BINARY_DIR}/test")
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-trans-mods-build-stderr.txt b/Tests/RunCMake/CXXModulesCompile/exp-trans-mods-build-stderr.txt
deleted file mode 100644
index 4397b15..0000000
--- a/Tests/RunCMake/CXXModulesCompile/exp-trans-mods-build-stderr.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-CMake Warning \(dev\) at CMakeLists\.txt:[0-9]+ \(project\):
-  CMake's support for exporting package information in the Common Package
-  Specification format is experimental\.  It is meant only for experimentation
-  and feedback to CMake developers\.
-This warning is for project developers\.  Use -Wno-dev to suppress it
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-trans-mods-build/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-trans-mods-build/CMakeLists.txt
index 99fecc8..8a87e7a 100644
--- a/Tests/RunCMake/CXXModulesCompile/exp-trans-mods-build/CMakeLists.txt
+++ b/Tests/RunCMake/CXXModulesCompile/exp-trans-mods-build/CMakeLists.txt
@@ -71,7 +71,6 @@
     "-Dexport_transitive_modules_DIR=${CMAKE_CURRENT_BINARY_DIR}"
     "-Dexport_transitive_modules1_cps_DIR=${CMAKE_PREFIX_PATH}"
     "-Dexport_transitive_modules_cps_DIR=${CMAKE_CURRENT_BINARY_DIR}"
-    "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES=e82e467b-f997-4464-8ace-b00808fff261"
     ${generator}
     -S "${CMAKE_CURRENT_SOURCE_DIR}/test"
     -B "${CMAKE_CURRENT_BINARY_DIR}/test")
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-trans-mods-install-stderr.txt b/Tests/RunCMake/CXXModulesCompile/exp-trans-mods-install-stderr.txt
deleted file mode 100644
index 4397b15..0000000
--- a/Tests/RunCMake/CXXModulesCompile/exp-trans-mods-install-stderr.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-CMake Warning \(dev\) at CMakeLists\.txt:[0-9]+ \(project\):
-  CMake's support for exporting package information in the Common Package
-  Specification format is experimental\.  It is meant only for experimentation
-  and feedback to CMake developers\.
-This warning is for project developers\.  Use -Wno-dev to suppress it
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-trans-mods-install/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-trans-mods-install/CMakeLists.txt
index d909125..bed56a0 100644
--- a/Tests/RunCMake/CXXModulesCompile/exp-trans-mods-install/CMakeLists.txt
+++ b/Tests/RunCMake/CXXModulesCompile/exp-trans-mods-install/CMakeLists.txt
@@ -75,7 +75,6 @@
     "-Dexport_transitive_modules_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/export_transitive_modules"
     "-Dexport_transitive_modules1_cps_DIR=${CMAKE_PREFIX_PATH}/lib/cmake/export_transitive_modules1_cps"
     "-Dexport_transitive_modules_cps_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/export_transitive_modules_cps"
-    "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES=e82e467b-f997-4464-8ace-b00808fff261"
     ${generator}
     -S "${CMAKE_CURRENT_SOURCE_DIR}/test"
     -B "${CMAKE_CURRENT_BINARY_DIR}/test")
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-build-stderr.txt b/Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-build-stderr.txt
deleted file mode 100644
index 4397b15..0000000
--- a/Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-build-stderr.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-CMake Warning \(dev\) at CMakeLists\.txt:[0-9]+ \(project\):
-  CMake's support for exporting package information in the Common Package
-  Specification format is experimental\.  It is meant only for experimentation
-  and feedback to CMake developers\.
-This warning is for project developers\.  Use -Wno-dev to suppress it
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-build/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-build/CMakeLists.txt
index bba1a4f..530c61e 100644
--- a/Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-build/CMakeLists.txt
+++ b/Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-build/CMakeLists.txt
@@ -47,7 +47,6 @@
     "-Dexpected_binary_dir=${CMAKE_CURRENT_BINARY_DIR}"
     "-Dexport_transitive_modules1_DIR=${CMAKE_CURRENT_BINARY_DIR}"
     "-Dexport_transitive_modules1_cps_DIR=${CMAKE_CURRENT_BINARY_DIR}"
-    "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES=e82e467b-f997-4464-8ace-b00808fff261"
     ${generator}
     -S "${CMAKE_CURRENT_SOURCE_DIR}/test"
     -B "${CMAKE_CURRENT_BINARY_DIR}/test")
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-install-stderr.txt b/Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-install-stderr.txt
deleted file mode 100644
index 4397b15..0000000
--- a/Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-install-stderr.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-CMake Warning \(dev\) at CMakeLists\.txt:[0-9]+ \(project\):
-  CMake's support for exporting package information in the Common Package
-  Specification format is experimental\.  It is meant only for experimentation
-  and feedback to CMake developers\.
-This warning is for project developers\.  Use -Wno-dev to suppress it
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-install/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-install/CMakeLists.txt
index 2c44f7b..dd37577 100644
--- a/Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-install/CMakeLists.txt
+++ b/Tests/RunCMake/CXXModulesCompile/exp-trans-mods1-install/CMakeLists.txt
@@ -51,7 +51,6 @@
     "-Dexpected_binary_dir=${CMAKE_INSTALL_PREFIX}/lib/cxx/bmi"
     "-Dexport_transitive_modules1_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/export_transitive_modules1"
     "-Dexport_transitive_modules1_cps_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/export_transitive_modules1_cps"
-    "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES=e82e467b-f997-4464-8ace-b00808fff261"
     ${generator}
     -S "${CMAKE_CURRENT_SOURCE_DIR}/test"
     -B "${CMAKE_CURRENT_BINARY_DIR}/test")
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-with-headers-build-stderr.txt b/Tests/RunCMake/CXXModulesCompile/exp-with-headers-build-stderr.txt
deleted file mode 100644
index 4397b15..0000000
--- a/Tests/RunCMake/CXXModulesCompile/exp-with-headers-build-stderr.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-CMake Warning \(dev\) at CMakeLists\.txt:[0-9]+ \(project\):
-  CMake's support for exporting package information in the Common Package
-  Specification format is experimental\.  It is meant only for experimentation
-  and feedback to CMake developers\.
-This warning is for project developers\.  Use -Wno-dev to suppress it
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-with-headers-build/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-with-headers-build/CMakeLists.txt
index e189c0b..8672cb8 100644
--- a/Tests/RunCMake/CXXModulesCompile/exp-with-headers-build/CMakeLists.txt
+++ b/Tests/RunCMake/CXXModulesCompile/exp-with-headers-build/CMakeLists.txt
@@ -48,7 +48,6 @@
     "${CMAKE_COMMAND}"
     "-Dexport_with_headers_DIR=${CMAKE_CURRENT_BINARY_DIR}"
     "-Dexport_with_headers_cps_DIR=${CMAKE_CURRENT_BINARY_DIR}"
-    "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES=e82e467b-f997-4464-8ace-b00808fff261"
     ${generator}
     -S "${CMAKE_CURRENT_SOURCE_DIR}/test"
     -B "${CMAKE_CURRENT_BINARY_DIR}/test")
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-with-headers-install-stderr.txt b/Tests/RunCMake/CXXModulesCompile/exp-with-headers-install-stderr.txt
deleted file mode 100644
index 4397b15..0000000
--- a/Tests/RunCMake/CXXModulesCompile/exp-with-headers-install-stderr.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-CMake Warning \(dev\) at CMakeLists\.txt:[0-9]+ \(project\):
-  CMake's support for exporting package information in the Common Package
-  Specification format is experimental\.  It is meant only for experimentation
-  and feedback to CMake developers\.
-This warning is for project developers\.  Use -Wno-dev to suppress it
diff --git a/Tests/RunCMake/CXXModulesCompile/exp-with-headers-install/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/exp-with-headers-install/CMakeLists.txt
index a3ded85..2932501 100644
--- a/Tests/RunCMake/CXXModulesCompile/exp-with-headers-install/CMakeLists.txt
+++ b/Tests/RunCMake/CXXModulesCompile/exp-with-headers-install/CMakeLists.txt
@@ -51,7 +51,6 @@
     "${CMAKE_COMMAND}"
     "-Dexport_with_headers_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/export_with_headers"
     "-Dexport_with_headers_cps_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/export_with_headers_cps"
-    "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES=e82e467b-f997-4464-8ace-b00808fff261"
     ${generator}
     -S "${CMAKE_CURRENT_SOURCE_DIR}/test"
     -B "${CMAKE_CURRENT_BINARY_DIR}/test")
diff --git a/Tests/RunCMake/CXXModulesCompile/library/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/library/CMakeLists.txt
index 97d2325..d611029 100644
--- a/Tests/RunCMake/CXXModulesCompile/library/CMakeLists.txt
+++ b/Tests/RunCMake/CXXModulesCompile/library/CMakeLists.txt
@@ -18,7 +18,9 @@
       BASE_DIRS
         "${CMAKE_CURRENT_SOURCE_DIR}"
       FILES
-        importable.cxx)
+        importable.ixx
+  PRIVATE
+    importable.cxx)
 target_compile_features(library PUBLIC cxx_std_20)
 
 add_executable(exe)
diff --git a/Tests/RunCMake/CXXModulesCompile/library/importable.cxx b/Tests/RunCMake/CXXModulesCompile/library/importable.cxx
index 72ed0df..859fa3d 100644
--- a/Tests/RunCMake/CXXModulesCompile/library/importable.cxx
+++ b/Tests/RunCMake/CXXModulesCompile/library/importable.cxx
@@ -1,8 +1,6 @@
-export module importable;
+module importable;
 
-#include "library_export.h"
-
-export LIBRARY_EXPORT int from_import()
+int from_import()
 {
   return 0;
 }
diff --git a/Tests/RunCMake/CXXModulesCompile/library/importable.ixx b/Tests/RunCMake/CXXModulesCompile/library/importable.ixx
new file mode 100644
index 0000000..d3fb7f6
--- /dev/null
+++ b/Tests/RunCMake/CXXModulesCompile/library/importable.ixx
@@ -0,0 +1,5 @@
+export module importable;
+
+#include "library_export.h"
+
+export LIBRARY_EXPORT int from_import();
diff --git a/Tests/RunCMake/CXXModulesCompile/mixed-bmi-compatibility-build-check.cmake b/Tests/RunCMake/CXXModulesCompile/mixed-bmi-compatibility-build-check.cmake
new file mode 100644
index 0000000..a53b3ca
--- /dev/null
+++ b/Tests/RunCMake/CXXModulesCompile/mixed-bmi-compatibility-build-check.cmake
@@ -0,0 +1,111 @@
+# Verify the build system generated a synthetic target/BMI for each unique importer
+set(expected_consumers consumer20 consumer23)
+set(linked_dir_keys "")
+set(linked_dir_names "")
+
+if (DEFINED RunCMake_TEST_CONFIG)
+  set(config_dir "${RunCMake_TEST_CONFIG}")
+else ()
+  set(config_dir "Debug")
+endif ()
+
+# Get and check linked-target-dirs for each consumer
+foreach (consumer IN LISTS expected_consumers)
+
+  if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
+    set(output_dir "${consumer}.dir/${config_dir}")
+  else ()
+    set(output_dir "${consumer}.dir")
+  endif ()
+
+  set(depend_info_file "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/${output_dir}/CXXDependInfo.json")
+  if (NOT EXISTS "${depend_info_file}")
+    list(APPEND RunCMake_TEST_FAILED
+      "Could not find CXXDependInfo.json for consumer ${consumer}: checked ${depend_info_file}")
+    continue()
+  endif ()
+
+  file(READ "${depend_info_file}" depend_info_json)
+
+  # Extract linked-target-dirs array length and first element
+  string(JSON linked_dirs_len LENGTH "${depend_info_json}" "linked-target-dirs")
+  string(JSON linked_dirs GET "${depend_info_json}" "linked-target-dirs")
+
+  if (NOT linked_dirs_len GREATER 0)
+    list(APPEND RunCMake_TEST_FAILED
+      "Consumer '${consumer}' has no linked-target-dirs but expected synthetic target for 'importable'")
+    continue()
+  endif ()
+
+  # For this test, expect exactly one linked target dir per consumer
+  if (NOT linked_dirs_len EQUAL 1)
+    list(APPEND RunCMake_TEST_FAILED
+      "Expected 1 linked-target-dir for '${consumer}' but found ${linked_dirs_len}: ${linked_dirs}")
+    continue()
+  endif ()
+
+  string(JSON linked_dir GET "${depend_info_json}" "linked-target-dirs" 0)
+
+  if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
+    cmake_path(GET linked_dir PARENT_PATH linked_tgt_root)
+  else ()
+    set(linked_tgt_root "${linked_dir}")
+  endif ()
+
+  cmake_path(GET linked_tgt_root FILENAME linked_tgt_name)
+
+  # Verify it is a synthetic target for the 'importable' library
+  if (NOT linked_tgt_name MATCHES "^importable@synth_[A-Za-z0-9_]+\.dir$")
+    list(APPEND RunCMake_TEST_FAILED
+      "Consumer '${consumer}' should link to synthetic target dir for 'importable' but found ${linked_dir}")
+    continue()
+  endif ()
+
+  if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
+    set(linked_output_dir "${linked_dir}/${config_dir}")
+  else ()
+    set(linked_output_dir "${linked_dir}")
+  endif ()
+
+  # Verify the synthetic target dir exists and contains a BMI
+  if (NOT EXISTS "${linked_dir}")
+    list(APPEND RunCMake_TEST_FAILED
+      "Consumer '${consumer}' links to synthetic target directory that does not exist: ${linked_dir}")
+    continue()
+  endif ()
+
+  file(GLOB_RECURSE bmi_files "${linked_dir}/*.bmi")
+  if (NOT bmi_files)
+    list(APPEND RunCMake_TEST_FAILED
+      "No BMI files found in synthetic target directory: ${linked_dir}")
+    continue()
+  endif ()
+
+  # Record the consumers of each linked dir to verify uniqueness
+  string(REGEX REPLACE "[^A-Za-z0-9_]" "_" linked_dir_key "${linked_tgt_name}")
+  set(linked_dir_consumers_var "linked_dir_consumers_${linked_dir_key}")
+  if (NOT DEFINED ${linked_dir_consumers_var})
+    list(APPEND linked_dir_keys "${linked_dir_key}")
+    list(APPEND linked_dir_names "${linked_tgt_name}")
+  endif ()
+
+  list(APPEND ${linked_dir_consumers_var} ${consumer})
+
+endforeach ()
+
+# Verify each synthetic target is consumed exactly once
+foreach (linked_dir_key IN LISTS linked_dir_keys)
+  set(consumers "${linked_dir_consumers_${linked_dir_key}}")
+  list(LENGTH consumers linked_dir_consumer_count)
+
+  if (linked_dir_consumer_count GREATER 1)
+    list(FIND linked_dir_keys ${linked_dir_key} linked_dir_index)
+    list(GET linked_dir_names ${linked_dir_index} linked_tgt_name)
+
+    string(JOIN ", " linked_dir_consumers_joined ${consumers})
+    list(APPEND RunCMake_TEST_FAILED
+      "Expected per-importer BMI generation, but '${linked_tgt_name}' is linked to by multiple targets: ${linked_dir_consumers_joined}")
+  endif ()
+endforeach ()
+
+string(REPLACE ";" "\n  " RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}")
diff --git a/Tests/RunCMake/CXXModulesCompile/mixed-bmi-compatibility/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/mixed-bmi-compatibility/CMakeLists.txt
new file mode 100644
index 0000000..4af50c8
--- /dev/null
+++ b/Tests/RunCMake/CXXModulesCompile/mixed-bmi-compatibility/CMakeLists.txt
@@ -0,0 +1,21 @@
+cmake_minimum_required(VERSION 3.24...3.28)
+project(cxx_modules_mixed_bmi_compatibility CXX)
+
+include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
+
+add_library(importable)
+target_sources(importable
+  PUBLIC FILE_SET CXX_MODULES FILES importable.cxx)
+
+target_compile_features(importable PUBLIC cxx_std_20)
+
+add_executable(consumer20 consumer20.cxx)
+target_compile_features(consumer20 PRIVATE cxx_std_20)
+target_link_libraries(consumer20 PRIVATE importable)
+
+add_executable(consumer23 consumer23.cxx)
+target_compile_features(consumer23 PRIVATE cxx_std_23)
+target_link_libraries(consumer23 PRIVATE importable)
+
+add_test(NAME consumer20 COMMAND consumer20)
+add_test(NAME consumer23 COMMAND consumer23)
diff --git a/Tests/RunCMake/CXXModulesCompile/mixed-bmi-compatibility/consumer20.cxx b/Tests/RunCMake/CXXModulesCompile/mixed-bmi-compatibility/consumer20.cxx
new file mode 100644
index 0000000..5f0bbbc
--- /dev/null
+++ b/Tests/RunCMake/CXXModulesCompile/mixed-bmi-compatibility/consumer20.cxx
@@ -0,0 +1,9 @@
+#include <iostream>
+
+import importable;
+
+int main()
+{
+  std::cout << "from_import() = " << from_import() << '\n';
+  return 0;
+}
diff --git a/Tests/RunCMake/CXXModulesCompile/mixed-bmi-compatibility/consumer23.cxx b/Tests/RunCMake/CXXModulesCompile/mixed-bmi-compatibility/consumer23.cxx
new file mode 100644
index 0000000..e36852b
--- /dev/null
+++ b/Tests/RunCMake/CXXModulesCompile/mixed-bmi-compatibility/consumer23.cxx
@@ -0,0 +1,9 @@
+#include <print>
+
+import importable;
+
+int main()
+{
+  std::println("from_import() = {}", from_import());
+  return 0;
+}
diff --git a/Tests/RunCMake/CXXModulesCompile/mixed-bmi-compatibility/importable.cxx b/Tests/RunCMake/CXXModulesCompile/mixed-bmi-compatibility/importable.cxx
new file mode 100644
index 0000000..607680a
--- /dev/null
+++ b/Tests/RunCMake/CXXModulesCompile/mixed-bmi-compatibility/importable.cxx
@@ -0,0 +1,6 @@
+export module importable;
+
+export int from_import()
+{
+  return 0;
+}
diff --git a/Tests/RunCMake/CXXModulesCompile/shared-library-symbol-visibility/CMakeLists.txt b/Tests/RunCMake/CXXModulesCompile/shared-library-symbol-visibility/CMakeLists.txt
new file mode 100644
index 0000000..7f3d290
--- /dev/null
+++ b/Tests/RunCMake/CXXModulesCompile/shared-library-symbol-visibility/CMakeLists.txt
@@ -0,0 +1,33 @@
+cmake_minimum_required(VERSION 3.24...3.28)
+project(cxx_modules_library CXX)
+
+include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
+
+include(GenerateExportHeader)
+
+add_library(library SHARED)
+generate_export_header(library)
+target_sources(library
+  PUBLIC
+    FILE_SET HEADERS
+      BASE_DIRS
+        "${CMAKE_CURRENT_BINARY_DIR}"
+      FILES
+        "${CMAKE_CURRENT_BINARY_DIR}/library_export.h"
+    FILE_SET CXX_MODULES
+      BASE_DIRS
+        "${CMAKE_CURRENT_SOURCE_DIR}"
+      FILES
+        importable.ixx
+  PRIVATE
+    importable.cxx)
+target_compile_features(library PUBLIC cxx_std_20)
+target_compile_definitions(library INTERFACE CHECK_IMPORT_INTERFACE)
+
+add_executable(exe)
+target_link_libraries(exe PRIVATE library)
+target_sources(exe
+  PRIVATE
+    main.cxx)
+
+add_test(NAME exe COMMAND exe)
diff --git a/Tests/RunCMake/CXXModulesCompile/shared-library-symbol-visibility/importable.cxx b/Tests/RunCMake/CXXModulesCompile/shared-library-symbol-visibility/importable.cxx
new file mode 100644
index 0000000..859fa3d
--- /dev/null
+++ b/Tests/RunCMake/CXXModulesCompile/shared-library-symbol-visibility/importable.cxx
@@ -0,0 +1,6 @@
+module importable;
+
+int from_import()
+{
+  return 0;
+}
diff --git a/Tests/RunCMake/CXXModulesCompile/shared-library-symbol-visibility/importable.ixx b/Tests/RunCMake/CXXModulesCompile/shared-library-symbol-visibility/importable.ixx
new file mode 100644
index 0000000..dd5fa68
--- /dev/null
+++ b/Tests/RunCMake/CXXModulesCompile/shared-library-symbol-visibility/importable.ixx
@@ -0,0 +1,15 @@
+export module importable;
+
+#include "library_export.h"
+
+#ifdef CHECK_IMPORT_INTERFACE
+#  ifdef library_EXPORTS
+#    error "library_EXPORTS defined but should NOT be defined when importing module"
+#  endif
+#else
+#  ifndef library_EXPORTS
+#    error "library_EXPORTS NOT defined but should be defined when building module"
+#  endif
+#endif
+
+export LIBRARY_EXPORT int from_import();
diff --git a/Tests/RunCMake/CXXModulesCompile/shared-library-symbol-visibility/main.cxx b/Tests/RunCMake/CXXModulesCompile/shared-library-symbol-visibility/main.cxx
new file mode 100644
index 0000000..feb38d2
--- /dev/null
+++ b/Tests/RunCMake/CXXModulesCompile/shared-library-symbol-visibility/main.cxx
@@ -0,0 +1,6 @@
+import importable;
+
+int main(int argc, char* argv[])
+{
+  return from_import();
+}
diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
index f42709c..b54a01a 100644
--- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
@@ -837,7 +837,7 @@
 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}/empty_file.txt" "")
-file(WRITE "${out}/unicode_file.txt" "àéùç - 한국어") # Korean in Korean
+file(WRITE "${out}/unicode_file.txt" "àéùç - 한국어") # UTF-8: Korean in Korean
 run_cmake_command(E_cat_good_cat
   ${CMAKE_COMMAND} -E cat "${out}/first_file.txt" "${out}/second_file.txt" "${out}/empty_file.txt" "${out}/unicode_file.txt")
 
diff --git a/Tests/RunCMake/CpsExportImportBuild/RunCMakeTest.cmake b/Tests/RunCMake/CpsExportImportBuild/RunCMakeTest.cmake
index c69ebbd..d0c460d 100644
--- a/Tests/RunCMake/CpsExportImportBuild/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CpsExportImportBuild/RunCMakeTest.cmake
@@ -1,11 +1,5 @@
 include(RunCMake)
 
-set(RunCMake_TEST_OPTIONS
-  -Wno-dev
-  "-DCMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO:STRING=7fa7d13b-8308-4dc7-af39-9e450456d68f"
-  "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES:STRING=e82e467b-f997-4464-8ace-b00808fff261"
-  )
-
 function(build_project test)
   set(RunCMake_TEST_NO_CLEAN FALSE)
   set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build)
diff --git a/Tests/RunCMake/CpsExportImportInstall/RunCMakeTest.cmake b/Tests/RunCMake/CpsExportImportInstall/RunCMakeTest.cmake
index 31d503b..bdc5e34 100644
--- a/Tests/RunCMake/CpsExportImportInstall/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CpsExportImportInstall/RunCMakeTest.cmake
@@ -1,11 +1,5 @@
 include(RunCMake)
 
-set(RunCMake_TEST_OPTIONS
-  -Wno-dev
-  "-DCMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO:STRING=7fa7d13b-8308-4dc7-af39-9e450456d68f"
-  "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES:STRING=e82e467b-f997-4464-8ace-b00808fff261"
-  )
-
 function(build_project test)
   set(RunCMake_TEST_NO_CLEAN FALSE)
   set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build)
diff --git a/Tests/RunCMake/CpsMapConfig/RunCMakeTest.cmake b/Tests/RunCMake/CpsMapConfig/RunCMakeTest.cmake
index cd0cd2d..0a381d6 100644
--- a/Tests/RunCMake/CpsMapConfig/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CpsMapConfig/RunCMakeTest.cmake
@@ -1,10 +1,5 @@
 include(RunCMake)
 
-set(RunCMake_TEST_OPTIONS
-  -Wno-dev
-  "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES:STRING=e82e467b-f997-4464-8ace-b00808fff261"
-  )
-
 function(build_project test)
   set(RunCMake_TEST_NO_CLEAN FALSE)
   set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build)
diff --git a/Tests/RunCMake/DependencyProviders/RedirectFetchContentSerial-stderr.txt b/Tests/RunCMake/DependencyProviders/RedirectFetchContentSerial-stderr.txt
index 047a64b..c168e07 100644
--- a/Tests/RunCMake/DependencyProviders/RedirectFetchContentSerial-stderr.txt
+++ b/Tests/RunCMake/DependencyProviders/RedirectFetchContentSerial-stderr.txt
@@ -2,6 +2,8 @@
   Could not find a package configuration file provided by "SomeDep" with any
   of the following names:
 
+    SomeDep\.cps
+    somedep\.cps
     SomeDepConfig\.cmake
     somedep-config\.cmake
 
diff --git a/Tests/RunCMake/EnvSbom/RunCMakeTest.cmake b/Tests/RunCMake/EnvSbom/RunCMakeTest.cmake
index f350661..f72942d 100644
--- a/Tests/RunCMake/EnvSbom/RunCMakeTest.cmake
+++ b/Tests/RunCMake/EnvSbom/RunCMakeTest.cmake
@@ -3,8 +3,6 @@
 set(common_test_options
   -Wno-dev
   "-DCMAKE_EXPERIMENTAL_GENERATE_SBOM:STRING=ca494ed3-b261-4205-a01f-603c95e4cae0"
-  "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES:STRING=e82e467b-f997-4464-8ace-b00808fff261"
-  "-DCMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO:STRING=7fa7d13b-8308-4dc7-af39-9e450456d68f"
   "-DCMAKE_INSTALL_SBOM_FORMATS:STRING=JSON"
   "-DCMAKE_INSTALL_LIBDIR=lib"
 )
diff --git a/Tests/RunCMake/ExportPackageInfo/ExperimentalGate-result.txt b/Tests/RunCMake/ExportPackageInfo/ExperimentalGate-result.txt
deleted file mode 100644
index d00491f..0000000
--- a/Tests/RunCMake/ExportPackageInfo/ExperimentalGate-result.txt
+++ /dev/null
@@ -1 +0,0 @@
-1
diff --git a/Tests/RunCMake/ExportPackageInfo/ExperimentalGate-stderr.txt b/Tests/RunCMake/ExportPackageInfo/ExperimentalGate-stderr.txt
deleted file mode 100644
index b0d7bc9..0000000
--- a/Tests/RunCMake/ExportPackageInfo/ExperimentalGate-stderr.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-CMake Error at ExperimentalGate\.cmake:5 \(export\):
-  export does not recognize sub-command PACKAGE_INFO
diff --git a/Tests/RunCMake/ExportPackageInfo/ExperimentalGate.cmake b/Tests/RunCMake/ExportPackageInfo/ExperimentalGate.cmake
deleted file mode 100644
index 96b19cd..0000000
--- a/Tests/RunCMake/ExportPackageInfo/ExperimentalGate.cmake
+++ /dev/null
@@ -1,5 +0,0 @@
-unset(CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO)
-
-add_library(foo INTERFACE)
-install(TARGETS foo EXPORT foo DESTINATION .)
-export(PACKAGE_INFO foo EXPORT foo)
diff --git a/Tests/RunCMake/ExportPackageInfo/ExperimentalWarning-stderr.txt b/Tests/RunCMake/ExportPackageInfo/ExperimentalWarning-stderr.txt
deleted file mode 100644
index d81b375..0000000
--- a/Tests/RunCMake/ExportPackageInfo/ExperimentalWarning-stderr.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-CMake Warning \(dev\) at ExperimentalWarning\.cmake:8 \(export\):
-  CMake's support for exporting package information in the Common Package
-  Specification format is experimental\.  It is meant only for experimentation
-  and feedback to CMake developers\.
-Call Stack \(most recent call first\):
-  CMakeLists\.txt:3 \(include\)
-This warning is for project developers\.  Use -Wno-dev to suppress it\.
diff --git a/Tests/RunCMake/ExportPackageInfo/ExperimentalWarning.cmake b/Tests/RunCMake/ExportPackageInfo/ExperimentalWarning.cmake
deleted file mode 100644
index f994893..0000000
--- a/Tests/RunCMake/ExportPackageInfo/ExperimentalWarning.cmake
+++ /dev/null
@@ -1,8 +0,0 @@
-set(
-  CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO
-  "7fa7d13b-8308-4dc7-af39-9e450456d68f"
-  )
-
-add_library(foo INTERFACE)
-install(TARGETS foo EXPORT foo DESTINATION .)
-export(PACKAGE_INFO foo EXPORT foo)
diff --git a/Tests/RunCMake/ExportPackageInfo/LinkDependentLibraries-check.cmake b/Tests/RunCMake/ExportPackageInfo/LinkDependentLibraries-check.cmake
new file mode 100644
index 0000000..19eb3f1
--- /dev/null
+++ b/Tests/RunCMake/ExportPackageInfo/LinkDependentLibraries-check.cmake
@@ -0,0 +1,15 @@
+include(${CMAKE_CURRENT_LIST_DIR}/Assertions.cmake)
+
+set(out_dir "${RunCMake_BINARY_DIR}/LinkDependentLibraries-build")
+
+file(READ "${out_dir}/dyld.cps" content)
+expect_value("${content}" "dyld" "name")
+expect_value("${content}" "dylib" "components" "private" "type")
+expect_value("${content}" "dylib" "components" "public" "type")
+
+expect_array(
+  "${content}" 1
+  "components" "public" "configurations" "generic" "dyld_requires")
+expect_value(
+  "${content}" ":private"
+  "components" "public" "configurations" "generic" "dyld_requires" 0)
diff --git a/Tests/RunCMake/ExportPackageInfo/LinkDependentLibraries.cmake b/Tests/RunCMake/ExportPackageInfo/LinkDependentLibraries.cmake
new file mode 100644
index 0000000..1867ae6
--- /dev/null
+++ b/Tests/RunCMake/ExportPackageInfo/LinkDependentLibraries.cmake
@@ -0,0 +1,16 @@
+project(dyld CXX)
+
+get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+if(_isMultiConfig)
+  set(CMAKE_CONFIGURATION_TYPES "generic" CACHE STRING "" FORCE)
+else()
+  set(CMAKE_BUILD_TYPE "generic" CACHE STRING "" FORCE)
+endif()
+
+add_library(private SHARED foo.cxx)
+add_library(public SHARED foo.cxx)
+
+target_link_libraries(public PRIVATE private)
+
+install(TARGETS private public EXPORT dyld DESTINATION .)
+export(PACKAGE_INFO dyld EXPORT dyld)
diff --git a/Tests/RunCMake/ExportPackageInfo/RunCMakeTest.cmake b/Tests/RunCMake/ExportPackageInfo/RunCMakeTest.cmake
index 3454a69..e2582cf 100644
--- a/Tests/RunCMake/ExportPackageInfo/RunCMakeTest.cmake
+++ b/Tests/RunCMake/ExportPackageInfo/RunCMakeTest.cmake
@@ -1,20 +1,5 @@
 include(RunCMake)
 
-# Test experimental gate
-run_cmake(ExperimentalGate)
-run_cmake(ExperimentalWarning)
-
-# Test version check author warning
-# TODO Move to be with other tests when experimental gate is removed.
-run_cmake(VersionCheckWarning)
-
-# Enable experimental feature and suppress warnings
-set(RunCMake_TEST_OPTIONS
-  -Wno-dev
-  "-DCMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO:STRING=7fa7d13b-8308-4dc7-af39-9e450456d68f"
-  "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES:STRING=e82e467b-f997-4464-8ace-b00808fff261"
-  )
-
 # Test incorrect usage
 run_cmake(BadArgs0)
 run_cmake(BadArgs1)
@@ -43,6 +28,7 @@
 run_cmake(MinimalVersion)
 run_cmake(LowerCaseFile)
 run_cmake(Requirements)
+run_cmake(LinkDependentLibraries)
 run_cmake(ExportSymbolicComponent)
 run_cmake(TargetTypes)
 run_cmake(DependsMultiple)
@@ -55,5 +41,5 @@
 run_cmake(DependencyVersionCps)
 run_cmake(TransitiveSymbolicComponent)
 run_cmake(VersionCheck)
-# run_cmake(VersionCheckWarning)
+run_cmake(VersionCheckWarning)
 run_cmake(VersionCheckError)
diff --git a/Tests/RunCMake/ExportPackageInfo/VersionCheckWarning.cmake b/Tests/RunCMake/ExportPackageInfo/VersionCheckWarning.cmake
index 4bb2d11..b87f282 100644
--- a/Tests/RunCMake/ExportPackageInfo/VersionCheckWarning.cmake
+++ b/Tests/RunCMake/ExportPackageInfo/VersionCheckWarning.cmake
@@ -1,8 +1,3 @@
-set(
-  CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO
-  "7fa7d13b-8308-4dc7-af39-9e450456d68f"
-)
-
 add_library(foo INTERFACE)
 install(TARGETS foo EXPORT foo DESTINATION .)
 
diff --git a/Tests/RunCMake/ExportSbom/RunCMakeTest.cmake b/Tests/RunCMake/ExportSbom/RunCMakeTest.cmake
index 1d81ee6..5e09f91 100644
--- a/Tests/RunCMake/ExportSbom/RunCMakeTest.cmake
+++ b/Tests/RunCMake/ExportSbom/RunCMakeTest.cmake
@@ -3,8 +3,6 @@
 set(common_test_options
   -Wno-dev
   "-DCMAKE_EXPERIMENTAL_GENERATE_SBOM:STRING=ca494ed3-b261-4205-a01f-603c95e4cae0"
-  "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES:STRING=e82e467b-f997-4464-8ace-b00808fff261"
-  "-DCMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO:STRING=7fa7d13b-8308-4dc7-af39-9e450456d68f"
 )
 
 function(run_cmake_install test)
diff --git a/Tests/RunCMake/FASTBuild/RunCMakeTest.cmake b/Tests/RunCMake/FASTBuild/RunCMakeTest.cmake
index 57f74a2..87b9048 100644
--- a/Tests/RunCMake/FASTBuild/RunCMakeTest.cmake
+++ b/Tests/RunCMake/FASTBuild/RunCMakeTest.cmake
@@ -6,6 +6,8 @@
 run_cmake(UnityBatchSize)
 run_cmake(UnityGroup)
 run_cmake(UnityIsolate)
+run_cmake(UnitySubdirs)
+run_cmake(UnitySubdirsIsolate)
 run_cmake(DisableCaching)
 run_cmake(DisableDistribution)
 run_cmake(SetCompilerProps)
diff --git a/Tests/RunCMake/FASTBuild/UnitySubdirs-check.cmake b/Tests/RunCMake/FASTBuild/UnitySubdirs-check.cmake
new file mode 100644
index 0000000..a249da3
--- /dev/null
+++ b/Tests/RunCMake/FASTBuild/UnitySubdirs-check.cmake
@@ -0,0 +1,23 @@
+# Verify that files from different subdirectories are combined into a single Unity node.
+
+set(REGEX_TO_MATCH "
+  Unity\\('main_Unity_1'\\)
+  {
+    \\.UnityOutputPath = 'CMakeFiles/main.dir'
+    \\.UnityOutputPattern = 'main_Unity_1.cpp'
+    \\.UnityInputFiles =
+    {
+      .*main.cpp',
+      .*subdir1/file1.cpp',
+      .*subdir2/file2.cpp'
+    }
+  }
+.*ObjectList.*
+.*
+    .CompilerInputUnity =
+    {
+      'main_Unity_1'
+    }
+")
+
+include(${RunCMake_SOURCE_DIR}/check.cmake)
diff --git a/Tests/RunCMake/FASTBuild/UnitySubdirs.cmake b/Tests/RunCMake/FASTBuild/UnitySubdirs.cmake
new file mode 100644
index 0000000..a2d50fa
--- /dev/null
+++ b/Tests/RunCMake/FASTBuild/UnitySubdirs.cmake
@@ -0,0 +1,16 @@
+# Test that unity build combines files from different subdirectories into the same unity bucket.
+
+set(CMAKE_UNITY_BUILD ON)
+
+file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/subdir1)
+file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/subdir2)
+
+file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/main.cpp "int main() { return 0; }\n")
+file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/subdir1/file1.cpp "int file1() { return 1; }\n")
+file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/subdir2/file2.cpp "int file2() { return 2; }\n")
+
+add_executable(main
+    ${CMAKE_CURRENT_BINARY_DIR}/main.cpp
+    ${CMAKE_CURRENT_BINARY_DIR}/subdir1/file1.cpp
+    ${CMAKE_CURRENT_BINARY_DIR}/subdir2/file2.cpp
+)
diff --git a/Tests/RunCMake/FASTBuild/UnitySubdirsIsolate-check.cmake b/Tests/RunCMake/FASTBuild/UnitySubdirsIsolate-check.cmake
new file mode 100644
index 0000000..2431660
--- /dev/null
+++ b/Tests/RunCMake/FASTBuild/UnitySubdirsIsolate-check.cmake
@@ -0,0 +1,26 @@
+# Verify that:
+# 1. Non-isolated files from different subdirs are combined in one Unity node
+# 2. Isolated files from subdirs are in separate ObjectLists with proper subdir paths
+
+# Check that Unity node contains the non-isolated files (main.cpp and unity_file.cpp)
+# but not the isolated file. The isolated file should be compiled separately with
+# its subdirectory in the output path.
+set(REGEX_TO_MATCH "
+  Unity\\('main_Unity_1'\\)
+  {
+    \\.UnityOutputPath = 'CMakeFiles/main.dir'
+    \\.UnityOutputPattern = 'main_Unity_1.cpp'
+    \\.UnityInputFiles =
+    {
+      .*main.cpp',
+      .*subdir1/unity_file.cpp'
+    }
+  }
+.*ObjectList.*
+.*
+    \\.CompilerOutputPath = 'CMakeFiles/main.dir/subdir2'
+.*
+      .*isolated_file.cpp'
+")
+
+include(${RunCMake_SOURCE_DIR}/check.cmake)
diff --git a/Tests/RunCMake/FASTBuild/UnitySubdirsIsolate.cmake b/Tests/RunCMake/FASTBuild/UnitySubdirsIsolate.cmake
new file mode 100644
index 0000000..8d37f93
--- /dev/null
+++ b/Tests/RunCMake/FASTBuild/UnitySubdirsIsolate.cmake
@@ -0,0 +1,23 @@
+# Test that isolated files from subdirectories get proper subdirectory-based object paths,
+# while non-isolated files are combined in unity buckets regardless of subdirectory.
+
+set(CMAKE_UNITY_BUILD ON)
+
+file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/subdir1)
+file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/subdir2)
+
+file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/main.cpp "int main() { return 0; }\n")
+file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/subdir1/unity_file.cpp "int unity_file() { return 1; }\n")
+file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/subdir2/isolated_file.cpp "int isolated_file() { return 2; }\n")
+
+add_executable(main
+    ${CMAKE_CURRENT_BINARY_DIR}/main.cpp
+    ${CMAKE_CURRENT_BINARY_DIR}/subdir1/unity_file.cpp
+    ${CMAKE_CURRENT_BINARY_DIR}/subdir2/isolated_file.cpp
+)
+
+set_source_files_properties(
+    ${CMAKE_CURRENT_BINARY_DIR}/subdir2/isolated_file.cpp
+    TARGET_DIRECTORY main
+    PROPERTIES SKIP_UNITY_BUILD_INCLUSION ON
+)
diff --git a/Tests/RunCMake/InstallExportsAsPackageInfo/ExperimentalWarning-stderr.txt b/Tests/RunCMake/InstallExportsAsPackageInfo/ExperimentalWarning-stderr.txt
index b761f9c..1b2c7d8 100644
--- a/Tests/RunCMake/InstallExportsAsPackageInfo/ExperimentalWarning-stderr.txt
+++ b/Tests/RunCMake/InstallExportsAsPackageInfo/ExperimentalWarning-stderr.txt
@@ -1,4 +1,4 @@
-CMake Warning \(dev\) at ExperimentalWarning\.cmake:13 \(install\):
+CMake Warning \(dev\) at ExperimentalWarning\.cmake:[0-9]+ \(install\):
   CMake's support for generating package information in the Common Package
   Specification format from CMake script exports is experimental\.  It is
   meant only for experimentation and feedback to CMake developers\.
diff --git a/Tests/RunCMake/InstallExportsAsPackageInfo/ExperimentalWarning.cmake b/Tests/RunCMake/InstallExportsAsPackageInfo/ExperimentalWarning.cmake
index e2740a8..941fe54 100644
--- a/Tests/RunCMake/InstallExportsAsPackageInfo/ExperimentalWarning.cmake
+++ b/Tests/RunCMake/InstallExportsAsPackageInfo/ExperimentalWarning.cmake
@@ -1,8 +1,4 @@
 set(
-  CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO
-  "7fa7d13b-8308-4dc7-af39-9e450456d68f"
-  )
-set(
   CMAKE_EXPERIMENTAL_MAPPED_PACKAGE_INFO
   "ababa1b5-7099-495f-a9cd-e22d38f274f2"
   )
diff --git a/Tests/RunCMake/InstallExportsAsPackageInfo/RunCMakeTest.cmake b/Tests/RunCMake/InstallExportsAsPackageInfo/RunCMakeTest.cmake
index f77161b..54f3e37 100644
--- a/Tests/RunCMake/InstallExportsAsPackageInfo/RunCMakeTest.cmake
+++ b/Tests/RunCMake/InstallExportsAsPackageInfo/RunCMakeTest.cmake
@@ -7,7 +7,6 @@
 # Enable experimental feature and suppress warnings
 set(RunCMake_TEST_OPTIONS
   -Wno-dev
-  "-DCMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO:STRING=7fa7d13b-8308-4dc7-af39-9e450456d68f"
   "-DCMAKE_EXPERIMENTAL_MAPPED_PACKAGE_INFO:STRING=ababa1b5-7099-495f-a9cd-e22d38f274f2"
   )
 
diff --git a/Tests/RunCMake/InstallPackageInfo/ExperimentalGate-result.txt b/Tests/RunCMake/InstallPackageInfo/ExperimentalGate-result.txt
deleted file mode 100644
index d00491f..0000000
--- a/Tests/RunCMake/InstallPackageInfo/ExperimentalGate-result.txt
+++ /dev/null
@@ -1 +0,0 @@
-1
diff --git a/Tests/RunCMake/InstallPackageInfo/ExperimentalGate-stderr.txt b/Tests/RunCMake/InstallPackageInfo/ExperimentalGate-stderr.txt
deleted file mode 100644
index d7ad6ff..0000000
--- a/Tests/RunCMake/InstallPackageInfo/ExperimentalGate-stderr.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-CMake Error at ExperimentalGate\.cmake:5 \(install\):
-  install does not recognize sub-command PACKAGE_INFO
diff --git a/Tests/RunCMake/InstallPackageInfo/ExperimentalGate.cmake b/Tests/RunCMake/InstallPackageInfo/ExperimentalGate.cmake
deleted file mode 100644
index 327d3bb..0000000
--- a/Tests/RunCMake/InstallPackageInfo/ExperimentalGate.cmake
+++ /dev/null
@@ -1,5 +0,0 @@
-unset(CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO)
-
-add_library(foo INTERFACE)
-install(TARGETS foo EXPORT foo DESTINATION .)
-install(PACKAGE_INFO foo DESTINATION cps EXPORT foo)
diff --git a/Tests/RunCMake/InstallPackageInfo/ExperimentalWarning-stderr.txt b/Tests/RunCMake/InstallPackageInfo/ExperimentalWarning-stderr.txt
deleted file mode 100644
index acac23b..0000000
--- a/Tests/RunCMake/InstallPackageInfo/ExperimentalWarning-stderr.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-CMake Warning \(dev\) at ExperimentalWarning\.cmake:8 \(install\):
-  CMake's support for exporting package information in the Common Package
-  Specification format is experimental\.  It is meant only for experimentation
-  and feedback to CMake developers\.
-Call Stack \(most recent call first\):
-  CMakeLists\.txt:3 \(include\)
-This warning is for project developers\.  Use -Wno-dev to suppress it\.
diff --git a/Tests/RunCMake/InstallPackageInfo/ExperimentalWarning.cmake b/Tests/RunCMake/InstallPackageInfo/ExperimentalWarning.cmake
deleted file mode 100644
index 3c6b90d..0000000
--- a/Tests/RunCMake/InstallPackageInfo/ExperimentalWarning.cmake
+++ /dev/null
@@ -1,8 +0,0 @@
-set(
-  CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO
-  "7fa7d13b-8308-4dc7-af39-9e450456d68f"
-  )
-
-add_library(foo INTERFACE)
-install(TARGETS foo EXPORT foo DESTINATION .)
-install(PACKAGE_INFO foo DESTINATION cps EXPORT foo)
diff --git a/Tests/RunCMake/InstallPackageInfo/RunCMakeTest.cmake b/Tests/RunCMake/InstallPackageInfo/RunCMakeTest.cmake
index 2f3be0c..56ee883 100644
--- a/Tests/RunCMake/InstallPackageInfo/RunCMakeTest.cmake
+++ b/Tests/RunCMake/InstallPackageInfo/RunCMakeTest.cmake
@@ -1,20 +1,5 @@
 include(RunCMake)
 
-# Test experimental gate
-run_cmake(ExperimentalGate)
-run_cmake(ExperimentalWarning)
-
-# Test version check author warning
-# TODO Move to be with other tests when experimental gate is removed.
-run_cmake(VersionCheckWarning)
-
-# Enable experimental feature and suppress warnings
-set(RunCMake_TEST_OPTIONS
-  -Wno-dev
-  "-DCMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO:STRING=7fa7d13b-8308-4dc7-af39-9e450456d68f"
-  "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES:STRING=e82e467b-f997-4464-8ace-b00808fff261"
-  )
-
 function(run_cmake_install test)
   set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build)
   if (NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
@@ -64,6 +49,6 @@
 run_cmake(TransitiveSymbolicComponent)
 run_cmake(InstallSymbolicComponent)
 run_cmake(VersionCheck)
-# run_cmake(VersionCheckWarning)
+run_cmake(VersionCheckWarning)
 run_cmake(VersionCheckError)
 run_cmake_install(Destination)
diff --git a/Tests/RunCMake/InstallPackageInfo/VersionCheckWarning.cmake b/Tests/RunCMake/InstallPackageInfo/VersionCheckWarning.cmake
index 833fbbf..62ee7d0 100644
--- a/Tests/RunCMake/InstallPackageInfo/VersionCheckWarning.cmake
+++ b/Tests/RunCMake/InstallPackageInfo/VersionCheckWarning.cmake
@@ -1,8 +1,3 @@
-set(
-  CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO
-  "7fa7d13b-8308-4dc7-af39-9e450456d68f"
-)
-
 add_library(foo INTERFACE)
 install(TARGETS foo EXPORT foo DESTINATION .)
 
diff --git a/Tests/RunCMake/InstallSbom/RunCMakeTest.cmake b/Tests/RunCMake/InstallSbom/RunCMakeTest.cmake
index 525a371..ef6b864 100644
--- a/Tests/RunCMake/InstallSbom/RunCMakeTest.cmake
+++ b/Tests/RunCMake/InstallSbom/RunCMakeTest.cmake
@@ -3,8 +3,6 @@
 set(common_test_options
   -Wno-dev
   "-DCMAKE_EXPERIMENTAL_GENERATE_SBOM:STRING=ca494ed3-b261-4205-a01f-603c95e4cae0"
-  "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES:STRING=e82e467b-f997-4464-8ace-b00808fff261"
-  "-DCMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO:STRING=7fa7d13b-8308-4dc7-af39-9e450456d68f"
 )
 
 function(run_cmake_install test)
diff --git a/Tests/RunCMake/Ninja/Intl-common.cmake b/Tests/RunCMake/Ninja/Intl-common.cmake
index 7703976..a26e517 100644
--- a/Tests/RunCMake/Ninja/Intl-common.cmake
+++ b/Tests/RunCMake/Ninja/Intl-common.cmake
@@ -1 +1 @@
-set(intl "intl-ë®")
+set(intl "intl-ë®") # UTF-8
diff --git a/Tests/RunCMake/add_test/CMP0110-Common-OtherSpecialChars.cmake b/Tests/RunCMake/add_test/CMP0110-Common-OtherSpecialChars.cmake
index f74c3b5..2a53a3c 100644
--- a/Tests/RunCMake/add_test/CMP0110-Common-OtherSpecialChars.cmake
+++ b/Tests/RunCMake/add_test/CMP0110-Common-OtherSpecialChars.cmake
@@ -1,2 +1,2 @@
-set(TEST_NAME "!§%&/ü:*😤~")
+set(TEST_NAME "!§%&/ü:*😤~") # UTF-8
 include(CMP0110-Common.cmake)
diff --git a/Tests/RunCMake/cmake_host_system_information/Locale-stdout-iso-8859-1.txt b/Tests/RunCMake/cmake_host_system_information/Locale-stdout-iso-8859-1.txt
new file mode 100644
index 0000000..2307984
--- /dev/null
+++ b/Tests/RunCMake/cmake_host_system_information/Locale-stdout-iso-8859-1.txt
@@ -0,0 +1 @@
+^-- LOCALE_CHARSET='ISO-8859-1'$
diff --git a/Tests/RunCMake/cmake_host_system_information/Locale-stdout-utf-8.txt b/Tests/RunCMake/cmake_host_system_information/Locale-stdout-utf-8.txt
new file mode 100644
index 0000000..f15d5c9
--- /dev/null
+++ b/Tests/RunCMake/cmake_host_system_information/Locale-stdout-utf-8.txt
@@ -0,0 +1 @@
+^-- LOCALE_CHARSET='UTF-8'$
diff --git a/Tests/RunCMake/cmake_host_system_information/Locale-stdout.txt b/Tests/RunCMake/cmake_host_system_information/Locale-stdout.txt
new file mode 100644
index 0000000..3cb5e72
--- /dev/null
+++ b/Tests/RunCMake/cmake_host_system_information/Locale-stdout.txt
@@ -0,0 +1 @@
+^-- LOCALE_CHARSET='[^']+'$
diff --git a/Tests/RunCMake/cmake_host_system_information/Locale.cmake b/Tests/RunCMake/cmake_host_system_information/Locale.cmake
new file mode 100644
index 0000000..32b31be
--- /dev/null
+++ b/Tests/RunCMake/cmake_host_system_information/Locale.cmake
@@ -0,0 +1,2 @@
+cmake_host_system_information(RESULT charset QUERY LOCALE_CHARSET)
+message(STATUS "LOCALE_CHARSET='${charset}'")
diff --git a/Tests/RunCMake/cmake_host_system_information/QueryKeys-stdout.txt b/Tests/RunCMake/cmake_host_system_information/QueryKeys-stdout.txt
index 1a43221..3575c84 100644
--- a/Tests/RunCMake/cmake_host_system_information/QueryKeys-stdout.txt
+++ b/Tests/RunCMake/cmake_host_system_information/QueryKeys-stdout.txt
@@ -23,6 +23,7 @@
 -- PROCESSOR_SERIAL_NUMBER=`.*`
 -- PROCESSOR_NAME=`.*`
 -- PROCESSOR_DESCRIPTION=`.*`
+-- LOCALE_CHARSET=`[^`]+`
 -- OS_NAME=`.*`
 -- OS_RELEASE=`.*`
 -- OS_VERSION=`.*`
diff --git a/Tests/RunCMake/cmake_host_system_information/QueryKeys.cmake b/Tests/RunCMake/cmake_host_system_information/QueryKeys.cmake
index 2b497fb..408dd0d 100644
--- a/Tests/RunCMake/cmake_host_system_information/QueryKeys.cmake
+++ b/Tests/RunCMake/cmake_host_system_information/QueryKeys.cmake
@@ -28,6 +28,7 @@
 try_and_print(PROCESSOR_SERIAL_NUMBER)
 try_and_print(PROCESSOR_NAME)
 try_and_print(PROCESSOR_DESCRIPTION)
+try_and_print(LOCALE_CHARSET)
 try_and_print(OS_NAME)
 try_and_print(OS_RELEASE)
 try_and_print(OS_VERSION)
diff --git a/Tests/RunCMake/cmake_host_system_information/RunCMakeTest.cmake b/Tests/RunCMake/cmake_host_system_information/RunCMakeTest.cmake
index 3917913..803518a 100644
--- a/Tests/RunCMake/cmake_host_system_information/RunCMakeTest.cmake
+++ b/Tests/RunCMake/cmake_host_system_information/RunCMakeTest.cmake
@@ -7,6 +7,14 @@
 run_cmake(QueryList)
 run_cmake(QueryKeys)
 
+if(CMake_TEST_LOCALE_CHARSET STREQUAL "UTF-8" OR CMAKE_HOST_WIN32)
+  set(RunCMake-stdout-file Locale-stdout-utf-8.txt)
+elseif(CMake_TEST_LOCALE_CHARSET STREQUAL "ISO-8859-1")
+  set(RunCMake-stdout-file Locale-stdout-iso-8859-1.txt)
+endif()
+run_cmake_script(Locale)
+unset(RunCMake-stdout-file)
+
 run_cmake(UnitTest)
 run_cmake(Exherbo)
 run_cmake(Ubuntu)
diff --git a/Tests/RunCMake/file/REAL_PATH.cmake b/Tests/RunCMake/file/REAL_PATH.cmake
index 0485655..a8a3d0e 100644
--- a/Tests/RunCMake/file/REAL_PATH.cmake
+++ b/Tests/RunCMake/file/REAL_PATH.cmake
@@ -88,6 +88,10 @@
   file(REAL_PATH "${low}" out)
 
   if(NOT "${out}" PATH_EQUAL "${in}")
-    message(SEND_ERROR "real path is \"${out}\", should be \"${in}\"")
+    message(SEND_ERROR
+      "real path is:\n"
+      "  \"${out}\"\n"
+      "but should be:\n"
+      "  \"${in}\"")
   endif()
 endif()
diff --git a/Tests/RunCMake/find_package-CPS/ExperimentalWarning-stderr.txt b/Tests/RunCMake/find_package-CPS/ExperimentalWarning-stderr.txt
deleted file mode 100644
index d23e7d5..0000000
--- a/Tests/RunCMake/find_package-CPS/ExperimentalWarning-stderr.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-CMake Warning \(dev\) at ExperimentalWarning\.cmake:[0-9]+ \(find_package\):
-  CMake's support for importing package information in the Common Package
-  Specification format \(via find_package\) is experimental\.  It is meant only
-  for experimentation and feedback to CMake developers\.
-Call Stack \(most recent call first\):
-  CMakeLists\.txt:3 \(include\)
-This warning is for project developers\.  Use -Wno-dev to suppress it\.
-
-CMake Warning at ExperimentalWarning\.cmake:[0-9]+ \(find_package\):
-  By not providing "FindDoesNotExist\.cmake" in CMAKE_MODULE_PATH this project
-  has asked CMake to find a package configuration file provided by
-  "DoesNotExist", but CMake did not find one\.
-
-  Could not find a package configuration file provided by "DoesNotExist" with
-  any of the following names:
-
-    DoesNotExist\.cps
-    doesnotexist\.cps
-    DoesNotExistConfig\.cmake
-    doesnotexist-config\.cmake
-
-  Add the installation prefix of "DoesNotExist" to CMAKE_PREFIX_PATH or set
-  "DoesNotExist_DIR" to a directory containing one of the above files\.  If
-  "DoesNotExist" provides a separate development package or SDK, be sure it
-  has been installed\.
-Call Stack \(most recent call first\):
-  CMakeLists\.txt:3 \(include\)
diff --git a/Tests/RunCMake/find_package-CPS/ExperimentalWarning.cmake b/Tests/RunCMake/find_package-CPS/ExperimentalWarning.cmake
deleted file mode 100644
index 3837352..0000000
--- a/Tests/RunCMake/find_package-CPS/ExperimentalWarning.cmake
+++ /dev/null
@@ -1,10 +0,0 @@
-cmake_minimum_required(VERSION 4.0)
-
-set(
-  CMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES
-  "e82e467b-f997-4464-8ace-b00808fff261"
-  )
-
-include(Setup.cmake)
-
-find_package(DoesNotExist)
diff --git a/Tests/RunCMake/find_package-CPS/RunCMakeTest.cmake b/Tests/RunCMake/find_package-CPS/RunCMakeTest.cmake
index 944b80b..698a0bf 100644
--- a/Tests/RunCMake/find_package-CPS/RunCMakeTest.cmake
+++ b/Tests/RunCMake/find_package-CPS/RunCMakeTest.cmake
@@ -1,13 +1,5 @@
 include(RunCMake)
 
-run_cmake(ExperimentalWarning)
-
-# Enable experimental feature and suppress warnings
-set(RunCMake_TEST_OPTIONS
-  -Wno-dev
-  "-DCMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES:STRING=e82e467b-f997-4464-8ace-b00808fff261"
-  )
-
 function(run_cmake_build test)
   set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build)
   if(${ARGC} EQUAL 2)
diff --git a/Tests/RunCMake/find_package/ConfigureLog-config.txt b/Tests/RunCMake/find_package/ConfigureLog-config.txt
index 4c39756..d55c2fe 100644
--- a/Tests/RunCMake/find_package/ConfigureLog-config.txt
+++ b/Tests/RunCMake/find_package/ConfigureLog-config.txt
@@ -19,10 +19,16 @@
     name: "ViaConfig"
     configs:
       -
-        filename: "ViaConfigConfig.cmake"
+        filename: "ViaConfig\.cps"
+        kind: "cps"
+      -
+        filename: "viaconfig\.cps"
+        kind: "cps"
+      -
+        filename: "ViaConfigConfig\.cmake"
         kind: "cmake"
       -
-        filename: "viaconfig-config.cmake"
+        filename: "viaconfig-config\.cmake"
         kind: "cmake"
     version_request:
       exact: false
@@ -48,31 +54,63 @@
         CMAKE_FIND_ROOT_PATH_MODE: "BOTH"
     candidates:
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/ViaConfigConfig.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/ViaConfigConfig\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/viaconfig-config.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/viaconfig-config\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/ViaConfigConfig.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/lib/cps/ViaConfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/lib/cps/viaconfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/share/cps/ViaConfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/share/cps/viaconfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/ViaConfigConfig\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/viaconfig-config.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/viaconfig-config\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/ViaConfigConfig.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/ViaConfigConfig\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/viaconfig-config.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/viaconfig-config\.cmake"
         mode: "config"
         reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/ViaConfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/viaconfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/ViaConfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/viaconfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
     found:
-      path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ViaConfig/ViaConfigConfig.cmake"
+      path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ViaConfig/ViaConfigConfig\.cmake"
       mode: "config"
       version: "1\.0"
     search_context:(
@@ -104,9 +142,9 @@
         CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY: true
         CMAKE_FIND_ROOT_PATH_MODE: "BOTH"
     found:
-      path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/FindViaModule.cmake"
+      path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/FindViaModule\.cmake"
       mode: "module"
-      version: "1.0"
+      version: "1\.0"
     search_context:(
       [^
 ]*)+
@@ -117,10 +155,16 @@
     name: "Inner"
     configs:
       -
-        filename: "InnerConfig.cmake"
+        filename: "Inner\.cps"
+        kind: "cps"
+      -
+        filename: "inner\.cps"
+        kind: "cps"
+      -
+        filename: "InnerConfig\.cmake"
         kind: "cmake"
       -
-        filename: "inner-config.cmake"
+        filename: "inner-config\.cmake"
         kind: "cmake"
     version_request:
       exact: false
@@ -146,33 +190,65 @@
         CMAKE_FIND_ROOT_PATH_MODE: "BOTH"
     candidates:
       -
-        path: "[^"]*/CMakeFiles/pkgRedirects/InnerConfig.cmake"
+        path: "[^"]*/CMakeFiles/pkgRedirects/InnerConfig\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/CMakeFiles/pkgRedirects/inner-config.cmake"
+        path: "[^"]*/CMakeFiles/pkgRedirects/inner-config\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/InnerConfig.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/lib/cps/Inner\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/lib/cps/inner\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/share/cps/Inner\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/share/cps/inner\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/InnerConfig\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/inner-config.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/inner-config\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/InnerConfig.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/InnerConfig\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/inner-config.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/inner-config\.cmake"
         mode: "config"
         reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/Inner\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/inner\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/Inner\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/inner\.cps"
+        mode: "cps"
+        reason: "no_exist"
     found:
-      path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/Inner/InnerConfig.cmake"
+      path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/Inner/InnerConfig\.cmake"
       mode: "config"
-      version: "1.1"
+      version: "1\.1"
     search_context:(
       [^
 ]*)+
@@ -202,9 +278,9 @@
         CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY: true
         CMAKE_FIND_ROOT_PATH_MODE: "BOTH"
     found:
-      path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/FindWithInner.cmake"
+      path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/FindWithInner\.cmake"
       mode: "module"
-      version: "1.1"
+      version: "1\.1"
     search_context:(
       [^
 ]*)+
@@ -215,14 +291,20 @@
     name: "VersionCheck"
     configs:
       -
-        filename: "VersionCheckConfig.cmake"
+        filename: "VersionCheck\.cps"
+        kind: "cps"
+      -
+        filename: "versioncheck\.cps"
+        kind: "cps"
+      -
+        filename: "VersionCheckConfig\.cmake"
         kind: "cmake"
       -
-        filename: "versioncheck-config.cmake"
+        filename: "versioncheck-config\.cmake"
         kind: "cmake"
     version_request:
-      version: "2.0"
-      version_complete: "2.0"
+      version: "2\.0"
+      version_complete: "2\.0"
       exact: false
     settings:
       required: "optional"
@@ -246,42 +328,74 @@
         CMAKE_FIND_ROOT_PATH_MODE: "BOTH"
     candidates:
       -
-        path: "[^"]*/CMakeFiles/pkgRedirects/VersionCheckConfig.cmake"
+        path: "[^"]*/CMakeFiles/pkgRedirects/VersionCheckConfig\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/CMakeFiles/pkgRedirects/versioncheck-config.cmake"
+        path: "[^"]*/CMakeFiles/pkgRedirects/versioncheck-config\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/VersionCheckConfig.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/lib/cps/VersionCheck\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/lib/cps/versioncheck\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/share/cps/VersionCheck\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/share/cps/versioncheck\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/VersionCheckConfig\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/versioncheck-config.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/versioncheck-config\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/VersionCheckConfig.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/VersionCheckConfig\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/versioncheck-config.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/versioncheck-config\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/VersionCheck-1.5/VersionCheckConfig.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/VersionCheck\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/versioncheck\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/VersionCheck\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/versioncheck\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/VersionCheck-1\.5/VersionCheckConfig\.cmake"
         mode: "config"
         reason: "insufficient_version"
-        message: "The version found is not compatible with the version requested."
+        message: "The version found is not compatible with the version requested\."
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/VersionCheck-1.5/versioncheck-config.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/VersionCheck-1\.5/versioncheck-config\.cmake"
         mode: "config"
         reason: "no_exist"
     found:
-      path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/VersionCheck-2.5/VersionCheckConfig.cmake"
+      path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/VersionCheck-2\.5/VersionCheckConfig\.cmake"
       mode: "config"
-      version: "2.5"
+      version: "2\.5"
     search_context:(
       [^
 ]*)+
diff --git a/Tests/RunCMake/find_package/ConfigureLog-stderr.txt b/Tests/RunCMake/find_package/ConfigureLog-stderr.txt
index e01e46e..87e3419 100644
--- a/Tests/RunCMake/find_package/ConfigureLog-stderr.txt
+++ b/Tests/RunCMake/find_package/ConfigureLog-stderr.txt
@@ -69,10 +69,18 @@
 
     .*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/ViaConfigConfig\.cmake
     .*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/viaconfig-config\.cmake
+    .*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/lib/cps/ViaConfig\.cps
+    .*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/lib/cps/viaconfig\.cps
+    .*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/share/cps/ViaConfig\.cps
+    .*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/share/cps/viaconfig\.cps
     .*/Tests/RunCMake/find_package/ConfigureLog/ViaConfigConfig\.cmake
     .*/Tests/RunCMake/find_package/ConfigureLog/viaconfig-config\.cmake
     .*/Tests/RunCMake/find_package/ConfigureLog/cmake/ViaConfigConfig\.cmake
     .*/Tests/RunCMake/find_package/ConfigureLog/cmake/viaconfig-config\.cmake
+    .*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/ViaConfig\.cps
+    .*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/viaconfig\.cps
+    .*/Tests/RunCMake/find_package/ConfigureLog/share/cps/ViaConfig\.cps
+    .*/Tests/RunCMake/find_package/ConfigureLog/share/cps/viaconfig\.cps
     .*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ViaConfig/ViaConfigConfig\.cmake
 
   The file was found at
@@ -165,12 +173,20 @@
 
   find_package considered the following locations for Inner's Config module:
 
-    .*/CMakeFiles/pkgRedirects/InnerConfig\.cmake
-    .*/CMakeFiles/pkgRedirects/inner-config\.cmake
+    .*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/InnerConfig\.cmake
+    .*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/inner-config\.cmake
+    .*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/lib/cps/Inner\.cps
+    .*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/lib/cps/inner\.cps
+    .*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/share/cps/Inner\.cps
+    .*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/share/cps/inner\.cps
     .*/Tests/RunCMake/find_package/ConfigureLog/InnerConfig\.cmake
     .*/Tests/RunCMake/find_package/ConfigureLog/inner-config\.cmake
     .*/Tests/RunCMake/find_package/ConfigureLog/cmake/InnerConfig\.cmake
     .*/Tests/RunCMake/find_package/ConfigureLog/cmake/inner-config\.cmake
+    .*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/Inner\.cps
+    .*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/inner\.cps
+    .*/Tests/RunCMake/find_package/ConfigureLog/share/cps/Inner\.cps
+    .*/Tests/RunCMake/find_package/ConfigureLog/share/cps/inner\.cps
     .*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/Inner/InnerConfig\.cmake
 
   The file was found at
@@ -266,12 +282,20 @@
   find_package considered the following locations for VersionCheck's Config
   module:
 
-    .*/CMakeFiles/pkgRedirects/VersionCheckConfig\.cmake
-    .*/CMakeFiles/pkgRedirects/versioncheck-config\.cmake
+    .*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/VersionCheckConfig\.cmake
+    .*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/versioncheck-config\.cmake
+    .*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/lib/cps/VersionCheck\.cps
+    .*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/lib/cps/versioncheck\.cps
+    .*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/share/cps/VersionCheck\.cps
+    .*/Tests/RunCMake/find_package/ConfigureLog-build/CMakeFiles/pkgRedirects/share/cps/versioncheck\.cps
     .*/Tests/RunCMake/find_package/ConfigureLog/VersionCheckConfig\.cmake
     .*/Tests/RunCMake/find_package/ConfigureLog/versioncheck-config\.cmake
     .*/Tests/RunCMake/find_package/ConfigureLog/cmake/VersionCheckConfig\.cmake
-    .*/Tests/RunCMake/find_package/ConfigureLog/cmake/versioncheck-config\.cmake(
+    .*/Tests/RunCMake/find_package/ConfigureLog/cmake/versioncheck-config\.cmake
+    .*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/VersionCheck\.cps
+    .*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/versioncheck\.cps
+    .*/Tests/RunCMake/find_package/ConfigureLog/share/cps/VersionCheck\.cps
+    .*/Tests/RunCMake/find_package/ConfigureLog/share/cps/versioncheck\.cps(
     .*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/VersionCheck-1\.5/VersionCheckConfig\.cmake
     .*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/VersionCheck-1\.5/versioncheck-config\.cmake)?
     .*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/VersionCheck-2\.5/VersionCheckConfig\.cmake
diff --git a/Tests/RunCMake/find_package/ConfigureLogParameters2-config.txt b/Tests/RunCMake/find_package/ConfigureLogParameters2-config.txt
index 362a080..07b5384 100644
--- a/Tests/RunCMake/find_package/ConfigureLogParameters2-config.txt
+++ b/Tests/RunCMake/find_package/ConfigureLogParameters2-config.txt
@@ -19,10 +19,16 @@
     name: "ParameterCheckConfig"
     configs:
       -
-        filename: "ParameterCheckConfigConfig.cmake"
+        filename: "ParameterCheckConfig\.cps"
+        kind: "cps"
+      -
+        filename: "parametercheckconfig\.cps"
+        kind: "cps"
+      -
+        filename: "ParameterCheckConfigConfig\.cmake"
         kind: "cmake"
       -
-        filename: "parametercheckconfig-config.cmake"
+        filename: "parametercheckconfig-config\.cmake"
         kind: "cmake"
     version_request:
       exact: false
@@ -50,33 +56,65 @@
         CMAKE_FIND_ROOT_PATH_MODE: "BOTH"
     candidates:
       -
-        path: "[^"]*/CMakeFiles/pkgRedirects/ParameterCheckConfigConfig.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/ParameterCheckConfigConfig\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/CMakeFiles/pkgRedirects/parametercheckconfig-config.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/parametercheckconfig-config\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/ParameterCheckConfigConfig.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/ParameterCheckConfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/parametercheckconfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/ParameterCheckConfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/parametercheckconfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/ParameterCheckConfigConfig\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/parametercheckconfig-config.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/parametercheckconfig-config\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/ParameterCheckConfigConfig.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/ParameterCheckConfigConfig\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/parametercheckconfig-config.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/parametercheckconfig-config\.cmake"
         mode: "config"
         reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/ParameterCheckConfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/parametercheckconfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/ParameterCheckConfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/parametercheckconfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
     found:
-      path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/ParameterCheckConfigConfig.cmake"
+      path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/ParameterCheckConfigConfig\.cmake"
       mode: "config"
-      version: "1.6"
+      version: "1\.6"
     search_context:(
       [^
 ]*)+
@@ -87,10 +125,16 @@
     name: "ParameterCheckConfig"
     configs:
       -
-        filename: "ParameterCheckConfigConfig.cmake"
+        filename: "ParameterCheckConfig\.cps"
+        kind: "cps"
+      -
+        filename: "parametercheckconfig\.cps"
+        kind: "cps"
+      -
+        filename: "ParameterCheckConfigConfig\.cmake"
         kind: "cmake"
       -
-        filename: "parametercheckconfig-config.cmake"
+        filename: "parametercheckconfig-config\.cmake"
         kind: "cmake"
     version_request:
       exact: false
@@ -118,81 +162,177 @@
         CMAKE_FIND_ROOT_PATH_MODE: "BOTH"
     candidates:
       -
-        path: "[^"]*/CMakeFiles/pkgRedirects/ParameterCheckConfigConfig.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/ParameterCheckConfigConfig\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/CMakeFiles/pkgRedirects/parametercheckconfig-config.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/parametercheckconfig-config\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/CMakeFiles/pkgRedirects/suffix1/ParameterCheckConfigConfig.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/suffix1/ParameterCheckConfigConfig\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/CMakeFiles/pkgRedirects/suffix1/parametercheckconfig-config.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/suffix1/parametercheckconfig-config\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/CMakeFiles/pkgRedirects/suffix2/ParameterCheckConfigConfig.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/suffix2/ParameterCheckConfigConfig\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/CMakeFiles/pkgRedirects/suffix2/parametercheckconfig-config.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/suffix2/parametercheckconfig-config\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/ParameterCheckConfigConfig.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/ParameterCheckConfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/parametercheckconfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/suffix1/ParameterCheckConfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/suffix1/parametercheckconfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/suffix2/ParameterCheckConfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/suffix2/parametercheckconfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/ParameterCheckConfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/parametercheckconfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/suffix1/ParameterCheckConfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/suffix1/parametercheckconfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/suffix2/ParameterCheckConfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/suffix2/parametercheckconfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/ParameterCheckConfigConfig\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/parametercheckconfig-config.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/parametercheckconfig-config\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/suffix1/ParameterCheckConfigConfig.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/suffix1/ParameterCheckConfigConfig\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/suffix1/parametercheckconfig-config.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/suffix1/parametercheckconfig-config\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/suffix2/ParameterCheckConfigConfig.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/suffix2/ParameterCheckConfigConfig\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/suffix2/parametercheckconfig-config.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/suffix2/parametercheckconfig-config\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/ParameterCheckConfigConfig.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/ParameterCheckConfigConfig\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/parametercheckconfig-config.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/parametercheckconfig-config\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/suffix1/ParameterCheckConfigConfig.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/suffix1/ParameterCheckConfigConfig\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/suffix1/parametercheckconfig-config.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/suffix1/parametercheckconfig-config\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/suffix2/ParameterCheckConfigConfig.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/suffix2/ParameterCheckConfigConfig\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/suffix2/parametercheckconfig-config.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/suffix2/parametercheckconfig-config\.cmake"
         mode: "config"
         reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/ParameterCheckConfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/parametercheckconfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/suffix1/ParameterCheckConfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/suffix1/parametercheckconfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/suffix2/ParameterCheckConfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/suffix2/parametercheckconfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/ParameterCheckConfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/parametercheckconfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/suffix1/ParameterCheckConfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/suffix1/parametercheckconfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/suffix2/ParameterCheckConfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/suffix2/parametercheckconfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
     found:
-      path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/ParameterCheckConfigConfig.cmake"
+      path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/ParameterCheckConfigConfig\.cmake"
       mode: "config"
-      version: "1.6"
+      version: "1\.6"
     search_context:(
       [^
 ]*)+
@@ -203,10 +343,16 @@
     name: "ParameterCheckConfig"
     configs:
       -
-        filename: "ParameterCheckConfigConfig.cmake"
+        filename: "ParameterCheckConfig\.cps"
+        kind: "cps"
+      -
+        filename: "parametercheckconfig\.cps"
+        kind: "cps"
+      -
+        filename: "ParameterCheckConfigConfig\.cmake"
         kind: "cmake"
       -
-        filename: "parametercheckconfig-config.cmake"
+        filename: "parametercheckconfig-config\.cmake"
         kind: "cmake"
     version_request:
       exact: false
@@ -232,13 +378,29 @@
         CMAKE_FIND_ROOT_PATH_MODE: "BOTH"
     candidates:
       -
-        path: "[^"]*/CMakeFiles/pkgRedirects/ParameterCheckConfigConfig.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/ParameterCheckConfigConfig\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/CMakeFiles/pkgRedirects/parametercheckconfig-config.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/parametercheckconfig-config\.cmake"
         mode: "config"
         reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/ParameterCheckConfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/parametercheckconfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/ParameterCheckConfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/parametercheckconfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
     found: null
     search_context:(
       [^
@@ -250,10 +412,16 @@
     name: "ParameterCheckConfig"
     configs:
       -
-        filename: "ParameterCheckConfigConfig.cmake"
+        filename: "ParameterCheckConfig\.cps"
+        kind: "cps"
+      -
+        filename: "parametercheckconfig\.cps"
+        kind: "cps"
+      -
+        filename: "ParameterCheckConfigConfig\.cmake"
         kind: "cmake"
       -
-        filename: "parametercheckconfig-config.cmake"
+        filename: "parametercheckconfig-config\.cmake"
         kind: "cmake"
     version_request:
       exact: false
@@ -279,33 +447,65 @@
         CMAKE_FIND_ROOT_PATH_MODE: "BOTH"
     candidates:
       -
-        path: "[^"]*/CMakeFiles/pkgRedirects/ParameterCheckConfigConfig.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/ParameterCheckConfigConfig\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/CMakeFiles/pkgRedirects/parametercheckconfig-config.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/parametercheckconfig-config\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/ParameterCheckConfigConfig.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/ParameterCheckConfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/parametercheckconfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/ParameterCheckConfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/parametercheckconfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/ParameterCheckConfigConfig\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/parametercheckconfig-config.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/parametercheckconfig-config\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/ParameterCheckConfigConfig.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/ParameterCheckConfigConfig\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/parametercheckconfig-config.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/parametercheckconfig-config\.cmake"
         mode: "config"
         reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/ParameterCheckConfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/parametercheckconfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/ParameterCheckConfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/parametercheckconfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
     found:
-      path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/ParameterCheckConfigConfig.cmake"
+      path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/ParameterCheckConfigConfig\.cmake"
       mode: "config"
-      version: "1.6"
+      version: "1\.6"
     search_context:(
       [^
 ]*)+
@@ -316,10 +516,16 @@
     name: "ParameterCheckConfig"
     configs:
       -
-        filename: "ParameterCheckConfigConfig.cmake"
+        filename: "ParameterCheckConfig\.cps"
+        kind: "cps"
+      -
+        filename: "parametercheckconfig\.cps"
+        kind: "cps"
+      -
+        filename: "ParameterCheckConfigConfig\.cmake"
         kind: "cmake"
       -
-        filename: "parametercheckconfig-config.cmake"
+        filename: "parametercheckconfig-config\.cmake"
         kind: "cmake"
     version_request:
       exact: false
@@ -345,33 +551,65 @@
         CMAKE_FIND_ROOT_PATH_MODE: "ONLY"
     candidates:
       -
-        path: "[^"]*/CMakeFiles/pkgRedirects/ParameterCheckConfigConfig.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/ParameterCheckConfigConfig\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/CMakeFiles/pkgRedirects/parametercheckconfig-config.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/parametercheckconfig-config\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/ParameterCheckConfigConfig.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/ParameterCheckConfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/parametercheckconfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/ParameterCheckConfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/parametercheckconfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/ParameterCheckConfigConfig\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/parametercheckconfig-config.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/parametercheckconfig-config\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/ParameterCheckConfigConfig.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/ParameterCheckConfigConfig\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/parametercheckconfig-config.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/parametercheckconfig-config\.cmake"
         mode: "config"
         reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/ParameterCheckConfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/parametercheckconfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/ParameterCheckConfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/parametercheckconfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
     found:
-      path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/ParameterCheckConfigConfig.cmake"
+      path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/ParameterCheckConfigConfig\.cmake"
       mode: "config"
-      version: "1.6"
+      version: "1\.6"
     search_context:(
       [^
 ]*)+
@@ -382,10 +620,16 @@
     name: "ParameterCheckConfig"
     configs:
       -
-        filename: "ParameterCheckConfigConfig.cmake"
+        filename: "ParameterCheckConfig\.cps"
+        kind: "cps"
+      -
+        filename: "parametercheckconfig\.cps"
+        kind: "cps"
+      -
+        filename: "ParameterCheckConfigConfig\.cmake"
         kind: "cmake"
       -
-        filename: "parametercheckconfig-config.cmake"
+        filename: "parametercheckconfig-config\.cmake"
         kind: "cmake"
     version_request:
       exact: false
@@ -411,33 +655,65 @@
         CMAKE_FIND_ROOT_PATH_MODE: "NEVER"
     candidates:
       -
-        path: "[^"]*/CMakeFiles/pkgRedirects/ParameterCheckConfigConfig.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/ParameterCheckConfigConfig\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/CMakeFiles/pkgRedirects/parametercheckconfig-config.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/parametercheckconfig-config\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/ParameterCheckConfigConfig.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/ParameterCheckConfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/parametercheckconfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/ParameterCheckConfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/parametercheckconfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/ParameterCheckConfigConfig\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/parametercheckconfig-config.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/parametercheckconfig-config\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/ParameterCheckConfigConfig.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/ParameterCheckConfigConfig\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/parametercheckconfig-config.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/parametercheckconfig-config\.cmake"
         mode: "config"
         reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/ParameterCheckConfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/parametercheckconfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/ParameterCheckConfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/parametercheckconfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
     found:
-      path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/ParameterCheckConfigConfig.cmake"
+      path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/ParameterCheckConfigConfig\.cmake"
       mode: "config"
-      version: "1.6"
+      version: "1\.6"
     search_context:(
       [^
 ]*)+
@@ -448,16 +724,28 @@
     name: "OtherParameterCheck"
     configs:
       -
-        filename: "BogusParameterCheckConfig.cmake"
+        filename: "BogusParameterCheck\.cps"
+        kind: "cps"
+      -
+        filename: "bogusparametercheck\.cps"
+        kind: "cps"
+      -
+        filename: "BogusParameterCheckConfig\.cmake"
         kind: "cmake"
       -
-        filename: "bogusparametercheck-config.cmake"
+        filename: "bogusparametercheck-config\.cmake"
         kind: "cmake"
       -
-        filename: "ParameterCheckConfigConfig.cmake"
+        filename: "ParameterCheckConfig\.cps"
+        kind: "cps"
+      -
+        filename: "parametercheckconfig\.cps"
+        kind: "cps"
+      -
+        filename: "ParameterCheckConfigConfig\.cmake"
         kind: "cmake"
       -
-        filename: "parametercheckconfig-config.cmake"
+        filename: "parametercheckconfig-config\.cmake"
         kind: "cmake"
     version_request:
       exact: false
@@ -484,65 +772,129 @@
         CMAKE_FIND_ROOT_PATH_MODE: "BOTH"
     candidates:
       -
-        path: "[^"]*/CMakeFiles/pkgRedirects/BogusParameterCheckConfig.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/BogusParameterCheckConfig\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/CMakeFiles/pkgRedirects/bogusparametercheck-config.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/bogusparametercheck-config\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/CMakeFiles/pkgRedirects/ParameterCheckConfigConfig.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/ParameterCheckConfigConfig\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/CMakeFiles/pkgRedirects/parametercheckconfig-config.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/parametercheckconfig-config\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/BogusParameterCheckConfig.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/BogusParameterCheck\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/bogusparametercheck\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/ParameterCheckConfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/parametercheckconfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/BogusParameterCheck\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/bogusparametercheck\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/ParameterCheckConfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/parametercheckconfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/BogusParameterCheckConfig\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/bogusparametercheck-config.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/bogusparametercheck-config\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/ParameterCheckConfigConfig.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/ParameterCheckConfigConfig\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/parametercheckconfig-config.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/parametercheckconfig-config\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/BogusParameterCheckConfig.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/BogusParameterCheckConfig\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/bogusparametercheck-config.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/bogusparametercheck-config\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/ParameterCheckConfigConfig.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/ParameterCheckConfigConfig\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/parametercheckconfig-config.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/cmake/parametercheckconfig-config\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/BogusParameterCheckConfig.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/BogusParameterCheck\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/bogusparametercheck\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/ParameterCheckConfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/parametercheckconfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/BogusParameterCheck\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/bogusparametercheck\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/ParameterCheckConfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/parametercheckconfig\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/BogusParameterCheckConfig\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/bogusparametercheck-config.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/bogusparametercheck-config\.cmake"
         mode: "config"
         reason: "no_exist"
     found:
-      path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/ParameterCheckConfigConfig.cmake"
+      path: "[^"]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/ParameterCheckConfigConfig\.cmake"
       mode: "config"
-      version: "1.6"
+      version: "1\.6"
     search_context:(
       [^
 ]*)+
diff --git a/Tests/RunCMake/find_package/ConfigureLogParameters2-stderr.txt b/Tests/RunCMake/find_package/ConfigureLogParameters2-stderr.txt
index 1fbf938..2d7d3ef 100644
--- a/Tests/RunCMake/find_package/ConfigureLogParameters2-stderr.txt
+++ b/Tests/RunCMake/find_package/ConfigureLogParameters2-stderr.txt
@@ -68,6 +68,14 @@
     [^
 ]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/parametercheckconfig-config\.cmake
     [^
+]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/ParameterCheckConfig\.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/parametercheckconfig\.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/ParameterCheckConfig\.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/parametercheckconfig\.cps
+    [^
 ]*/Tests/RunCMake/find_package/ConfigureLog/ParameterCheckConfigConfig\.cmake
     [^
 ]*/Tests/RunCMake/find_package/ConfigureLog/parametercheckconfig-config\.cmake
@@ -76,6 +84,14 @@
     [^
 ]*/Tests/RunCMake/find_package/ConfigureLog/cmake/parametercheckconfig-config\.cmake
     [^
+]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/ParameterCheckConfig\.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/parametercheckconfig\.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/ParameterCheckConfig\.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/parametercheckconfig\.cps
+    [^
 ]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/ParameterCheckConfigConfig\.cmake
 
   The file was found at
@@ -164,6 +180,30 @@
     [^
 ]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/suffix2/parametercheckconfig-config\.cmake
     [^
+]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/ParameterCheckConfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/parametercheckconfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/suffix1/ParameterCheckConfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/suffix1/parametercheckconfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/suffix2/ParameterCheckConfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/suffix2/parametercheckconfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/ParameterCheckConfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/parametercheckconfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/suffix1/ParameterCheckConfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/suffix1/parametercheckconfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/suffix2/ParameterCheckConfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/suffix2/parametercheckconfig.cps
+    [^
 ]*/Tests/RunCMake/find_package/ConfigureLog/ParameterCheckConfigConfig\.cmake
     [^
 ]*/Tests/RunCMake/find_package/ConfigureLog/parametercheckconfig-config\.cmake
@@ -188,6 +228,30 @@
     [^
 ]*/Tests/RunCMake/find_package/ConfigureLog/cmake/suffix2/parametercheckconfig-config\.cmake
     [^
+]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/ParameterCheckConfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/parametercheckconfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/suffix1/ParameterCheckConfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/suffix1/parametercheckconfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/suffix2/ParameterCheckConfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/suffix2/parametercheckconfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/ParameterCheckConfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/parametercheckconfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/suffix1/ParameterCheckConfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/suffix1/parametercheckconfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/suffix2/ParameterCheckConfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/suffix2/parametercheckconfig.cps
+    [^
 ]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/ParameterCheckConfigConfig\.cmake
 
   The file was found at
@@ -220,6 +284,14 @@
 ]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/ParameterCheckConfigConfig\.cmake
     [^
 ]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/parametercheckconfig-config\.cmake
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/ParameterCheckConfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/parametercheckconfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/ParameterCheckConfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/parametercheckconfig.cps
 
   The file was not found\.
 
@@ -296,6 +368,14 @@
     [^
 ]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/parametercheckconfig-config\.cmake
     [^
+]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/ParameterCheckConfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/parametercheckconfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/ParameterCheckConfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/parametercheckconfig.cps
+    [^
 ]*/Tests/RunCMake/find_package/ConfigureLog/ParameterCheckConfigConfig\.cmake
     [^
 ]*/Tests/RunCMake/find_package/ConfigureLog/parametercheckconfig-config\.cmake
@@ -304,6 +384,14 @@
     [^
 ]*/Tests/RunCMake/find_package/ConfigureLog/cmake/parametercheckconfig-config\.cmake
     [^
+]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/ParameterCheckConfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/parametercheckconfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/ParameterCheckConfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/parametercheckconfig.cps
+    [^
 ]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/ParameterCheckConfigConfig\.cmake
 
   The file was found at
@@ -384,6 +472,14 @@
     [^
 ]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/parametercheckconfig-config\.cmake
     [^
+]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/ParameterCheckConfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/parametercheckconfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/ParameterCheckConfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/parametercheckconfig.cps
+    [^
 ]*/Tests/RunCMake/find_package/ConfigureLog/ParameterCheckConfigConfig\.cmake
     [^
 ]*/Tests/RunCMake/find_package/ConfigureLog/parametercheckconfig-config\.cmake
@@ -392,6 +488,14 @@
     [^
 ]*/Tests/RunCMake/find_package/ConfigureLog/cmake/parametercheckconfig-config\.cmake
     [^
+]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/ParameterCheckConfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/parametercheckconfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/ParameterCheckConfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/parametercheckconfig.cps
+    [^
 ]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/ParameterCheckConfigConfig\.cmake
 
   The file was found at
@@ -472,6 +576,14 @@
     [^
 ]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/parametercheckconfig-config\.cmake
     [^
+]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/ParameterCheckConfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/parametercheckconfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/ParameterCheckConfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/parametercheckconfig.cps
+    [^
 ]*/Tests/RunCMake/find_package/ConfigureLog/ParameterCheckConfigConfig\.cmake
     [^
 ]*/Tests/RunCMake/find_package/ConfigureLog/parametercheckconfig-config\.cmake
@@ -480,6 +592,14 @@
     [^
 ]*/Tests/RunCMake/find_package/ConfigureLog/cmake/parametercheckconfig-config\.cmake
     [^
+]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/ParameterCheckConfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/parametercheckconfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/ParameterCheckConfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/parametercheckconfig.cps
+    [^
 ]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/ParameterCheckConfigConfig\.cmake
 
   The file was found at
@@ -564,6 +684,22 @@
     [^
 ]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/parametercheckconfig-config\.cmake
     [^
+]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/BogusParameterCheck.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/bogusparametercheck.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/ParameterCheckConfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/lib/cps/parametercheckconfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/BogusParameterCheck.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/bogusparametercheck.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/ParameterCheckConfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLogParameters2-build/CMakeFiles/pkgRedirects/share/cps/parametercheckconfig.cps
+    [^
 ]*/Tests/RunCMake/find_package/ConfigureLog/BogusParameterCheckConfig\.cmake
     [^
 ]*/Tests/RunCMake/find_package/ConfigureLog/bogusparametercheck-config\.cmake
@@ -580,6 +716,22 @@
     [^
 ]*/Tests/RunCMake/find_package/ConfigureLog/cmake/parametercheckconfig-config\.cmake
     [^
+]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/BogusParameterCheck.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/bogusparametercheck.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/ParameterCheckConfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLog/lib/cps/parametercheckconfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/BogusParameterCheck.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/bogusparametercheck.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/ParameterCheckConfig.cps
+    [^
+]*/Tests/RunCMake/find_package/ConfigureLog/share/cps/parametercheckconfig.cps
+    [^
 ]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/BogusParameterCheckConfig\.cmake
     [^
 ]*/Tests/RunCMake/find_package/ConfigureLog/lib/cmake/ParameterCheckConfig/bogusparametercheck-config\.cmake
diff --git a/Tests/RunCMake/find_package/ConfigureLogTransitionsConfig2-stderr.txt b/Tests/RunCMake/find_package/ConfigureLogTransitionsConfig2-stderr.txt
index 6f8f9f1..7691f6d 100644
--- a/Tests/RunCMake/find_package/ConfigureLogTransitionsConfig2-stderr.txt
+++ b/Tests/RunCMake/find_package/ConfigureLogTransitionsConfig2-stderr.txt
@@ -7,6 +7,8 @@
   Could not find a package configuration file provided by "ViaConfig" with
   any of the following names:
 
+    ViaConfig\.cps
+    viaconfig\.cps
     ViaConfigConfig\.cmake
     viaconfig-config\.cmake
 
@@ -27,6 +29,8 @@
   Could not find a package configuration file provided by "ViaConfig" with
   any of the following names:
 
+    ViaConfig\.cps
+    viaconfig\.cps
     ViaConfigConfig\.cmake
     viaconfig-config\.cmake
 
@@ -49,6 +53,8 @@
   Could not find a package configuration file provided by "ViaConfig" with
   any of the following names:
 
+    ViaConfig\.cps
+    viaconfig\.cps
     ViaConfigConfig\.cmake
     viaconfig-config\.cmake
 
diff --git a/Tests/RunCMake/find_package/ConfigureLogTransitionsConfig2Suppressed-stderr.txt b/Tests/RunCMake/find_package/ConfigureLogTransitionsConfig2Suppressed-stderr.txt
index 88574e3..343e48c 100644
--- a/Tests/RunCMake/find_package/ConfigureLogTransitionsConfig2Suppressed-stderr.txt
+++ b/Tests/RunCMake/find_package/ConfigureLogTransitionsConfig2Suppressed-stderr.txt
@@ -7,6 +7,8 @@
   Could not find a package configuration file provided by "ViaConfig" with
   any of the following names:
 
+    ViaConfig\.cps
+    viaconfig\.cps
     ViaConfigConfig\.cmake
     viaconfig-config\.cmake
 
@@ -27,6 +29,8 @@
   Could not find a package configuration file provided by "ViaConfig" with
   any of the following names:
 
+    ViaConfig\.cps
+    viaconfig\.cps
     ViaConfigConfig\.cmake
     viaconfig-config\.cmake
 
@@ -49,6 +53,8 @@
   Could not find a package configuration file provided by "ViaConfig" with
   any of the following names:
 
+    ViaConfig\.cps
+    viaconfig\.cps
     ViaConfigConfig\.cmake
     viaconfig-config\.cmake
 
diff --git a/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-config.txt b/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-config.txt
index b7cd63a..bd1de84 100644
--- a/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-config.txt
+++ b/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-config.txt
@@ -27,10 +27,16 @@
     name: "ViaModule"
     configs:
       -
-        filename: "ViaModuleConfig.cmake"
+        filename: "ViaModule\.cps"
+        kind: "cps"
+      -
+        filename: "viamodule\.cps"
+        kind: "cps"
+      -
+        filename: "ViaModuleConfig\.cmake"
         kind: "cmake"
       -
-        filename: "viamodule-config.cmake"
+        filename: "viamodule-config\.cmake"
         kind: "cmake"
     version_request:
       exact: false
@@ -56,16 +62,32 @@
         CMAKE_FIND_ROOT_PATH_MODE: "BOTH"
     candidates:
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-build/CMakeFiles/pkgRedirects/ViaModuleConfig.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-build/CMakeFiles/pkgRedirects/ViaModuleConfig\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-build/CMakeFiles/pkgRedirects/viamodule-config.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-build/CMakeFiles/pkgRedirects/viamodule-config\.cmake"
         mode: "config"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-build/CMakeFiles/pkgRedirects/lib/cps/ViaModule\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-build/CMakeFiles/pkgRedirects/lib/cps/viamodule\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-build/CMakeFiles/pkgRedirects/share/cps/ViaModule\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-build/CMakeFiles/pkgRedirects/share/cps/viamodule\.cps"
+        mode: "cps"
         reason: "no_exist"(
       -
-        path: "[^"]*/(viamodule-config|ViaModuleConfig).cmake"
-        mode: "config"
+        path: "[^"]*/((viamodule|ViaModule)\.cps|(viamodule-config|ViaModuleConfig)\.cmake)"
+        mode: "(cps|config)"
         reason: "no_exist")*
     found: null
     search_context:(
@@ -107,10 +129,16 @@
     name: "ViaModule"
     configs:
       -
-        filename: "ViaModuleConfig.cmake"
+        filename: "ViaModule\.cps"
+        kind: "cps"
+      -
+        filename: "viamodule\.cps"
+        kind: "cps"
+      -
+        filename: "ViaModuleConfig\.cmake"
         kind: "cmake"
       -
-        filename: "viamodule-config.cmake"
+        filename: "viamodule-config\.cmake"
         kind: "cmake"
     version_request:
       exact: false
@@ -136,16 +164,32 @@
         CMAKE_FIND_ROOT_PATH_MODE: "BOTH"
     candidates:
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-build/CMakeFiles/pkgRedirects/ViaModuleConfig.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-build/CMakeFiles/pkgRedirects/ViaModuleConfig\.cmake"
         mode: "config"
         reason: "no_exist"
       -
-        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-build/CMakeFiles/pkgRedirects/viamodule-config.cmake"
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-build/CMakeFiles/pkgRedirects/viamodule-config\.cmake"
         mode: "config"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-build/CMakeFiles/pkgRedirects/lib/cps/ViaModule\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-build/CMakeFiles/pkgRedirects/lib/cps/viamodule\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-build/CMakeFiles/pkgRedirects/share/cps/ViaModule\.cps"
+        mode: "cps"
+        reason: "no_exist"
+      -
+        path: "[^"]*/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-build/CMakeFiles/pkgRedirects/share/cps/viamodule\.cps"
+        mode: "cps"
         reason: "no_exist"(
       -
-        path: "[^"]*/(viamodule-config|ViaModuleConfig).cmake"
-        mode: "config"
+        path: "[^"]*/((viamodule|ViaModule)\.cps|(viamodule-config|ViaModuleConfig)\.cmake)"
+        mode: "(cps|config)"
         reason: "no_exist")*
     found: null
     search_context:(
diff --git a/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-stderr.txt b/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-stderr.txt
index de0168b..aa642c4 100644
--- a/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-stderr.txt
+++ b/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2-stderr.txt
@@ -7,6 +7,8 @@
   Could not find a package configuration file provided by "ViaModule" with
   any of the following names:
 
+    ViaModule\.cps
+    viamodule\.cps
     ViaModuleConfig\.cmake
     viamodule-config\.cmake
 
@@ -27,6 +29,8 @@
   Could not find a package configuration file provided by "ViaModule" with
   any of the following names:
 
+    ViaModule\.cps
+    viamodule\.cps
     ViaModuleConfig\.cmake
     viamodule-config\.cmake
 
@@ -49,6 +53,8 @@
   Could not find a package configuration file provided by "ViaModule" with
   any of the following names:
 
+    ViaModule\.cps
+    viamodule\.cps
     ViaModuleConfig\.cmake
     viamodule-config\.cmake
 
diff --git a/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2Suppressed-stderr.txt b/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2Suppressed-stderr.txt
index a41ea03..4895471 100644
--- a/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2Suppressed-stderr.txt
+++ b/Tests/RunCMake/find_package/ConfigureLogTransitionsModule2Suppressed-stderr.txt
@@ -7,6 +7,8 @@
   Could not find a package configuration file provided by "ViaModule" with
   any of the following names:
 
+    ViaModule\.cps
+    viamodule\.cps
     ViaModuleConfig\.cmake
     viamodule-config\.cmake
 
@@ -27,6 +29,8 @@
   Could not find a package configuration file provided by "ViaModule" with
   any of the following names:
 
+    ViaModule\.cps
+    viamodule\.cps
     ViaModuleConfig\.cmake
     viamodule-config\.cmake
 
@@ -49,6 +53,8 @@
   Could not find a package configuration file provided by "ViaModule" with
   any of the following names:
 
+    ViaModule\.cps
+    viamodule\.cps
     ViaModuleConfig\.cmake
     viamodule-config\.cmake
 
diff --git a/Tests/RunCMake/find_package/DebugRoot-stderr.txt b/Tests/RunCMake/find_package/DebugRoot-stderr.txt
index c27c314..512f9ed 100644
--- a/Tests/RunCMake/find_package/DebugRoot-stderr.txt
+++ b/Tests/RunCMake/find_package/DebugRoot-stderr.txt
@@ -41,6 +41,14 @@
     [^
 ]*/Tests/RunCMake/find_package/DebugRoot/NoExist/DebugRoot/debugroot-config\.cmake
     [^
+]*/Tests/RunCMake/find_package/DebugRoot/NoExist/DebugRoot/lib/cps/DebugRoot\.cps
+    [^
+]*/Tests/RunCMake/find_package/DebugRoot/NoExist/DebugRoot/lib/cps/debugroot\.cps
+    [^
+]*/Tests/RunCMake/find_package/DebugRoot/NoExist/DebugRoot/share/cps/DebugRoot\.cps
+    [^
+]*/Tests/RunCMake/find_package/DebugRoot/NoExist/DebugRoot/share/cps/debugroot\.cps
+    [^
 ]*/Tests/RunCMake/find_package/DebugRoot/Exist/DebugRoot/DebugRootConfig\.cmake
 
   The file was found at
diff --git a/Tests/RunCMake/find_package/FromPATHEnv-stderr.txt b/Tests/RunCMake/find_package/FromPATHEnv-stderr.txt
index 19449f1..0df8659 100644
--- a/Tests/RunCMake/find_package/FromPATHEnv-stderr.txt
+++ b/Tests/RunCMake/find_package/FromPATHEnv-stderr.txt
@@ -78,6 +78,14 @@
     [^
 ]*/Tests/RunCMake/find_package/FromPATHEnv-build/CMakeFiles/pkgRedirects/resolved-config\.cmake
     [^
+]*/Tests/RunCMake/find_package/FromPATHEnv-build/CMakeFiles/pkgRedirects/lib/cps/Resolved\.cps
+    [^
+]*/Tests/RunCMake/find_package/FromPATHEnv-build/CMakeFiles/pkgRedirects/lib/cps/resolved\.cps
+    [^
+]*/Tests/RunCMake/find_package/FromPATHEnv-build/CMakeFiles/pkgRedirects/share/cps/Resolved\.cps
+    [^
+]*/Tests/RunCMake/find_package/FromPATHEnv-build/CMakeFiles/pkgRedirects/share/cps/resolved\.cps
+    [^
 ]*/Tests/RunCMake/find_package/PackageRoot/ResolvedConfig\.cmake
 
   The file was found at
diff --git a/Tests/RunCMake/find_package/FromPATHEnvDebugPkg-stderr.txt b/Tests/RunCMake/find_package/FromPATHEnvDebugPkg-stderr.txt
index f0f8e32..368f40c 100644
--- a/Tests/RunCMake/find_package/FromPATHEnvDebugPkg-stderr.txt
+++ b/Tests/RunCMake/find_package/FromPATHEnvDebugPkg-stderr.txt
@@ -78,6 +78,14 @@
     [^
 ]*/Tests/RunCMake/find_package/FromPATHEnvDebugPkg-build/CMakeFiles/pkgRedirects/resolved-config\.cmake
     [^
+]*/Tests/RunCMake/find_package/FromPATHEnvDebugPkg-build/CMakeFiles/pkgRedirects/lib/cps/Resolved\.cps
+    [^
+]*/Tests/RunCMake/find_package/FromPATHEnvDebugPkg-build/CMakeFiles/pkgRedirects/lib/cps/resolved\.cps
+    [^
+]*/Tests/RunCMake/find_package/FromPATHEnvDebugPkg-build/CMakeFiles/pkgRedirects/share/cps/Resolved\.cps
+    [^
+]*/Tests/RunCMake/find_package/FromPATHEnvDebugPkg-build/CMakeFiles/pkgRedirects/share/cps/resolved\.cps
+    [^
 ]*/Tests/RunCMake/find_package/PackageRoot/ResolvedConfig\.cmake
 
   The file was found at
diff --git a/Tests/RunCMake/find_package/MissingConfigRequired-stderr.txt b/Tests/RunCMake/find_package/MissingConfigRequired-stderr.txt
index 363f5de..da58d29 100644
--- a/Tests/RunCMake/find_package/MissingConfigRequired-stderr.txt
+++ b/Tests/RunCMake/find_package/MissingConfigRequired-stderr.txt
@@ -2,6 +2,8 @@
   Could not find a package configuration file provided by "NotHere" with any
   of the following names:
 
+    NotHere\.cps
+    nothere\.cps
     NotHereConfig\.cmake
     nothere-config\.cmake
 
diff --git a/Tests/RunCMake/find_package/MissingNormal-stderr.txt b/Tests/RunCMake/find_package/MissingNormal-stderr.txt
index 9e79ea6..005854c 100644
--- a/Tests/RunCMake/find_package/MissingNormal-stderr.txt
+++ b/Tests/RunCMake/find_package/MissingNormal-stderr.txt
@@ -6,6 +6,8 @@
   Could not find a package configuration file provided by "NotHere" with any
   of the following names:
 
+    NotHere\.cps
+    nothere\.cps
     NotHereConfig\.cmake
     nothere-config\.cmake
 
diff --git a/Tests/RunCMake/find_package/MissingNormalRequired-stderr.txt b/Tests/RunCMake/find_package/MissingNormalRequired-stderr.txt
index e455b2d..6d517d2 100644
--- a/Tests/RunCMake/find_package/MissingNormalRequired-stderr.txt
+++ b/Tests/RunCMake/find_package/MissingNormalRequired-stderr.txt
@@ -6,6 +6,8 @@
   Could not find a package configuration file provided by "NotHere" with any
   of the following names:
 
+    NotHere\.cps
+    nothere\.cps
     NotHereConfig\.cmake
     nothere-config\.cmake
 
diff --git a/Tests/RunCMake/find_package/MissingNormalVersion-stderr.txt b/Tests/RunCMake/find_package/MissingNormalVersion-stderr.txt
index 258cff7..11dc7f1 100644
--- a/Tests/RunCMake/find_package/MissingNormalVersion-stderr.txt
+++ b/Tests/RunCMake/find_package/MissingNormalVersion-stderr.txt
@@ -6,6 +6,8 @@
   Could not find a package configuration file provided by "NotHere"
   \(requested version 1\.2\) with any of the following names:
 
+    NotHere\.cps
+    nothere\.cps
     NotHereConfig\.cmake
     nothere-config\.cmake
 
diff --git a/Tests/RunCMake/find_package/MissingNormalWarnNoModuleNew-stderr.txt b/Tests/RunCMake/find_package/MissingNormalWarnNoModuleNew-stderr.txt
index ee0b337..0d3b5fb 100644
--- a/Tests/RunCMake/find_package/MissingNormalWarnNoModuleNew-stderr.txt
+++ b/Tests/RunCMake/find_package/MissingNormalWarnNoModuleNew-stderr.txt
@@ -19,6 +19,8 @@
   Could not find a package configuration file provided by "NotHere" with any
   of the following names:
 
+    NotHere\.cps
+    nothere\.cps
     NotHereConfig\.cmake
     nothere-config\.cmake
 
diff --git a/Tests/RunCMake/find_package/MissingNormalWarnNoModuleOld-stderr.txt b/Tests/RunCMake/find_package/MissingNormalWarnNoModuleOld-stderr.txt
index 288730a..5f45a51 100644
--- a/Tests/RunCMake/find_package/MissingNormalWarnNoModuleOld-stderr.txt
+++ b/Tests/RunCMake/find_package/MissingNormalWarnNoModuleOld-stderr.txt
@@ -19,6 +19,8 @@
   Could not find a package configuration file provided by "NotHere" with any
   of the following names:
 
+    NotHere\.cps
+    nothere\.cps
     NotHereConfig\.cmake
     nothere-config\.cmake
 
diff --git a/Tests/RunCMake/find_package/ModuleModeDebugPkg-stderr.txt b/Tests/RunCMake/find_package/ModuleModeDebugPkg-stderr.txt
index cd0fc78..ced6175 100644
--- a/Tests/RunCMake/find_package/ModuleModeDebugPkg-stderr.txt
+++ b/Tests/RunCMake/find_package/ModuleModeDebugPkg-stderr.txt
@@ -116,6 +116,14 @@
 ]*/Tests/RunCMake/find_package/ModuleModeDebugPkg-build/CMakeFiles/pkgRedirects/ZotConfig\.cmake
     [^
 ]*/Tests/RunCMake/find_package/ModuleModeDebugPkg-build/CMakeFiles/pkgRedirects/zot-config\.cmake
+    [^
+]*/Tests/RunCMake/find_package/ModuleModeDebugPkg-build/CMakeFiles/pkgRedirects/lib/cps/Zot\.cps
+    [^
+]*/Tests/RunCMake/find_package/ModuleModeDebugPkg-build/CMakeFiles/pkgRedirects/lib/cps/zot\.cps
+    [^
+]*/Tests/RunCMake/find_package/ModuleModeDebugPkg-build/CMakeFiles/pkgRedirects/share/cps/Zot\.cps
+    [^
+]*/Tests/RunCMake/find_package/ModuleModeDebugPkg-build/CMakeFiles/pkgRedirects/share/cps/zot\.cps
 
   The file was not found\.
 
diff --git a/Tests/RunCMake/find_package/PackageVarOverridesOptional-stderr.txt b/Tests/RunCMake/find_package/PackageVarOverridesOptional-stderr.txt
index bec4fba..ca1830f 100644
--- a/Tests/RunCMake/find_package/PackageVarOverridesOptional-stderr.txt
+++ b/Tests/RunCMake/find_package/PackageVarOverridesOptional-stderr.txt
@@ -6,6 +6,8 @@
   Could not find a package configuration file provided by "Foo" with any of
   the following names:
 
+    Foo\.cps
+    foo\.cps
     FooConfig\.cmake
     foo-config\.cmake
 
diff --git a/Tests/RunCMake/find_package/RequiredVarNested-stderr.txt b/Tests/RunCMake/find_package/RequiredVarNested-stderr.txt
index dad7bf6..79354d1 100644
--- a/Tests/RunCMake/find_package/RequiredVarNested-stderr.txt
+++ b/Tests/RunCMake/find_package/RequiredVarNested-stderr.txt
@@ -6,6 +6,8 @@
   Could not find a package configuration file provided by "DoesNotExist" with
   any of the following names:
 
+    DoesNotExist\.cps
+    doesnotexist\.cps
     DoesNotExistConfig\.cmake
     doesnotexist-config\.cmake
 
diff --git a/Tests/RunCMake/find_package/RequiredVarOptional-stderr.txt b/Tests/RunCMake/find_package/RequiredVarOptional-stderr.txt
index 0bb5dd0..a69a2a6 100644
--- a/Tests/RunCMake/find_package/RequiredVarOptional-stderr.txt
+++ b/Tests/RunCMake/find_package/RequiredVarOptional-stderr.txt
@@ -6,6 +6,8 @@
   Could not find a package configuration file provided by "DoesNotExist" with
   any of the following names:
 
+    DoesNotExist\.cps
+    doesnotexist\.cps
     DoesNotExistConfig\.cmake
     doesnotexist-config\.cmake
 
diff --git a/Tests/RunCMake/find_package/UnwindIncludeBlock-stderr.txt b/Tests/RunCMake/find_package/UnwindIncludeBlock-stderr.txt
index 5a80e75..3b48bbf 100644
--- a/Tests/RunCMake/find_package/UnwindIncludeBlock-stderr.txt
+++ b/Tests/RunCMake/find_package/UnwindIncludeBlock-stderr.txt
@@ -6,6 +6,7 @@
   Could not find a package configuration file provided by "foo" with any of
   the following names:
 
+    foo\.cps
     fooConfig\.cmake
     foo-config\.cmake
 
diff --git a/Tests/RunCMake/find_package/UnwindIncludeFunction-stderr.txt b/Tests/RunCMake/find_package/UnwindIncludeFunction-stderr.txt
index 209143b..bd475ee 100644
--- a/Tests/RunCMake/find_package/UnwindIncludeFunction-stderr.txt
+++ b/Tests/RunCMake/find_package/UnwindIncludeFunction-stderr.txt
@@ -6,6 +6,7 @@
   Could not find a package configuration file provided by "foo" with any of
   the following names:
 
+    foo\.cps
     fooConfig\.cmake
     foo-config\.cmake
 
diff --git a/Tests/RunCMake/find_package/UnwindIncludeInvalidFindPackage-stderr.txt b/Tests/RunCMake/find_package/UnwindIncludeInvalidFindPackage-stderr.txt
index 7a33a52..af68586 100644
--- a/Tests/RunCMake/find_package/UnwindIncludeInvalidFindPackage-stderr.txt
+++ b/Tests/RunCMake/find_package/UnwindIncludeInvalidFindPackage-stderr.txt
@@ -6,6 +6,7 @@
   Could not find a package configuration file provided by "foo" with any of
   the following names:
 
+    foo\.cps
     fooConfig\.cmake
     foo-config\.cmake
 
diff --git a/Tests/RunCMake/find_package/UnwindIncludeInvalidInclude-stderr.txt b/Tests/RunCMake/find_package/UnwindIncludeInvalidInclude-stderr.txt
index 6306519..48286aa 100644
--- a/Tests/RunCMake/find_package/UnwindIncludeInvalidInclude-stderr.txt
+++ b/Tests/RunCMake/find_package/UnwindIncludeInvalidInclude-stderr.txt
@@ -6,6 +6,7 @@
   Could not find a package configuration file provided by "foo" with any of
   the following names:
 
+    foo\.cps
     fooConfig\.cmake
     foo-config\.cmake
 
diff --git a/Tests/RunCMake/find_package/UnwindIncludeOnly-stderr.txt b/Tests/RunCMake/find_package/UnwindIncludeOnly-stderr.txt
index 7ca9976..cea39ed 100644
--- a/Tests/RunCMake/find_package/UnwindIncludeOnly-stderr.txt
+++ b/Tests/RunCMake/find_package/UnwindIncludeOnly-stderr.txt
@@ -6,6 +6,7 @@
   Could not find a package configuration file provided by "foo" with any of
   the following names:
 
+    foo\.cps
     fooConfig\.cmake
     foo-config\.cmake
 
diff --git a/Tests/RunCMake/no_install_prefix/no_install_prefix-stderr.txt b/Tests/RunCMake/no_install_prefix/no_install_prefix-stderr.txt
index 038dac2..dedabfe 100644
--- a/Tests/RunCMake/no_install_prefix/no_install_prefix-stderr.txt
+++ b/Tests/RunCMake/no_install_prefix/no_install_prefix-stderr.txt
@@ -6,6 +6,8 @@
   Could not find a package configuration file provided by "NoPrefix" with any
   of the following names:
 
+    NoPrefix\.cps
+    noprefix\.cps
     NoPrefixConfig\.cmake
     noprefix-config\.cmake
 
diff --git a/Tests/RunCMake/project/KeywordProjectName-stderr.txt b/Tests/RunCMake/project/KeywordProjectName-stderr.txt
index a96ac32..73ca463 100644
--- a/Tests/RunCMake/project/KeywordProjectName-stderr.txt
+++ b/Tests/RunCMake/project/KeywordProjectName-stderr.txt
@@ -15,6 +15,22 @@
 This warning is for project developers\.  Use -Wno-dev to suppress it\.
 
 CMake Warning \(dev\) at KeywordProjectName\.cmake:[0-9]+ \(project\):
+  project\(\) called with 'COMPAT_VERSION' as first argument\.  The first
+  parameter should be the project name, not a keyword argument\.  See the
+  cmake-commands\(7\) manual for correct usage of the project\(\) command\.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
+This warning is for project developers\.  Use -Wno-dev to suppress it\.
+
+CMake Warning \(dev\) at KeywordProjectName\.cmake:[0-9]+ \(project\):
+  project\(\) called with 'SPDX_LICENSE' as first argument\.  The first
+  parameter should be the project name, not a keyword argument\.  See the
+  cmake-commands\(7\) manual for correct usage of the project\(\) command\.
+Call Stack \(most recent call first\):
+  CMakeLists\.txt:[0-9]+ \(include\)
+This warning is for project developers\.  Use -Wno-dev to suppress it\.
+
+CMake Warning \(dev\) at KeywordProjectName\.cmake:[0-9]+ \(project\):
   project\(\) called with 'DESCRIPTION' as first argument\.  The first parameter
   should be the project name, not a keyword argument\.  See the
   cmake-commands\(7\) manual for correct usage of the project\(\) command\.
diff --git a/Tests/RunCMake/project/KeywordProjectName.cmake b/Tests/RunCMake/project/KeywordProjectName.cmake
index a8215bc..6e27dd5 100644
--- a/Tests/RunCMake/project/KeywordProjectName.cmake
+++ b/Tests/RunCMake/project/KeywordProjectName.cmake
@@ -1,9 +1,6 @@
 project(LANGUAGES)
 project(VERSION)
+project(COMPAT_VERSION)
+project(SPDX_LICENSE)
 project(DESCRIPTION)
 project(HOMEPAGE_URL)
-
-# CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO=7fa7d13b-8308-4dc7-af39-9e450456d68f
-# Enable these when Package Info is no longer experimental
-# project(COMPAT_VERSION)
-# project(SPDX_LICENSE)
diff --git a/Tests/RunCMake/project/RunCMakeTest.cmake b/Tests/RunCMake/project/RunCMakeTest.cmake
index 9ad4504..e98ce74 100644
--- a/Tests/RunCMake/project/RunCMakeTest.cmake
+++ b/Tests/RunCMake/project/RunCMakeTest.cmake
@@ -36,6 +36,13 @@
   run_cmake(LanguagesUsedButNotEnabled)
 endif()
 run_cmake(ProjectCMP0126)
+run_cmake(ProjectCompatVersion)
+run_cmake(ProjectCompatVersion2)
+run_cmake(ProjectCompatVersionEqual)
+run_cmake(ProjectCompatVersionInvalid)
+run_cmake(ProjectCompatVersionMissingVersion)
+run_cmake(ProjectCompatVersionNewer)
+run_cmake(ProjectCompatVersionNoArg)
 run_cmake(ProjectDescription)
 run_cmake(ProjectDescription2)
 run_cmake(ProjectDescriptionNoArg)
@@ -46,6 +53,10 @@
 run_cmake(ProjectIsTopLevel)
 run_cmake(ProjectIsTopLevelMultiple)
 run_cmake(ProjectIsTopLevelSubdirectory)
+run_cmake(ProjectLicense)
+run_cmake(ProjectLicense2)
+run_cmake(ProjectLicenseNoArg)
+run_cmake(ProjectLicenseNoArg2)
 run_cmake(ProjectTwice)
 run_cmake(Omissions)
 run_cmake(VersionAbsent)
@@ -57,23 +68,6 @@
 run_cmake(VersionTwice)
 run_cmake(VersionMax)
 
-set(opts
-  "-DCMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO=7fa7d13b-8308-4dc7-af39-9e450456d68f"
-  "-Wno-dev"
-)
-
-run_cmake_with_options(ProjectCompatVersion ${opts})
-run_cmake_with_options(ProjectCompatVersion2 ${opts})
-run_cmake_with_options(ProjectCompatVersionEqual ${opts})
-run_cmake_with_options(ProjectCompatVersionInvalid ${opts})
-run_cmake_with_options(ProjectCompatVersionMissingVersion ${opts})
-run_cmake_with_options(ProjectCompatVersionNewer ${opts})
-run_cmake_with_options(ProjectCompatVersionNoArg ${opts})
-run_cmake_with_options(ProjectLicense ${opts})
-run_cmake_with_options(ProjectLicense2 ${opts})
-run_cmake_with_options(ProjectLicenseNoArg ${opts})
-run_cmake_with_options(ProjectLicenseNoArg2 ${opts})
-
 run_cmake(CMP0048-NEW)
 
 run_cmake(CMP0096-WARN)
diff --git a/Tests/RunCMake/string/CaseUTF-8.cmake b/Tests/RunCMake/string/CaseUTF-8.cmake
new file mode 100644
index 0000000..f44e47c
--- /dev/null
+++ b/Tests/RunCMake/string/CaseUTF-8.cmake
@@ -0,0 +1,11 @@
+#                 Chinese Hindi  Greek English Russian
+set(string_mixed "注意    यूनिकोड είναι VeRy    здорово!") # UTF-8
+set(string_upper "注意    यूनिकोड είναι VERY    здорово!") # UTF-8
+set(string_lower "注意    यूनिकोड είναι very    здорово!") # UTF-8
+string(TOLOWER "${string_mixed}" output_lower)
+string(TOUPPER "${string_mixed}" output_upper)
+foreach(case lower upper)
+  if(NOT "${output_${case}}" STREQUAL "${string_${case}}")
+    message(SEND_ERROR "to${case} failed:\n  \"${output_${case}}\"")
+  endif()
+endforeach()
diff --git a/Tests/RunCMake/string/Hex.cmake b/Tests/RunCMake/string/Hex.cmake
index 1c5aaa1..c314156 100644
--- a/Tests/RunCMake/string/Hex.cmake
+++ b/Tests/RunCMake/string/Hex.cmake
@@ -12,7 +12,7 @@
 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")
+set(_input3 "Ash nazg durbatulûk\nAsh nazg gimbatul\nAsh nazg thrakatulûk\nAgh burzum-ishi krimpatul") # UTF-8
 string(HEX "${_input3}" _result3)
 assert_strequal("${_input3}" "${_result3}" "417368206e617a6720647572626174756cc3bb6b0a417368206e617a672067696d626174756c0a417368206e617a6720746872616b6174756cc3bb6b0a416768206275727a756d2d69736869206b72696d706174756c")
 
diff --git a/Tests/RunCMake/string/RunCMakeTest.cmake b/Tests/RunCMake/string/RunCMakeTest.cmake
index f4a6ff8..3da258e 100644
--- a/Tests/RunCMake/string/RunCMakeTest.cmake
+++ b/Tests/RunCMake/string/RunCMakeTest.cmake
@@ -14,6 +14,8 @@
 run_cmake(Prepend)
 run_cmake(PrependNoArgs)
 
+run_cmake_script(CaseUTF-8)
+
 run_cmake(Concat)
 run_cmake(ConcatNoArgs)
 
diff --git a/Utilities/Scripts/update-nghttp2.bash b/Utilities/Scripts/update-nghttp2.bash
index ad7e79b..551044b 100755
--- a/Utilities/Scripts/update-nghttp2.bash
+++ b/Utilities/Scripts/update-nghttp2.bash
@@ -8,7 +8,7 @@
 readonly ownership="nghttp2 upstream <kwrobot@kitware.com>"
 readonly subtree="Utilities/cmnghttp2"
 readonly repo="https://github.com/nghttp2/nghttp2.git"
-readonly tag="v1.52.0" # When updating, sync PACKAGE_VERSION below!
+readonly tag="v1.68.0" # When updating, sync PACKAGE_VERSION below!
 readonly shortlog=false
 readonly exact_tree_match=false
 readonly paths="
@@ -24,7 +24,7 @@
     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.52.0/;s/@PACKAGE_VERSION_NUM@/0x013400/' lib/includes/nghttp2/nghttp2ver.h
+    sed -i 's/@PACKAGE_VERSION@/1.68.0/;s/@PACKAGE_VERSION_NUM@/0x014400/' lib/includes/nghttp2/nghttp2ver.h
     popd
 }
 
diff --git a/Utilities/cmcurl/CMakeLists.txt b/Utilities/cmcurl/CMakeLists.txt
index 0b4b558..2c6a6e6 100644
--- a/Utilities/cmcurl/CMakeLists.txt
+++ b/Utilities/cmcurl/CMakeLists.txt
@@ -82,7 +82,7 @@
 set(ENABLE_DEBUG OFF CACHE INTERNAL "No curl debug features")
 set(ENABLE_IPV6 ON CACHE INTERNAL "Enable curl IPv6 support detection")
 set(ENABLE_THREADED_RESOLVER OFF CACHE INTERNAL "No curl POSIX threaded DNS lookup")
-set(ENABLE_UNICODE OFF)
+set(ENABLE_UNICODE ON)
 set(ENABLE_UNIX_SOCKETS OFF CACHE INTERNAL "No curl Unix domain sockets support")
 set(HAVE_ATOMIC 0)
 set(HAVE_BORINGSSL 0) # we do not need this info
diff --git a/Utilities/cmnghttp2/CMakeLists.txt b/Utilities/cmnghttp2/CMakeLists.txt
index d49693a..ff8de47 100644
--- a/Utilities/cmnghttp2/CMakeLists.txt
+++ b/Utilities/cmnghttp2/CMakeLists.txt
@@ -16,6 +16,7 @@
 configure_file(cmakeconfig.h.in config.h)
 
 add_library(cmnghttp2 STATIC
+  lib/nghttp2_alpn.c
   lib/nghttp2_buf.c
   lib/nghttp2_callbacks.c
   lib/nghttp2_debug.c
@@ -28,17 +29,19 @@
   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_ratelim.c
   lib/nghttp2_rcbuf.c
   lib/nghttp2_session.c
   lib/nghttp2_stream.c
   lib/nghttp2_submit.c
+  lib/nghttp2_time.c
   lib/nghttp2_version.c
+  lib/sfparse.c
   )
 
 target_compile_definitions(cmnghttp2
diff --git a/Utilities/cmnghttp2/lib/includes/nghttp2/nghttp2.h b/Utilities/cmnghttp2/lib/includes/nghttp2/nghttp2.h
index 3f31b89..ff1e576 100644
--- a/Utilities/cmnghttp2/lib/includes/nghttp2/nghttp2.h
+++ b/Utilities/cmnghttp2/lib/includes/nghttp2/nghttp2.h
@@ -51,13 +51,14 @@
 #endif /* !defined(_MSC_VER) || (_MSC_VER >= 1800) */
 #include <sys/types.h>
 #include <stdarg.h>
+#include <stddef.h>
 
 #include "nghttp2ver.h"
 
 #ifdef NGHTTP2_STATICLIB
 #  define NGHTTP2_EXTERN
-#elif defined(WIN32) || (__has_declspec_attribute(dllexport) &&                \
-                         __has_declspec_attribute(dllimport))
+#elif defined(WIN32) ||                                                        \
+  (__has_declspec_attribute(dllexport) && __has_declspec_attribute(dllimport))
 #  ifdef BUILDING_NGHTTP2
 #    define NGHTTP2_EXTERN __declspec(dllexport)
 #  else /* !BUILDING_NGHTTP2 */
@@ -71,6 +72,17 @@
 #  endif /* !BUILDING_NGHTTP2 */
 #endif   /* !defined(WIN32) */
 
+#ifdef BUILDING_NGHTTP2
+#  undef NGHTTP2_NO_SSIZE_T
+#endif /* BUILDING_NGHTTP2 */
+
+/**
+ * @typedef
+ *
+ * :type:`nghttp2_ssize` is a signed counterpart of size_t.
+ */
+typedef ptrdiff_t nghttp2_ssize;
+
 /**
  * @macro
  *
@@ -168,6 +180,12 @@
 /**
  * @macro
  *
+ * .. warning::
+ *
+ *   Deprecated.  :rfc:`7540` priorities are deprecated by
+ *   :rfc:`9113`.  Consider migrating to :rfc:`9218` extensible
+ *   prioritization scheme.
+ *
  * The default weight of stream dependency.
  */
 #define NGHTTP2_DEFAULT_WEIGHT 16
@@ -175,6 +193,12 @@
 /**
  * @macro
  *
+ * .. warning::
+ *
+ *   Deprecated.  :rfc:`7540` priorities are deprecated by
+ *   :rfc:`9113`.  Consider migrating to :rfc:`9218` extensible
+ *   prioritization scheme.
+ *
  * The maximum weight of stream dependency.
  */
 #define NGHTTP2_MAX_WEIGHT 256
@@ -182,6 +206,12 @@
 /**
  * @macro
  *
+ * .. warning::
+ *
+ *   Deprecated.  :rfc:`7540` priorities are deprecated by
+ *   :rfc:`9113`.  Consider migrating to :rfc:`9218` extensible
+ *   prioritization scheme.
+ *
  * The minimum weight of stream dependency.
  */
 #define NGHTTP2_MIN_WEIGHT 1
@@ -255,7 +285,7 @@
    */
   NGHTTP2_ERR_UNSUPPORTED_VERSION = -503,
   /**
-   * Used as a return value from :type:`nghttp2_send_callback`,
+   * Used as a return value from :type:`nghttp2_send_callback2`,
    * :type:`nghttp2_recv_callback` and
    * :type:`nghttp2_send_data_callback` to indicate that the operation
    * would block.
@@ -275,9 +305,9 @@
   NGHTTP2_ERR_EOF = -507,
   /**
    * Used as a return value from
-   * :func:`nghttp2_data_source_read_callback` to indicate that data
+   * :func:`nghttp2_data_source_read_callback2` to indicate that data
    * transfer is postponed.  See
-   * :func:`nghttp2_data_source_read_callback` for details.
+   * :func:`nghttp2_data_source_read_callback2` for details.
    */
   NGHTTP2_ERR_DEFERRED = -508,
   /**
@@ -440,7 +470,12 @@
    * exhaustion on server side to send these frames forever and does
    * not read network.
    */
-  NGHTTP2_ERR_FLOODED = -904
+  NGHTTP2_ERR_FLOODED = -904,
+  /**
+   * When a local endpoint receives too many CONTINUATION frames
+   * following a HEADER frame.
+   */
+  NGHTTP2_ERR_TOO_MANY_CONTINUATIONS = -905,
 } nghttp2_error;
 
 /**
@@ -830,7 +865,7 @@
  * @union
  *
  * This union represents the some kind of data source passed to
- * :type:`nghttp2_data_source_read_callback`.
+ * :type:`nghttp2_data_source_read_callback2`.
  */
 typedef union {
   /**
@@ -847,7 +882,7 @@
  * @enum
  *
  * The flags used to set in |data_flags| output parameter in
- * :type:`nghttp2_data_source_read_callback`.
+ * :type:`nghttp2_data_source_read_callback2`.
  */
 typedef enum {
   /**
@@ -861,8 +896,8 @@
   /**
    * 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()`.
+   * trailer fields with `nghttp2_submit_request2()` or
+   * `nghttp2_submit_response2()`.
    */
   NGHTTP2_DATA_FLAG_NO_END_STREAM = 0x02,
   /**
@@ -872,9 +907,15 @@
   NGHTTP2_DATA_FLAG_NO_COPY = 0x04
 } nghttp2_data_flag;
 
+#ifndef NGHTTP2_NO_SSIZE_T
 /**
  * @functypedef
  *
+ * .. warning::
+ *
+ *   Deprecated.  Use :type:`nghttp2_data_source_read_callback2`
+ *   instead.
+ *
  * 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|
@@ -936,8 +977,101 @@
  * 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);
+  nghttp2_session *session, int32_t stream_id, uint8_t *buf, size_t length,
+  uint32_t *data_flags, nghttp2_data_source *source, void *user_data);
+
+#endif /* NGHTTP2_NO_SSIZE_T */
+
+/**
+ * @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.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.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.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_request2()`,
+ * `nghttp2_submit_response2()` or `nghttp2_submit_headers()` and
+ * `nghttp2_submit_data2()` with flag parameter
+ * :enum:`nghttp2_flag.NGHTTP2_FLAG_END_STREAM` set, and
+ * :enum:`nghttp2_data_flag.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.NGHTTP2_DATA_FLAG_NO_END_STREAM` along
+ * with :enum:`nghttp2_data_flag.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_error.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_send2()` without
+ * sending anything, return :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE`.
+ *
+ * In case of error, there are 2 choices. Returning
+ * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` will
+ * close the stream by issuing RST_STREAM with
+ * :enum:`nghttp2_error_code.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_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`.
+ * Returning :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` will
+ * signal the entire session failure.
+ */
+typedef nghttp2_ssize (*nghttp2_data_source_read_callback2)(
+  nghttp2_session *session, int32_t stream_id, uint8_t *buf, size_t length,
+  uint32_t *data_flags, nghttp2_data_source *source, void *user_data);
+
+#ifndef NGHTTP2_NO_SSIZE_T
+/**
+ * @struct
+ *
+ * .. warning::
+ *
+ *   Deprecated.  Use :type:`nghttp2_data_provider2` instead.
+ *
+ * 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;
+
+#endif /* NGHTTP2_NO_SSIZE_T */
 
 /**
  * @struct
@@ -953,8 +1087,8 @@
   /**
    * The callback function to read a chunk of data from the |source|.
    */
-  nghttp2_data_source_read_callback read_callback;
-} nghttp2_data_provider;
+  nghttp2_data_source_read_callback2 read_callback;
+} nghttp2_data_provider2;
 
 /**
  * @struct
@@ -1008,6 +1142,12 @@
 /**
  * @struct
  *
+ * .. warning::
+ *
+ *   Deprecated.  :rfc:`7540` priorities are deprecated by
+ *   :rfc:`9113`.  Consider migrating to :rfc:`9218` extensible
+ *   prioritization scheme.
+ *
  * The structure to specify stream dependency.
  */
 typedef struct {
@@ -1042,6 +1182,12 @@
    */
   size_t padlen;
   /**
+   * .. warning::
+   *
+   *   Deprecated.  :rfc:`7540` priorities are deprecated by
+   *   :rfc:`9113`.  Consider migrating to :rfc:`9218` extensible
+   *   prioritization scheme.
+   *
    * The priority specification
    */
   nghttp2_priority_spec pri_spec;
@@ -1062,6 +1208,12 @@
 /**
  * @struct
  *
+ * .. warning::
+ *
+ *   Deprecated.  :rfc:`7540` priorities are deprecated by
+ *   :rfc:`9113`.  Consider migrating to :rfc:`9218` extensible
+ *   prioritization scheme.
+ *
  * The PRIORITY frame.  It has the following members:
  */
 typedef struct {
@@ -1305,9 +1457,14 @@
   nghttp2_extension ext;
 } nghttp2_frame;
 
+#ifndef NGHTTP2_NO_SSIZE_T
 /**
  * @functypedef
  *
+ * .. warning::
+ *
+ *   Deprecated.  Use :type:`nghttp2_send_callback2` instead.
+ *
  * 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
@@ -1340,6 +1497,44 @@
                                          const uint8_t *data, size_t length,
                                          int flags, void *user_data);
 
+#endif /* NGHTTP2_NO_SSIZE_T */
+
+/**
+ * @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_error.NGHTTP2_ERR_WOULDBLOCK`.  For
+ * other errors, it must return
+ * :enum:`nghttp2_error.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_send2()` instead,
+ * this callback function is unnecessary.
+ *
+ * To set this callback to :type:`nghttp2_session_callbacks`, use
+ * `nghttp2_session_callbacks_set_send_callback2()`.
+ *
+ * .. 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 nghttp2_ssize (*nghttp2_send_callback2)(nghttp2_session *session,
+                                                const uint8_t *data,
+                                                size_t length, int flags,
+                                                void *user_data);
+
 /**
  * @functypedef
  *
@@ -1370,7 +1565,7 @@
  * 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()`
+ * to make `nghttp2_session_mem_send2()` or `nghttp2_session_send()`
  * return immediately without processing next frames, return
  * :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE`.  If application decided to
  * reset this stream, return
@@ -1387,9 +1582,14 @@
                                           nghttp2_data_source *source,
                                           void *user_data);
 
+#ifndef NGHTTP2_NO_SSIZE_T
 /**
  * @functypedef
  *
+ * .. warning::
+ *
+ *   Deprecated.  Use :type:`nghttp2_recv_callback2` instead.
+ *
  * 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
@@ -1417,11 +1617,43 @@
                                          size_t length, int flags,
                                          void *user_data);
 
+#endif /* NGHTTP2_NO_SSIZE_T */
+
+/**
+ * @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_error.NGHTTP2_ERR_WOULDBLOCK`.  If it gets EOF
+ * before it reads any single byte, it must return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_EOF`.  For other errors, it must
+ * return :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
+ * Returning 0 is treated as
+ * :enum:`nghttp2_error.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_recv2()`
+ * instead, this callback function is unnecessary.
+ *
+ * To set this callback to :type:`nghttp2_session_callbacks`, use
+ * `nghttp2_session_callbacks_set_recv_callback2()`.
+ */
+typedef nghttp2_ssize (*nghttp2_recv_callback2)(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
+ * `nghttp2_session_mem_recv2()` 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()`.
  *
@@ -1439,8 +1671,8 @@
  *
  * 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
+ * `nghttp2_session_recv()` and `nghttp2_session_mem_recv2()`
+ * functions immediately return
  * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
  *
  * To set this callback to :type:`nghttp2_session_callbacks`, use
@@ -1454,7 +1686,7 @@
  * @functypedef
  *
  * Callback function invoked by `nghttp2_session_recv()` and
- * `nghttp2_session_mem_recv()` when an invalid non-DATA frame is
+ * `nghttp2_session_mem_recv2()` 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
@@ -1468,16 +1700,16 @@
  *
  * 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
+ * `nghttp2_session_recv()` and `nghttp2_session_mem_recv2()`
+ * functions immediately return
  * :enum:`nghttp2_error.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);
+  nghttp2_session *session, const nghttp2_frame *frame, int lib_error_code,
+  void *user_data);
 
 /**
  * @functypedef
@@ -1492,19 +1724,19 @@
  * 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_error.NGHTTP2_ERR_PAUSE` to make
- * `nghttp2_session_mem_recv()` return without processing further
+ * If the application uses `nghttp2_session_mem_recv2()`, it can
+ * return :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE` to make
+ * `nghttp2_session_mem_recv2()` 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
+ * `nghttp2_session_mem_recv2()` 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
+ * `nghttp2_session_recv()` and `nghttp2_session_mem_recv2()`
+ * functions immediately return
  * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
  *
  * To set this callback to :type:`nghttp2_session_callbacks`, use
@@ -1531,8 +1763,8 @@
  * If there is a fatal error while executing this callback, the
  * implementation should return
  * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`, which makes
- * `nghttp2_session_send()` and `nghttp2_session_mem_send()` functions
- * immediately return
+ * `nghttp2_session_send()` and `nghttp2_session_mem_send2()`
+ * functions immediately return
  * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
  *
  * If the other value is returned, it is treated as if
@@ -1556,8 +1788,8 @@
  *
  * 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
+ * `nghttp2_session_send()` and `nghttp2_session_mem_send2()`
+ * functions immediately return
  * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
  *
  * To set this callback to :type:`nghttp2_session_callbacks`, use
@@ -1579,8 +1811,8 @@
  *
  * 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
+ * `nghttp2_session_send()` and `nghttp2_session_mem_send2()`
+ * functions immediately return
  * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
  *
  * `nghttp2_session_get_stream_user_data()` can be used to get
@@ -1601,7 +1833,7 @@
  * 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
+ * `nghttp2_submit_request2()` 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()`.
@@ -1610,8 +1842,8 @@
  *
  * 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()`
+ * `nghttp2_session_recv()`, `nghttp2_session_mem_recv2()`,
+ * `nghttp2_session_send()`, and `nghttp2_session_mem_send2()`
  * functions immediately return
  * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
  *
@@ -1681,7 +1913,7 @@
  * value is returned, it is treated as if
  * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` is returned.  If
  * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` is returned,
- * `nghttp2_session_mem_recv()` function will immediately return
+ * `nghttp2_session_mem_recv2()` function will immediately return
  * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
  *
  * To set this callback to :type:`nghttp2_session_callbacks`, use
@@ -1726,11 +1958,11 @@
  * 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_error.NGHTTP2_ERR_PAUSE` to make
- * `nghttp2_session_mem_recv()` return without processing further
+ * If the application uses `nghttp2_session_mem_recv2()`, it can
+ * return :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE` to make
+ * `nghttp2_session_mem_recv2()` return without processing further
  * input bytes.  The memory pointed by |frame|, |name| and |value|
- * parameters are retained until `nghttp2_session_mem_recv()` or
+ * parameters are retained until `nghttp2_session_mem_recv2()` 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.
@@ -1757,8 +1989,8 @@
  * nonzero value is returned, it is treated as
  * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.  If
  * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` is returned,
- * `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
- * immediately return
+ * `nghttp2_session_recv()` and `nghttp2_session_mem_recv2()`
+ * functions immediately return
  * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
  *
  * To set this callback to :type:`nghttp2_session_callbacks`, use
@@ -1807,18 +2039,19 @@
 /**
  * @functypedef
  *
- * Callback function invoked when a invalid header name/value pair is
+ * Callback function invoked when an 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.
+ * callback is only invoked when an invalid header name/value pair is
+ * received which is treated as stream error if this callback returns
+ * :enum:`nghttp2_error.NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE` and
+ * :type:`nghttp2_on_invalid_header_callback2` 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
@@ -1837,24 +2070,25 @@
  * 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);
+  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
+ * Callback function invoked when an 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.
+ * callback is only invoked when an invalid header name/value pair is
+ * received which is silently ignored if neither this callback nor
+ * :type:`nghttp2_on_invalid_header_callback` is 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
@@ -1870,12 +2104,18 @@
  * :enum:`nghttp2_error.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);
+  nghttp2_session *session, const nghttp2_frame *frame, nghttp2_rcbuf *name,
+  nghttp2_rcbuf *value, uint8_t flags, void *user_data);
 
+#ifndef NGHTTP2_NO_SSIZE_T
 /**
  * @functypedef
  *
+ * .. warning::
+ *
+ *   Deprecated.  Use :type:`nghttp2_select_padding_callback2`
+ *   instead.
+ *
  * 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
@@ -1896,9 +2136,39 @@
                                                    size_t max_payloadlen,
                                                    void *user_data);
 
+#endif /* NGHTTP2_NO_SSIZE_T */
+
 /**
  * @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_error.NGHTTP2_ERR_CALLBACK_FAILURE`.  Returning
+ * ``frame->hd.length`` means no padding is added.  Returning
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE` will make
+ * `nghttp2_session_send()` and `nghttp2_session_mem_send2()`
+ * functions immediately return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
+ *
+ * To set this callback to :type:`nghttp2_session_callbacks`, use
+ * `nghttp2_session_callbacks_set_select_padding_callback2()`.
+ */
+typedef nghttp2_ssize (*nghttp2_select_padding_callback2)(
+  nghttp2_session *session, const nghttp2_frame *frame, size_t max_payloadlen,
+  void *user_data);
+
+#ifndef NGHTTP2_NO_SSIZE_T
+/**
+ * @functypedef
+ *
+ * .. warning::
+ *
+ *   Deprecated.  Use
+ *   :type:`nghttp2_data_source_read_length_callback2` instead.
+ *
  * 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,
@@ -1922,9 +2192,41 @@
  * `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);
+  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);
+
+#endif /* NGHTTP2_NO_SSIZE_T */
+
+/**
+ * @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_error.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_frame_type.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_error.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_callback2()`.
+ */
+typedef nghttp2_ssize (*nghttp2_data_source_read_length_callback2)(
+  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
@@ -1942,8 +2244,8 @@
  *
  * 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
+ * `nghttp2_session_recv()` and `nghttp2_session_mem_recv2()`
+ * functions immediately return
  * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
  *
  * To set this callback to :type:`nghttp2_session_callbacks`, use
@@ -1967,15 +2269,15 @@
  *
  * If fatal error occurred, application should return
  * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.  In this case,
- * `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
- * immediately return
+ * `nghttp2_session_recv()` and `nghttp2_session_mem_recv2()`
+ * functions immediately return
  * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.  If the other
  * values are returned, currently they are treated as
  * :enum:`nghttp2_error.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);
+  nghttp2_session *session, const nghttp2_frame_hd *hd, const uint8_t *data,
+  size_t len, void *user_data);
 
 /**
  * @functypedef
@@ -1997,7 +2299,7 @@
  * ``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
+ * callback.  Of course, application has a liberty not to use
  * |*payload|, and do its own mechanism to process extension frames.
  *
  * To abort processing this extension frame, return
@@ -2005,8 +2307,8 @@
  *
  * If fatal error occurred, application should return
  * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.  In this case,
- * `nghttp2_session_recv()` and `nghttp2_session_mem_recv()` functions
- * immediately return
+ * `nghttp2_session_recv()` and `nghttp2_session_mem_recv2()`
+ * functions immediately return
  * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.  If the other
  * values are returned, currently they are treated as
  * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
@@ -2016,9 +2318,15 @@
                                                  const nghttp2_frame_hd *hd,
                                                  void *user_data);
 
+#ifndef NGHTTP2_NO_SSIZE_T
 /**
  * @functypedef
  *
+ * .. warning::
+ *
+ *   Deprecated.  Use :type:`nghttp2_pack_extension_callback2`
+ *   instead.
+ *
  * 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.
@@ -2049,18 +2357,53 @@
                                                    const nghttp2_frame *frame,
                                                    void *user_data);
 
+#endif /* NGHTTP2_NO_SSIZE_T */
+
 /**
  * @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_error.NGHTTP2_ERR_CANCEL`, and
+ * :type:`nghttp2_on_frame_not_send_callback` will be invoked.
+ *
+ * If fatal error occurred, application should return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.  In this case,
+ * `nghttp2_session_send()` and `nghttp2_session_mem_send2()`
+ * functions immediately return
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.  If the other
+ * values are returned, currently they are treated as
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.  If the return
+ * value is strictly larger than |len|, it is treated as
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`.
+ */
+typedef nghttp2_ssize (*nghttp2_pack_extension_callback2)(
+  nghttp2_session *session, uint8_t *buf, size_t len,
+  const nghttp2_frame *frame, void *user_data);
+
+/**
+ * @functypedef
+ *
+ * .. warning::
+ *
+ *   Deprecated.  Use :type:`nghttp2_error_callback2` instead.
+ *
  * 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.
@@ -2104,6 +2447,15 @@
                                        int lib_error_code, const char *msg,
                                        size_t len, void *user_data);
 
+/**
+ * @functypedef
+ *
+ * Callback function invoked when unpredictable data of |destlen|
+ * bytes are needed.  The implementation must write unpredictable data
+ * of |destlen| bytes into the buffer pointed by |dest|.
+ */
+typedef void (*nghttp2_rand_callback)(uint8_t *dest, size_t destlen);
+
 struct nghttp2_session_callbacks;
 
 /**
@@ -2143,49 +2495,87 @@
 NGHTTP2_EXTERN void
 nghttp2_session_callbacks_del(nghttp2_session_callbacks *callbacks);
 
+#ifndef NGHTTP2_NO_SSIZE_T
 /**
  * @function
  *
+ * .. warning::
+ *
+ *   Deprecated.  Use `nghttp2_session_callbacks_set_send_callback2()`
+ *   with :type:`nghttp2_send_callback2` instead.
+ *
  * 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);
+  nghttp2_session_callbacks *cbs, nghttp2_send_callback send_callback);
+
+#endif /* NGHTTP2_NO_SSIZE_T */
 
 /**
  * @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_send2()` to serialize data to
+ * transmit.
+ */
+NGHTTP2_EXTERN void nghttp2_session_callbacks_set_send_callback2(
+  nghttp2_session_callbacks *cbs, nghttp2_send_callback2 send_callback);
+
+#ifndef NGHTTP2_NO_SSIZE_T
+/**
+ * @function
+ *
+ * .. warning::
+ *
+ *   Deprecated.  Use `nghttp2_session_callbacks_set_recv_callback2()`
+ *   with :type:`nghttp2_recv_callback2` instead.
+ *
  * 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);
+  nghttp2_session_callbacks *cbs, nghttp2_recv_callback recv_callback);
+
+#endif /* NGHTTP2_NO_SSIZE_T */
+
+/**
+ * @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_recv2()` to process
+ * received data.
+ */
+NGHTTP2_EXTERN void nghttp2_session_callbacks_set_recv_callback2(
+  nghttp2_session_callbacks *cbs, nghttp2_recv_callback2 recv_callback);
 
 /**
  * @function
  *
  * Sets callback function invoked by `nghttp2_session_recv()` and
- * `nghttp2_session_mem_recv()` when a frame is received.
+ * `nghttp2_session_mem_recv2()` 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);
+  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
+ * `nghttp2_session_mem_recv2()` 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);
+  nghttp2_session_callbacks *cbs,
+  nghttp2_on_invalid_frame_recv_callback on_invalid_frame_recv_callback);
 
 /**
  * @function
@@ -2194,8 +2584,8 @@
  * 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);
+  nghttp2_session_callbacks *cbs,
+  nghttp2_on_data_chunk_recv_callback on_data_chunk_recv_callback);
 
 /**
  * @function
@@ -2203,8 +2593,8 @@
  * 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);
+  nghttp2_session_callbacks *cbs,
+  nghttp2_before_frame_send_callback before_frame_send_callback);
 
 /**
  * @function
@@ -2212,8 +2602,8 @@
  * 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);
+  nghttp2_session_callbacks *cbs,
+  nghttp2_on_frame_send_callback on_frame_send_callback);
 
 /**
  * @function
@@ -2222,8 +2612,8 @@
  * 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);
+  nghttp2_session_callbacks *cbs,
+  nghttp2_on_frame_not_send_callback on_frame_not_send_callback);
 
 /**
  * @function
@@ -2231,8 +2621,8 @@
  * 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);
+  nghttp2_session_callbacks *cbs,
+  nghttp2_on_stream_close_callback on_stream_close_callback);
 
 /**
  * @function
@@ -2241,8 +2631,8 @@
  * 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);
+  nghttp2_session_callbacks *cbs,
+  nghttp2_on_begin_headers_callback on_begin_headers_callback);
 
 /**
  * @function
@@ -2254,8 +2644,8 @@
  * 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);
+  nghttp2_session_callbacks *cbs,
+  nghttp2_on_header_callback on_header_callback);
 
 /**
  * @function
@@ -2264,31 +2654,51 @@
  * received.
  */
 NGHTTP2_EXTERN void nghttp2_session_callbacks_set_on_header_callback2(
-    nghttp2_session_callbacks *cbs,
-    nghttp2_on_header_callback2 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
+ * Sets callback function invoked when an 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);
+  nghttp2_session_callbacks *cbs,
+  nghttp2_on_invalid_header_callback on_invalid_header_callback);
 
 /**
  * @function
  *
- * Sets callback function invoked when a invalid header name/value
+ * Sets callback function invoked when an 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);
+  nghttp2_session_callbacks *cbs,
+  nghttp2_on_invalid_header_callback2 on_invalid_header_callback2);
+
+#ifndef NGHTTP2_NO_SSIZE_T
+/**
+ * @function
+ *
+ * .. warning::
+ *
+ *   Deprecated.  Use
+ *   `nghttp2_session_callbacks_set_select_padding_callback2()` with
+ *   :type:`nghttp2_select_padding_callback2` instead.
+ *
+ * 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);
+
+#endif /* NGHTTP2_NO_SSIZE_T */
 
 /**
  * @function
@@ -2297,20 +2707,40 @@
  * 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);
+NGHTTP2_EXTERN void nghttp2_session_callbacks_set_select_padding_callback2(
+  nghttp2_session_callbacks *cbs,
+  nghttp2_select_padding_callback2 select_padding_callback);
 
+#ifndef NGHTTP2_NO_SSIZE_T
 /**
  * @function
  *
+ * .. warning::
+ *
+ *   Deprecated.  Use
+ *   `nghttp2_session_callbacks_set_data_source_read_length_callback2()`
+ *   with :type:`nghttp2_data_source_read_length_callback2` instead.
+ *
  * 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);
+  nghttp2_session_callbacks *cbs,
+  nghttp2_data_source_read_length_callback data_source_read_length_callback);
+
+#endif /* NGHTTP2_NO_SSIZE_T */
+
+/**
+ * @function
+ *
+ * Sets callback function determine the length allowed in
+ * :type:`nghttp2_data_source_read_callback2`.
+ */
+NGHTTP2_EXTERN void
+nghttp2_session_callbacks_set_data_source_read_length_callback2(
+  nghttp2_session_callbacks *cbs,
+  nghttp2_data_source_read_length_callback2 data_source_read_length_callback);
 
 /**
  * @function
@@ -2318,19 +2748,38 @@
  * 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);
+  nghttp2_session_callbacks *cbs,
+  nghttp2_on_begin_frame_callback on_begin_frame_callback);
 
 /**
  * @function
  *
  * Sets callback function invoked when
  * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_NO_COPY` is used in
- * :type:`nghttp2_data_source_read_callback` to avoid data copy.
+ * :type:`nghttp2_data_source_read_callback2` 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);
+  nghttp2_session_callbacks *cbs,
+  nghttp2_send_data_callback send_data_callback);
+
+#ifndef NGHTTP2_NO_SSIZE_T
+/**
+ * @function
+ *
+ * .. warning::
+ *
+ *   Deprecated.  Use
+ *   `nghttp2_session_callbacks_set_pack_extension_callback2()` with
+ *   :type:`nghttp2_pack_extension_callback2` instead.
+ *
+ * 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);
+
+#endif /* NGHTTP2_NO_SSIZE_T */
 
 /**
  * @function
@@ -2338,9 +2787,9 @@
  * 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);
+NGHTTP2_EXTERN void nghttp2_session_callbacks_set_pack_extension_callback2(
+  nghttp2_session_callbacks *cbs,
+  nghttp2_pack_extension_callback2 pack_extension_callback);
 
 /**
  * @function
@@ -2349,8 +2798,8 @@
  * 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);
+  nghttp2_session_callbacks *cbs,
+  nghttp2_unpack_extension_callback unpack_extension_callback);
 
 /**
  * @function
@@ -2360,24 +2809,27 @@
  */
 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);
+  nghttp2_session_callbacks *cbs,
+  nghttp2_on_extension_chunk_recv_callback on_extension_chunk_recv_callback);
 
 /**
  * @function
  *
+ * .. warning::
+ *
+ *   Deprecated.  Use
+ *   `nghttp2_session_callbacks_set_error_callback2()` with
+ *   :type:`nghttp2_error_callback2` instead.
+ *
  * 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);
+  nghttp2_session_callbacks *cbs, nghttp2_error_callback error_callback);
 
 /**
  * @function
@@ -2390,7 +2842,19 @@
  * precedence.
  */
 NGHTTP2_EXTERN void nghttp2_session_callbacks_set_error_callback2(
-    nghttp2_session_callbacks *cbs, nghttp2_error_callback2 error_callback2);
+  nghttp2_session_callbacks *cbs, nghttp2_error_callback2 error_callback2);
+
+/**
+ * @function
+ *
+ * Sets callback function invoked when unpredictable data is needed.
+ * Although this callback is optional due to the backward
+ * compatibility, it is recommended to specify it to harden the
+ * runtime behavior against suspicious activities of a remote
+ * endpoint.
+ */
+NGHTTP2_EXTERN void nghttp2_session_callbacks_set_rand_callback(
+  nghttp2_session_callbacks *cbs, nghttp2_rand_callback rand_callback);
 
 /**
  * @functypedef
@@ -2568,7 +3032,7 @@
  *
  * 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
+ * and `nghttp2_session_mem_recv2()` will return error
  * :enum:`nghttp2_error.NGHTTP2_ERR_BAD_CLIENT_MAGIC`, which is fatal
  * error.
  */
@@ -2692,14 +3156,12 @@
 /**
  * @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.
+ * .. warning::
  *
- * If
- * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES`
- * of value of 1 is submitted via `nghttp2_submit_settings()`, any
- * closed streams are not retained regardless of this option.
+ *   Deprecated.  Closed streams are not retained anymore.
+ *
+ * This function works as before, but it does not take any effect
+ * against :type:`nghttp2_session`.
  */
 NGHTTP2_EXTERN void nghttp2_option_set_no_closed_streams(nghttp2_option *option,
                                                          int val);
@@ -2729,16 +3191,11 @@
 /**
  * @function
  *
- * This option, if set to nonzero, allows server to fallback to
- * :rfc:`7540` priorities if SETTINGS_NO_RFC7540_PRIORITIES was not
- * received from client, and server submitted
- * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES`
- * = 1 via `nghttp2_submit_settings()`.  Most of the advanced
- * functionality for RFC 7540 priorities are still disabled.  This
- * fallback only enables the minimal feature set of RFC 7540
- * priorities to deal with priority signaling from client.
+ * .. warning::
+ *    Deprecated.  :rfc:`7540` priorities have been removed.
  *
- * Client session ignores this option.
+ * This function works as before, but it does not take any effect
+ * against :type:`nghttp2_session`.
  */
 NGHTTP2_EXTERN void
 nghttp2_option_set_server_fallback_rfc7540_priorities(nghttp2_option *option,
@@ -2754,7 +3211,52 @@
  */
 NGHTTP2_EXTERN void
 nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation(
-    nghttp2_option *option, int val);
+  nghttp2_option *option, int val);
+
+/**
+ * @function
+ *
+ * This function sets the rate limit for the incoming stream reset
+ * (RST_STREAM frame).  It is server use only.  It is a token-bucket
+ * based rate limiter.  |burst| specifies the number of tokens that is
+ * initially available.  The maximum number of tokens is capped to
+ * this value.  |rate| specifies the number of tokens that are
+ * regenerated per second.  An incoming RST_STREAM consumes one token.
+ * If there is no token available, GOAWAY is sent to tear down the
+ * connection.  |burst| and |rate| default to 1000 and 33
+ * respectively.
+ */
+NGHTTP2_EXTERN void
+nghttp2_option_set_stream_reset_rate_limit(nghttp2_option *option,
+                                           uint64_t burst, uint64_t rate);
+
+/**
+ * @function
+ *
+ * This function sets the maximum number of CONTINUATION frames
+ * following an incoming HEADER frame.  If more than those frames are
+ * received, the remote endpoint is considered to be misbehaving and
+ * session will be closed.  The default value is 8.
+ */
+NGHTTP2_EXTERN void nghttp2_option_set_max_continuations(nghttp2_option *option,
+                                                         size_t val);
+
+/**
+ * @function
+ *
+ * This function sets the rate limit for the "glitches", the
+ * suspicious activities from a remote endpoint.  It is a token-bucket
+ * based rate limiter.  |burst| specifies the number of tokens that is
+ * initially available.  The maximum number of tokens is capped to
+ * this value.  |rate| specifies the number of tokens that are
+ * regenerated per second.  When a suspicious activity is detected,
+ * some amount of tokens are consumed.  If there is no token
+ * available, GOAWAY is sent to tear down the connection.  |burst| and
+ * |rate| default to 1000 and 33 respectively.
+ */
+NGHTTP2_EXTERN void nghttp2_option_set_glitch_rate_limit(nghttp2_option *option,
+                                                         uint64_t burst,
+                                                         uint64_t rate);
 
 /**
  * @function
@@ -2764,7 +3266,7 @@
  * 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
+ * The :type:`nghttp2_send_callback2` 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``.
@@ -2790,7 +3292,7 @@
  * 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
+ * The :type:`nghttp2_send_callback2` 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``.
@@ -2882,8 +3384,8 @@
  *     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);
+  nghttp2_session **session_ptr, const nghttp2_session_callbacks *callbacks,
+  void *user_data, const nghttp2_option *option, nghttp2_mem *mem);
 
 /**
  * @function
@@ -2907,8 +3409,8 @@
  *     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);
+  nghttp2_session **session_ptr, const nghttp2_session_callbacks *callbacks,
+  void *user_data, const nghttp2_option *option, nghttp2_mem *mem);
 
 /**
  * @function
@@ -2926,7 +3428,7 @@
  * This function retrieves the highest prioritized frame from the
  * outbound queue and sends it to the remote peer.  It does this as
  * many times as possible until the user callback
- * :type:`nghttp2_send_callback` returns
+ * :type:`nghttp2_send_callback2` returns
  * :enum:`nghttp2_error.NGHTTP2_ERR_WOULDBLOCK`, the outbound queue
  * becomes empty or flow control is triggered (remote window size
  * becomes depleted or maximum number of concurrent streams is
@@ -2956,7 +3458,7 @@
  *    :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
+ * 8. :type:`nghttp2_send_callback2` is invoked one or more times to
  *    send the frame.
  *
  * 9. :type:`nghttp2_on_frame_send_callback` is invoked.
@@ -2975,9 +3477,14 @@
  */
 NGHTTP2_EXTERN int nghttp2_session_send(nghttp2_session *session);
 
+#ifndef NGHTTP2_NO_SSIZE_T
 /**
  * @function
  *
+ * .. warning::
+ *
+ *   Deprecated.  Use `nghttp2_session_mem_send2()` instead.
+ *
  * Returns the serialized data to send.
  *
  * This function behaves like `nghttp2_session_send()` except that it
@@ -3017,6 +3524,50 @@
 NGHTTP2_EXTERN ssize_t nghttp2_session_mem_send(nghttp2_session *session,
                                                 const uint8_t **data_ptr);
 
+#endif /* NGHTTP2_NO_SSIZE_T */
+
+/**
+ * @function
+ *
+ * Returns the serialized data to send.
+ *
+ * This function behaves like `nghttp2_session_send()` except that it
+ * does not use :type:`nghttp2_send_callback2` 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_send2()` 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_error.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 nghttp2_ssize
+nghttp2_session_mem_send2(nghttp2_session *session, const uint8_t **data_ptr);
+
 /**
  * @function
  *
@@ -3087,9 +3638,14 @@
  */
 NGHTTP2_EXTERN int nghttp2_session_recv(nghttp2_session *session);
 
+#ifndef NGHTTP2_NO_SSIZE_T
 /**
  * @function
  *
+ * .. warning::
+ *
+ *   Deprecated.  Use `nghttp2_session_mem_recv2()` instead.
+ *
  * Processes data |in| as an input from the remote endpoint.  The
  * |inlen| indicates the number of bytes to receive in the |in|.
  *
@@ -3128,6 +3684,49 @@
                                                 const uint8_t *in,
                                                 size_t inlen);
 
+#endif /* NGHTTP2_NO_SSIZE_T */
+
+/**
+ * @function
+ *
+ * Processes data |in| as an input from the remote endpoint.  The
+ * |inlen| indicates the number of bytes to receive 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 |inlen| bytes of input data unless either an error occurs or
+ * :enum:`nghttp2_error.NGHTTP2_ERR_PAUSE` is returned from
+ * :type:`nghttp2_on_header_callback` or
+ * :type:`nghttp2_on_data_chunk_recv_callback`.  If
+ * :enum:`nghttp2_error.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_error.NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_CALLBACK_FAILURE`
+ *     The callback function failed.
+ * :enum:`nghttp2_error.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_error.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 nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
+                                                       const uint8_t *in,
+                                                       size_t inlen);
+
 /**
  * @function
  *
@@ -3173,7 +3772,7 @@
  * @function
  *
  * Returns stream_user_data for the stream |stream_id|.  The
- * stream_user_data is provided by `nghttp2_submit_request()`,
+ * stream_user_data is provided by `nghttp2_submit_request2()`,
  * `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
@@ -3241,7 +3840,7 @@
  * 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);
+  nghttp2_session *session, int32_t stream_id);
 
 /**
  * @function
@@ -3261,7 +3860,7 @@
  * 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);
+  nghttp2_session *session, int32_t stream_id);
 
 /**
  * @function
@@ -3276,7 +3875,7 @@
  * 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);
+  nghttp2_session *session, int32_t stream_id);
 
 /**
  * @function
@@ -3344,7 +3943,7 @@
  * 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);
+  nghttp2_session *session, int32_t stream_id);
 
 /**
  * @function
@@ -3498,7 +4097,7 @@
  * :enum:`nghttp2_settings_id`.
  */
 NGHTTP2_EXTERN uint32_t nghttp2_session_get_remote_settings(
-    nghttp2_session *session, nghttp2_settings_id id);
+  nghttp2_session *session, nghttp2_settings_id id);
 
 /**
  * @function
@@ -3508,7 +4107,7 @@
  * in :enum:`nghttp2_settings_id`.
  */
 NGHTTP2_EXTERN uint32_t nghttp2_session_get_local_settings(
-    nghttp2_session *session, nghttp2_settings_id id);
+  nghttp2_session *session, nghttp2_settings_id id);
 
 /**
  * @function
@@ -3609,36 +4208,13 @@
 /**
  * @function
  *
- * Changes priority of existing stream denoted by |stream_id|.  The
- * new priority specification is |pri_spec|.
+ * .. warning::
  *
- * 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.
+ *   Deprecated.  :rfc:`7540` priorities are deprecated by
+ *   :rfc:`9113`.  Consider migrating to :rfc:`9218` extensible
+ *   prioritization scheme.
  *
- * 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.
- *
- * If
- * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES`
- * of value of 1 is submitted via `nghttp2_submit_settings()`, this
- * function does nothing and returns 0.
- *
- * This function returns 0 if it succeeds, or one of the following
- * negative error codes:
- *
- * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
- *     Out of memory.
- * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
- *     Attempted to depend on itself; or no stream exist for the given
- *     |stream_id|; or |stream_id| is 0
+ * This function is noop.  It always returns 0.
  */
 NGHTTP2_EXTERN int
 nghttp2_session_change_stream_priority(nghttp2_session *session,
@@ -3648,48 +4224,13 @@
 /**
  * @function
  *
- * Creates idle stream with the given |stream_id|, and priority
- * |pri_spec|.
+ * .. warning::
  *
- * 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.
+ *   Deprecated.  :rfc:`7540` priorities are deprecated by
+ *   :rfc:`9113`.  Consider migrating to :rfc:`9218` extensible
+ *   prioritization scheme.
  *
- * 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.
- *
- * If
- * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES`
- * of value of 1 is submitted via `nghttp2_submit_settings()`, this
- * function does nothing and returns 0.
- *
- * This function returns 0 if it succeeds, or one of the following
- * negative error codes:
- *
- * :enum:`nghttp2_error.NGHTTP2_ERR_NOMEM`
- *     Out of memory.
- * :enum:`nghttp2_error.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
+ * This function is noop.  It always returns 0.
  */
 NGHTTP2_EXTERN int
 nghttp2_session_create_idle_stream(nghttp2_session *session, int32_t stream_id,
@@ -3698,10 +4239,6 @@
 /**
  * @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
@@ -3713,6 +4250,10 @@
  *   HEAD is used in request, the length of response body must be 0
  *   regardless of value included in content-length header field.
  *
+ * 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
@@ -3792,6 +4333,37 @@
                                             int head_request,
                                             void *stream_user_data);
 
+#ifndef NGHTTP2_NO_SSIZE_T
+/**
+ * @function
+ *
+ * .. warning::
+ *
+ *   Deprecated.  Use `nghttp2_pack_settings_payload2()` instead.
+ *
+ * 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_error.NGHTTP2_ERR_INVALID_ARGUMENT`
+ *     The |iv| contains duplicate settings ID or invalid value.
+ *
+ * :enum:`nghttp2_error.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);
+
+#endif /* NGHTTP2_NO_SSIZE_T */
+
 /**
  * @function
  *
@@ -3813,8 +4385,8 @@
  * :enum:`nghttp2_error.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);
+NGHTTP2_EXTERN nghttp2_ssize nghttp2_pack_settings_payload2(
+  uint8_t *buf, size_t buflen, const nghttp2_settings_entry *iv, size_t niv);
 
 /**
  * @function
@@ -3837,6 +4409,12 @@
 /**
  * @function
  *
+ * .. warning::
+ *
+ *   Deprecated.  :rfc:`7540` priorities are deprecated by
+ *   :rfc:`9113`.  Consider migrating to :rfc:`9218` extensible
+ *   prioritization scheme.
+ *
  * 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.
@@ -3851,6 +4429,12 @@
 /**
  * @function
  *
+ * .. warning::
+ *
+ *   Deprecated.  :rfc:`7540` priorities are deprecated by
+ *   :rfc:`9113`.  Consider migrating to :rfc:`9218` extensible
+ *   prioritization scheme.
+ *
  * Initializes |pri_spec| with the default values.  The default values
  * are: stream_id = 0, weight = :macro:`NGHTTP2_DEFAULT_WEIGHT` and
  * exclusive = 0.
@@ -3861,33 +4445,28 @@
 /**
  * @function
  *
+ * .. warning::
+ *
+ *   Deprecated.  :rfc:`7540` priorities are deprecated by
+ *   :rfc:`9113`.  Consider migrating to :rfc:`9218` extensible
+ *   prioritization scheme.
+ *
  * 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);
 
+#ifndef NGHTTP2_NO_SSIZE_T
 /**
  * @function
  *
+ * .. warning::
+ *
+ *   Deprecated.  Use `nghttp2_submit_request2()` instead.
+ *
  * 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 [:macro:`NGHTTP2_MIN_WEIGHT`,
- * :macro:`NGHTTP2_MAX_WEIGHT`], inclusive.  If ``pri_spec->weight``
- * is strictly less than :macro:`NGHTTP2_MIN_WEIGHT`, it becomes
- * :macro:`NGHTTP2_MIN_WEIGHT`.  If it is strictly greater than
- * :macro:`NGHTTP2_MAX_WEIGHT`, it becomes
- * :macro:`NGHTTP2_MAX_WEIGHT`.
- *
- * If
- * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES`
- * of value of 1 is received by a remote endpoint, |pri_spec| is
- * ignored, and treated as if ``NULL`` is specified.
+ * The |pri_spec| is ignored.
  *
  * The |nva| is an array of name/value pair :type:`nghttp2_nv` with
  * |nvlen| elements.  The application is responsible to include
@@ -3930,9 +4509,6 @@
  * :enum:`nghttp2_error.NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE`
  *     No stream ID is available because maximum stream ID was
  *     reached.
- * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
- *     Trying to depend on itself (new stream ID equals
- *     ``pri_spec->stream_id``).
  * :enum:`nghttp2_error.NGHTTP2_ERR_PROTO`
  *     The |session| is server session.
  *
@@ -3949,13 +4525,88 @@
  *
  */
 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);
+  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);
+
+#endif /* NGHTTP2_NO_SSIZE_T */
 
 /**
  * @function
  *
+ * Submits HEADERS frame and optionally one or more DATA frames.
+ *
+ * The |pri_spec| is ignored.
+ *
+ * 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.NGHTTP2_NV_FLAG_NO_COPY_NAME` and
+ * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set,
+ * header field name and value are not copied respectively.  With
+ * :enum:`nghttp2_nv_flag.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_error.NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_STREAM_ID_NOT_AVAILABLE`
+ *     No stream ID is available because maximum stream ID was
+ *     reached.
+ * :enum:`nghttp2_error.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_request2(
+  nghttp2_session *session, const nghttp2_priority_spec *pri_spec,
+  const nghttp2_nv *nva, size_t nvlen, const nghttp2_data_provider2 *data_prd,
+  void *stream_user_data);
+
+#ifndef NGHTTP2_NO_SSIZE_T
+/**
+ * @function
+ *
+ * .. warning::
+ *
+ *   Deprecated.  Use `nghttp2_submit_response2()` instead.
+ *
  * Submits response HEADERS frame and optionally one or more DATA
  * frames against the stream |stream_id|.
  *
@@ -4022,6 +4673,77 @@
                         const nghttp2_nv *nva, size_t nvlen,
                         const nghttp2_data_provider *data_prd);
 
+#endif /* NGHTTP2_NO_SSIZE_T */
+
+/**
+ * @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.NGHTTP2_NV_FLAG_NO_COPY_NAME` and
+ * :enum:`nghttp2_nv_flag.NGHTTP2_NV_FLAG_NO_COPY_VALUE` are set,
+ * header field name and value are not copied respectively.  With
+ * :enum:`nghttp2_nv_flag.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_error.NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
+ *     The |stream_id| is 0.
+ * :enum:`nghttp2_error.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_response2()` twice,
+ *     this may happen.
+ * :enum:`nghttp2_error.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_response2(nghttp2_session *session, int32_t stream_id,
+                         const nghttp2_nv *nva, size_t nvlen,
+                         const nghttp2_data_provider2 *data_prd);
+
 /**
  * @function
  *
@@ -4047,22 +4769,23 @@
  * 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.
+ * submission (usually by `nghttp2_submit_response2()`), 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.NGHTTP2_FLAG_END_STREAM` and both
  * pri_spec and stream_user_data to NULL.
  *
- * To submit trailer fields after `nghttp2_submit_response()` is
+ * To submit trailer fields after `nghttp2_submit_response2()` 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
+ * :type:`nghttp2_data_provider2` to `nghttp2_submit_response2()`.
+ * Inside of :type:`nghttp2_data_source_read_callback2`, when setting
  * :enum:`nghttp2_data_flag.NGHTTP2_DATA_FLAG_EOF`, also set
  * :enum:`nghttp2_data_flag.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`.
+ * inside :type:`nghttp2_data_source_read_callback2`.
  *
  * This function returns 0 if it succeeds and |stream_id| is -1.
  * Otherwise, this function returns 0 if it succeeds, or one of the
@@ -4097,22 +4820,7 @@
  * 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 [:macro:`NGHTTP2_MIN_WEIGHT`,
- * :macro:`NGHTTP2_MAX_WEIGHT`], inclusive.  If ``pri_spec->weight``
- * is strictly less than :macro:`NGHTTP2_MIN_WEIGHT`, it becomes
- * :macro:`NGHTTP2_MIN_WEIGHT`.  If it is strictly greater than
- * :macro:`NGHTTP2_MAX_WEIGHT`, it becomes :macro:`NGHTTP2_MAX_WEIGHT`.
- *
- * If
- * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES`
- * of value of 1 is received by a remote endpoint, |pri_spec| is
- * ignored, and treated as if ``NULL`` is specified.
+ * The |pri_spec| is ignored.
  *
  * The |nva| is an array of name/value pair :type:`nghttp2_nv` with
  * |nvlen| elements.  The application is responsible to include
@@ -4139,8 +4847,8 @@
  *
  * 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()`.
+ * `nghttp2_submit_request2()` is useful.  Likewise, for HTTP
+ * response, prefer `nghttp2_submit_response2()`.
  *
  * This function returns newly assigned stream ID if it succeeds and
  * |stream_id| is -1.  Otherwise, this function returns 0 if it
@@ -4152,8 +4860,7 @@
  *     No stream ID is available because maximum stream ID was
  *     reached.
  * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
- *     The |stream_id| is 0; or trying to depend on itself (stream ID
- *     equals ``pri_spec->stream_id``).
+ *     The |stream_id| is 0.
  * :enum:`nghttp2_error.NGHTTP2_ERR_DATA_EXIST`
  *     DATA or HEADERS has been already submitted and not fully
  *     processed yet.  This happens if stream denoted by |stream_id|
@@ -4171,13 +4878,18 @@
  *
  */
 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);
+  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);
 
+#ifndef NGHTTP2_NO_SSIZE_T
 /**
  * @function
  *
+ * .. warning::
+ *
+ *   Deprecated.  Use `nghttp2_submit_data2()` instead.
+ *
  * 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.NGHTTP2_FLAG_END_STREAM`, the last DATA frame
@@ -4220,40 +4932,63 @@
                                        int32_t stream_id,
                                        const nghttp2_data_provider *data_prd);
 
+#endif /* NGHTTP2_NO_SSIZE_T */
+
 /**
  * @function
  *
- * Submits PRIORITY frame to change the priority of stream |stream_id|
- * to the priority specification |pri_spec|.
+ * 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.NGHTTP2_FLAG_END_STREAM`, the last DATA frame
+ * has END_STREAM flag set.
  *
- * The |flags| is currently ignored and should be
- * :enum:`nghttp2_flag.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 [:macro:`NGHTTP2_MIN_WEIGHT`,
- * :macro:`NGHTTP2_MAX_WEIGHT`], inclusive.  If ``pri_spec->weight``
- * is strictly less than :macro:`NGHTTP2_MIN_WEIGHT`, it becomes
- * :macro:`NGHTTP2_MIN_WEIGHT`.  If it is strictly greater than
- * :macro:`NGHTTP2_MAX_WEIGHT`, it becomes
- * :macro:`NGHTTP2_MAX_WEIGHT`.
- *
- * If
- * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES`
- * of value of 1 is received by a remote endpoint, this function does
- * nothing and returns 0.
+ * 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_error.NGHTTP2_ERR_NOMEM`
  *     Out of memory.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_DATA_EXIST`
+ *     DATA or HEADERS has been already submitted and not fully
+ *     processed yet.
  * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
- *     The |stream_id| is 0; or the |pri_spec| is NULL; or trying to
- *     depend on itself.
+ *     The |stream_id| is 0.
+ * :enum:`nghttp2_error.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_error.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_data2()`.  Of
+ *   course, all data except for last one must not have
+ *   :enum:`nghttp2_flag.NGHTTP2_FLAG_END_STREAM` flag set in |flags|.
+ *   This sounds a bit complicated, and we recommend to use
+ *   `nghttp2_submit_request2()` and `nghttp2_submit_response2()` 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_data2(nghttp2_session *session, uint8_t flags,
+                                        int32_t stream_id,
+                                        const nghttp2_data_provider2 *data_prd);
+
+/**
+ * @function
+ *
+ * .. warning::
+ *
+ *   Deprecated.  :rfc:`7540` priorities are deprecated by
+ *   :rfc:`9113`.  Consider migrating to :rfc:`9218` extensible
+ *   prioritization scheme.
+ *
+ * This function is noop.  It always returns 0.
  */
 NGHTTP2_EXTERN int
 nghttp2_submit_priority(nghttp2_session *session, uint8_t flags,
@@ -4412,7 +5147,7 @@
  * The client side is not allowed to use this function.
  *
  * To submit response headers and data, use
- * `nghttp2_submit_response()`.
+ * `nghttp2_submit_response2()`.
  *
  * This function returns assigned promised stream ID if it succeeds,
  * or one of the following negative error codes:
@@ -4445,8 +5180,8 @@
  *
  */
 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);
+  nghttp2_session *session, uint8_t flags, int32_t stream_id,
+  const nghttp2_nv *nva, size_t nvlen, void *promised_stream_user_data);
 
 /**
  * @function
@@ -4551,10 +5286,11 @@
  * 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.
+ * The application can call `nghttp2_submit_request2()` without
+ * consulting this function.  In that case,
+ * `nghttp2_submit_request2()` 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);
@@ -4656,11 +5392,11 @@
  * 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
+ * :type:`nghttp2_pack_extension_callback2`.  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 must set :type:`nghttp2_pack_extension_callback2`
+ * using `nghttp2_session_callbacks_set_pack_extension_callback2()`.
  *
  * The application should retain the memory pointed by |payload| until
  * the transmission of extension frame is done (which is indicated by
@@ -4668,7 +5404,7 @@
  * (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`.
+ * :type:`nghttp2_pack_extension_callback2`.
  *
  * The standard HTTP/2 frame cannot be sent with this function, so
  * |type| must be strictly grater than 0x9.  Otherwise, this function
@@ -4679,7 +5415,7 @@
  * negative error codes:
  *
  * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`
- *     If :type:`nghttp2_pack_extension_callback` is not set.
+ *     If :type:`nghttp2_pack_extension_callback2` is not set.
  * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
  *     If  |type| specifies  standard  HTTP/2 frame  type.  The  frame
  *     types  in the  rage [0x0,  0x9], both  inclusive, are  standard
@@ -4938,8 +5674,57 @@
  *     found.
  */
 NGHTTP2_EXTERN int nghttp2_session_change_extpri_stream_priority(
-    nghttp2_session *session, int32_t stream_id, const nghttp2_extpri *extpri,
-    int ignore_client_signal);
+  nghttp2_session *session, int32_t stream_id, const nghttp2_extpri *extpri,
+  int ignore_client_signal);
+
+/**
+ * @function
+ *
+ * Stores the stream priority of the existing stream denoted by
+ * |stream_id| in the object pointed by |extpri|.  This function is
+ * meant to be used by server for :rfc:`9218` extensible
+ * prioritization scheme.
+ *
+ * If |session| is initialized as client, this function returns
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`.
+ *
+ * If
+ * :enum:`nghttp2_settings_id.NGHTTP2_SETTINGS_NO_RFC7540_PRIORITIES`
+ * of value of 1 is not submitted via `nghttp2_submit_settings()`,
+ * this function does nothing and returns 0.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_STATE`
+ *     The |session| is initialized as client.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
+ *     |stream_id| is zero; or a stream denoted by |stream_id| is not
+ *     found.
+ */
+NGHTTP2_EXTERN int nghttp2_session_get_extpri_stream_priority(
+  nghttp2_session *session, nghttp2_extpri *extpri, int32_t stream_id);
+
+/**
+ * @function
+ *
+ * Parses Priority header field value pointed by |value| of length
+ * |len|, and stores the result in the object pointed by |extpri|.
+ * Priority header field is defined in :rfc:`9218`.
+ *
+ * This function does not initialize the object pointed by |extpri|
+ * before storing the result.  It only assigns the values that the
+ * parser correctly extracted to fields.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INVALID_ARGUMENT`
+ *     Failed to parse the header field value.
+ */
+NGHTTP2_EXTERN int nghttp2_extpri_parse_priority(nghttp2_extpri *extpri,
+                                                 const uint8_t *value,
+                                                 size_t len);
 
 /**
  * @function
@@ -4956,11 +5741,14 @@
 /**
  * @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::
+ * .. warning::
+ *
+ *   Deprecated.  Use `nghttp2_select_alpn` instead.
+ *
+ * A helper function for dealing with 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"
@@ -4985,20 +5773,18 @@
  *
  * For ALPN, refer to https://tools.ietf.org/html/rfc7301
  *
- * See http://technotes.googlecode.com/git/nextprotoneg.html for more
- * details about NPN.
+ * To use this method you should do something like::
  *
- * For NPN, to use this method you should do something like::
- *
- *     static int select_next_proto_cb(SSL* ssl,
- *                                     unsigned char **out,
+ *     static int alpn_select_proto_cb(SSL* ssl,
+ *                                     const 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);
+ *         rv = nghttp2_select_next_protocol((unsigned char**)out, outlen,
+ *                                           in, inlen);
  *         if (rv == -1) {
  *             return SSL_TLSEXT_ERR_NOACK;
  *         }
@@ -5008,7 +5794,7 @@
  *         return SSL_TLSEXT_ERR_OK;
  *     }
  *     ...
- *     SSL_CTX_set_next_proto_select_cb(ssl_ctx, select_next_proto_cb, my_obj);
+ *     SSL_CTX_set_alpn_select_cb(ssl_ctx, alpn_select_proto_cb, my_obj);
  *
  */
 NGHTTP2_EXTERN int nghttp2_select_next_protocol(unsigned char **out,
@@ -5019,6 +5805,65 @@
 /**
  * @function
  *
+ * A helper function for dealing with 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
+ *
+ * To use this method you should do something like::
+ *
+ *     static int alpn_select_proto_cb(SSL* ssl,
+ *                                     const unsigned char **out,
+ *                                     unsigned char *outlen,
+ *                                     const unsigned char *in,
+ *                                     unsigned int inlen,
+ *                                     void *arg)
+ *     {
+ *         int rv;
+ *         rv = nghttp2_select_alpn(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_alpn_select_cb(ssl_ctx, alpn_select_proto_cb, my_obj);
+ *
+ */
+NGHTTP2_EXTERN int nghttp2_select_alpn(const 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
@@ -5100,6 +5945,12 @@
  * :authority or host header field is valid according to
  * https://tools.ietf.org/html/rfc3986#section-3.2
  *
+ * Note that :authority and host field values are not authority.  They
+ * do not include userinfo in RFC 3986, see
+ * https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2, that
+ * is, it does not include '@'.  This function treats '@' as a valid
+ * character.
+ *
  * |value| is valid if it merely consists of the allowed characters.
  * In particular, it does not check whether |value| follows the syntax
  * of authority.
@@ -5191,9 +6042,14 @@
 nghttp2_hd_deflate_change_table_size(nghttp2_hd_deflater *deflater,
                                      size_t settings_max_dynamic_table_size);
 
+#ifndef NGHTTP2_NO_SSIZE_T
 /**
  * @function
  *
+ * .. warning::
+ *
+ *   Deprecated.  Use `nghttp2_hd_deflate_hd2()` instead.
+ *
  * Deflates the |nva|, which has the |nvlen| name/value pairs, into
  * the |buf| of length |buflen|.
  *
@@ -5223,10 +6079,48 @@
                                              const nghttp2_nv *nva,
                                              size_t nvlen);
 
+#endif /* NGHTTP2_NO_SSIZE_T */
+
 /**
  * @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_error.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_error.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_error.NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP`
+ *     Deflation process has failed.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INSUFF_BUFSIZE`
+ *     The provided |buflen| size is too small to hold the output.
+ */
+NGHTTP2_EXTERN nghttp2_ssize
+nghttp2_hd_deflate_hd2(nghttp2_hd_deflater *deflater, uint8_t *buf,
+                       size_t buflen, const nghttp2_nv *nva, size_t nvlen);
+
+#ifndef NGHTTP2_NO_SSIZE_T
+/**
+ * @function
+ *
+ * .. warning::
+ *
+ *   Deprecated.  Use `nghttp2_hd_deflate_hd_vec2()` instead.
+ *
+ * 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
@@ -5257,6 +6151,40 @@
                                                  const nghttp2_nv *nva,
                                                  size_t nvlen);
 
+#endif /* NGHTTP2_NO_SSIZE_T */
+
+/**
+ * @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_error.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_error.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_error.NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP`
+ *     Deflation process has failed.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_INSUFF_BUFSIZE`
+ *     The provided |buflen| size is too small to hold the output.
+ */
+NGHTTP2_EXTERN nghttp2_ssize nghttp2_hd_deflate_hd_vec2(
+  nghttp2_hd_deflater *deflater, const nghttp2_vec *vec, size_t veclen,
+  const nghttp2_nv *nva, size_t nvlen);
+
 /**
  * @function
  *
@@ -5370,7 +6298,7 @@
  * 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_hd3()`, or after
  * `nghttp2_hd_inflate_end_headers()`.  Otherwise,
  * `NGHTTP2_ERR_INVALID_STATE` was returned.
  *
@@ -5408,6 +6336,7 @@
   NGHTTP2_HD_INFLATE_EMIT = 0x02
 } nghttp2_hd_inflate_flag;
 
+#ifndef NGHTTP2_NO_SSIZE_T
 /**
  * @function
  *
@@ -5495,9 +6424,16 @@
                                              int *inflate_flags, uint8_t *in,
                                              size_t inlen, int in_final);
 
+#endif /* NGHTTP2_NO_SSIZE_T */
+
+#ifndef NGHTTP2_NO_SSIZE_T
 /**
  * @function
  *
+ * .. warning::
+ *
+ *   Deprecated.  Use `nghttp2_hd_inflate_hd3()` instead.
+ *
  * Inflates name/value block stored in |in| with length |inlen|.  This
  * function performs decompression.  For each successful emission of
  * header name/value pair,
@@ -5584,6 +6520,95 @@
                                               const uint8_t *in, size_t inlen,
                                               int in_final);
 
+#endif /* NGHTTP2_NO_SSIZE_T */
+
+/**
+ * @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_flag.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.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_error.NGHTTP2_ERR_NOMEM`
+ *     Out of memory.
+ * :enum:`nghttp2_error.NGHTTP2_ERR_HEADER_COMP`
+ *     Inflation process has failed.
+ * :enum:`nghttp2_error.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)
+ *     {
+ *         nghttp2_ssize rv;
+ *
+ *         for(;;) {
+ *             nghttp2_nv nv;
+ *             int inflate_flags = 0;
+ *
+ *             rv = nghttp2_hd_inflate_hd3(hd_inflater, &nv, &inflate_flags,
+ *                                         in, inlen, final);
+ *
+ *             if(rv < 0) {
+ *                 fprintf(stderr, "inflate failed with error code %td", 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 nghttp2_ssize nghttp2_hd_inflate_hd3(
+  nghttp2_hd_inflater *inflater, nghttp2_nv *nv_out, int *inflate_flags,
+  const uint8_t *in, size_t inlen, int in_final);
+
 /**
  * @function
  *
@@ -5657,8 +6682,8 @@
  * `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()`.
+ * call of `nghttp2_session_send()`, `nghttp2_session_mem_send2()`,
+ * `nghttp2_session_recv()`, and `nghttp2_session_mem_recv2()`.
  */
 NGHTTP2_EXTERN nghttp2_stream *
 nghttp2_session_find_stream(nghttp2_session *session, int32_t stream_id);
@@ -5712,6 +6737,12 @@
 /**
  * @function
  *
+ * .. warning::
+ *
+ *   Deprecated.  :rfc:`7540` priorities are deprecated by
+ *   :rfc:`9113`.  Consider migrating to :rfc:`9218` extensible
+ *   prioritization scheme.
+ *
  * 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()`.
@@ -5722,8 +6753,13 @@
 /**
  * @function
  *
- * Returns the parent stream of |stream| in dependency tree.  Returns
- * NULL if there is no such stream.
+ * .. warning::
+ *
+ *   Deprecated.  :rfc:`7540` priorities are deprecated by
+ *   :rfc:`9113`.  Consider migrating to :rfc:`9218` extensible
+ *   prioritization scheme.
+ *
+ * This function always returns NULL.
  */
 NGHTTP2_EXTERN nghttp2_stream *
 nghttp2_stream_get_parent(nghttp2_stream *stream);
@@ -5733,8 +6769,13 @@
 /**
  * @function
  *
- * Returns the next sibling stream of |stream| in dependency tree.
- * Returns NULL if there is no such stream.
+ * .. warning::
+ *
+ *   Deprecated.  :rfc:`7540` priorities are deprecated by
+ *   :rfc:`9113`.  Consider migrating to :rfc:`9218` extensible
+ *   prioritization scheme.
+ *
+ * This function always returns NULL.
  */
 NGHTTP2_EXTERN nghttp2_stream *
 nghttp2_stream_get_next_sibling(nghttp2_stream *stream);
@@ -5742,8 +6783,13 @@
 /**
  * @function
  *
- * Returns the previous sibling stream of |stream| in dependency tree.
- * Returns NULL if there is no such stream.
+ * .. warning::
+ *
+ *   Deprecated.  :rfc:`7540` priorities are deprecated by
+ *   :rfc:`9113`.  Consider migrating to :rfc:`9218` extensible
+ *   prioritization scheme.
+ *
+ * This function always returns NULL.
  */
 NGHTTP2_EXTERN nghttp2_stream *
 nghttp2_stream_get_previous_sibling(nghttp2_stream *stream);
@@ -5751,8 +6797,13 @@
 /**
  * @function
  *
- * Returns the first child stream of |stream| in dependency tree.
- * Returns NULL if there is no such stream.
+ * .. warning::
+ *
+ *   Deprecated.  :rfc:`7540` priorities are deprecated by
+ *   :rfc:`9113`.  Consider migrating to :rfc:`9218` extensible
+ *   prioritization scheme.
+ *
+ * This function always returns NULL.
  */
 NGHTTP2_EXTERN nghttp2_stream *
 nghttp2_stream_get_first_child(nghttp2_stream *stream);
@@ -5760,14 +6811,26 @@
 /**
  * @function
  *
- * Returns dependency weight to the parent stream of |stream|.
+ * .. warning::
+ *
+ *   Deprecated.  :rfc:`7540` priorities are deprecated by
+ *   :rfc:`9113`.  Consider migrating to :rfc:`9218` extensible
+ *   prioritization scheme.
+ *
+ * This function always returns :macro:`NGHTTP2_DEFAULT_WEIGHT`.
  */
 NGHTTP2_EXTERN int32_t nghttp2_stream_get_weight(nghttp2_stream *stream);
 
 /**
  * @function
  *
- * Returns the sum of the weight for |stream|'s children.
+ * .. warning::
+ *
+ *   Deprecated.  :rfc:`7540` priorities are deprecated by
+ *   :rfc:`9113`.  Consider migrating to :rfc:`9218` extensible
+ *   prioritization scheme.
+ *
+ * This function always returns 0.
  */
 NGHTTP2_EXTERN int32_t
 nghttp2_stream_get_sum_dependency_weight(nghttp2_stream *stream);
@@ -5806,7 +6869,7 @@
  *   this is important.
  */
 NGHTTP2_EXTERN void nghttp2_set_debug_vprintf_callback(
-    nghttp2_debug_vprintf_callback debug_vprintf_callback);
+  nghttp2_debug_vprintf_callback debug_vprintf_callback);
 
 #ifdef __cplusplus
 }
diff --git a/Utilities/cmnghttp2/lib/includes/nghttp2/nghttp2ver.h b/Utilities/cmnghttp2/lib/includes/nghttp2/nghttp2ver.h
index 6ed0ac4..8dfe536 100644
--- a/Utilities/cmnghttp2/lib/includes/nghttp2/nghttp2ver.h
+++ b/Utilities/cmnghttp2/lib/includes/nghttp2/nghttp2ver.h
@@ -29,7 +29,7 @@
  * @macro
  * Version number of the nghttp2 library release
  */
-#define NGHTTP2_VERSION "1.52.0"
+#define NGHTTP2_VERSION "1.68.0"
 
 /**
  * @macro
@@ -37,6 +37,6 @@
  * 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 0x013400
+#define NGHTTP2_VERSION_NUM 0x014400
 
 #endif /* NGHTTP2VER_H */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_npn.c b/Utilities/cmnghttp2/lib/nghttp2_alpn.c
similarity index 65%
rename from Utilities/cmnghttp2/lib/nghttp2_npn.c
rename to Utilities/cmnghttp2/lib/nghttp2_alpn.c
index d1384c8..33c5885 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_npn.c
+++ b/Utilities/cmnghttp2/lib/nghttp2_alpn.c
@@ -22,13 +22,13 @@
  * 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 "nghttp2_alpn.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) {
+static int select_alpn(const 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) {
@@ -45,12 +45,25 @@
 
 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) {
+  if (select_alpn((const unsigned char **)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) {
+  if (select_alpn((const unsigned char **)out, outlen, in, inlen,
+                  NGHTTP2_HTTP_1_1_ALPN, NGHTTP2_HTTP_1_1_ALPN_LEN) == 0) {
+    return 0;
+  }
+  return -1;
+}
+
+int nghttp2_select_alpn(const unsigned char **out, unsigned char *outlen,
+                        const unsigned char *in, unsigned int inlen) {
+  if (select_alpn(out, outlen, in, inlen, NGHTTP2_PROTO_ALPN,
+                  NGHTTP2_PROTO_ALPN_LEN) == 0) {
+    return 1;
+  }
+  if (select_alpn(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_alpn.h
similarity index 90%
rename from Utilities/cmnghttp2/lib/nghttp2_npn.h
rename to Utilities/cmnghttp2/lib/nghttp2_alpn.h
index c6f1c04..ecc9ed2 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_npn.h
+++ b/Utilities/cmnghttp2/lib/nghttp2_alpn.h
@@ -22,13 +22,13 @@
  * 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
+#ifndef NGHTTP2_ALPN_H
+#define NGHTTP2_ALPN_H
 
 #ifdef HAVE_CONFIG_H
 #  include <config.h>
-#endif /* HAVE_CONFIG_H */
+#endif /* defined(HAVE_CONFIG_H) */
 
 #include <nghttp2/nghttp2.h>
 
-#endif /* NGHTTP2_NPN_H */
+#endif /* !defined(NGHTTP2_ALPN_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_buf.c b/Utilities/cmnghttp2/lib/nghttp2_buf.c
index ce51251..79de1dd 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_buf.c
+++ b/Utilities/cmnghttp2/lib/nghttp2_buf.c
@@ -65,7 +65,7 @@
     return 0;
   }
 
-  new_cap = nghttp2_max(new_cap, cap * 2);
+  new_cap = nghttp2_max_size(new_cap, cap * 2);
 
   ptr = nghttp2_mem_realloc(mem, buf->begin, new_cap);
   if (ptr == NULL) {
@@ -347,7 +347,7 @@
   while (len) {
     buf = &bufs->cur->buf;
 
-    nwrite = nghttp2_min(nghttp2_buf_avail(buf), len);
+    nwrite = nghttp2_min_size(nghttp2_buf_avail(buf), len);
     if (nwrite == 0) {
       rv = bufs_alloc_chain(bufs);
       if (rv != 0) {
@@ -446,7 +446,7 @@
   return 0;
 }
 
-ssize_t nghttp2_bufs_remove(nghttp2_bufs *bufs, uint8_t **out) {
+nghttp2_ssize nghttp2_bufs_remove(nghttp2_bufs *bufs, uint8_t **out) {
   size_t len;
   nghttp2_buf_chain *chain;
   nghttp2_buf *buf;
@@ -478,7 +478,7 @@
 
   *out = res;
 
-  return (ssize_t)len;
+  return (nghttp2_ssize)len;
 }
 
 size_t nghttp2_bufs_remove_copy(nghttp2_bufs *bufs, uint8_t *out) {
diff --git a/Utilities/cmnghttp2/lib/nghttp2_buf.h b/Utilities/cmnghttp2/lib/nghttp2_buf.h
index 45f62f1..636aa61 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_buf.h
+++ b/Utilities/cmnghttp2/lib/nghttp2_buf.h
@@ -27,7 +27,7 @@
 
 #ifdef HAVE_CONFIG_H
 #  include <config.h>
-#endif /* HAVE_CONFIG_H */
+#endif /* defined(HAVE_CONFIG_H) */
 
 #include <nghttp2/nghttp2.h>
 
@@ -349,7 +349,7 @@
  * NGHTTP2_ERR_NOMEM
  *     Out of memory
  */
-ssize_t nghttp2_bufs_remove(nghttp2_bufs *bufs, uint8_t **out);
+nghttp2_ssize nghttp2_bufs_remove(nghttp2_bufs *bufs, uint8_t **out);
 
 /*
  * Copies all data stored in |bufs| to |out|.  This function assumes
@@ -409,4 +409,4 @@
  */
 size_t nghttp2_bufs_len(nghttp2_bufs *bufs);
 
-#endif /* NGHTTP2_BUF_H */
+#endif /* !defined(NGHTTP2_BUF_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_callbacks.c b/Utilities/cmnghttp2/lib/nghttp2_callbacks.c
index 3c38214..162ca6b 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_callbacks.c
+++ b/Utilities/cmnghttp2/lib/nghttp2_callbacks.c
@@ -41,135 +41,168 @@
 }
 
 void nghttp2_session_callbacks_set_send_callback(
-    nghttp2_session_callbacks *cbs, nghttp2_send_callback send_callback) {
+  nghttp2_session_callbacks *cbs, nghttp2_send_callback send_callback) {
   cbs->send_callback = send_callback;
 }
 
+void nghttp2_session_callbacks_set_send_callback2(
+  nghttp2_session_callbacks *cbs, nghttp2_send_callback2 send_callback) {
+  cbs->send_callback2 = send_callback;
+}
+
 void nghttp2_session_callbacks_set_recv_callback(
-    nghttp2_session_callbacks *cbs, nghttp2_recv_callback recv_callback) {
+  nghttp2_session_callbacks *cbs, nghttp2_recv_callback recv_callback) {
   cbs->recv_callback = recv_callback;
 }
 
+void nghttp2_session_callbacks_set_recv_callback2(
+  nghttp2_session_callbacks *cbs, nghttp2_recv_callback2 recv_callback) {
+  cbs->recv_callback2 = recv_callback;
+}
+
 void nghttp2_session_callbacks_set_on_frame_recv_callback(
-    nghttp2_session_callbacks *cbs,
-    nghttp2_on_frame_recv_callback 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) {
+  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) {
+  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) {
+  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) {
+  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) {
+  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) {
+  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) {
+  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) {
+  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) {
+  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) {
+  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) {
+  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) {
+  nghttp2_session_callbacks *cbs,
+  nghttp2_select_padding_callback select_padding_callback) {
   cbs->select_padding_callback = select_padding_callback;
 }
 
+void nghttp2_session_callbacks_set_select_padding_callback2(
+  nghttp2_session_callbacks *cbs,
+  nghttp2_select_padding_callback2 select_padding_callback) {
+  cbs->select_padding_callback2 = 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) {
+  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_data_source_read_length_callback2(
+  nghttp2_session_callbacks *cbs,
+  nghttp2_data_source_read_length_callback2 data_source_read_length_callback) {
+  cbs->read_length_callback2 = 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) {
+  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) {
+  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) {
+  nghttp2_session_callbacks *cbs,
+  nghttp2_pack_extension_callback pack_extension_callback) {
   cbs->pack_extension_callback = pack_extension_callback;
 }
 
+void nghttp2_session_callbacks_set_pack_extension_callback2(
+  nghttp2_session_callbacks *cbs,
+  nghttp2_pack_extension_callback2 pack_extension_callback) {
+  cbs->pack_extension_callback2 = pack_extension_callback;
+}
+
 void nghttp2_session_callbacks_set_unpack_extension_callback(
-    nghttp2_session_callbacks *cbs,
-    nghttp2_unpack_extension_callback 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) {
+  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) {
+  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) {
+  nghttp2_session_callbacks *cbs, nghttp2_error_callback2 error_callback2) {
   cbs->error_callback2 = error_callback2;
 }
+
+void nghttp2_session_callbacks_set_rand_callback(
+  nghttp2_session_callbacks *cbs, nghttp2_rand_callback rand_callback) {
+  cbs->rand_callback = rand_callback;
+}
diff --git a/Utilities/cmnghttp2/lib/nghttp2_callbacks.h b/Utilities/cmnghttp2/lib/nghttp2_callbacks.h
index 61e51fa..4b45e57 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_callbacks.h
+++ b/Utilities/cmnghttp2/lib/nghttp2_callbacks.h
@@ -27,7 +27,7 @@
 
 #ifdef HAVE_CONFIG_H
 #  include <config.h>
-#endif /* HAVE_CONFIG_H */
+#endif /* defined(HAVE_CONFIG_H) */
 
 #include <nghttp2/nghttp2.h>
 
@@ -36,20 +36,34 @@
  */
 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.
+   * Deprecated.  Use send_callback2 instead.  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.
+   * 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_send2()` to
+   * serialize data to transmit.
+   */
+  nghttp2_send_callback2 send_callback2;
+  /**
+   * Deprecated.  Use recv_callback2 instead.  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 when the session wants to receive data
+   * from the remote peer.  This callback is not necessary if the
+   * application uses solely `nghttp2_session_mem_recv2()` to process
+   * received data.
+   */
+  nghttp2_recv_callback2 recv_callback2;
+  /**
    * Callback function invoked by `nghttp2_session_recv()` when a
    * frame is received.
    */
@@ -100,26 +114,44 @@
   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
+   * Deprecated.  Use select_padding_callback2 instead.  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
+   * Callback function invoked when the library asks application how
+   * many padding bytes are required for the transmission of the given
+   * frame.
+   */
+  nghttp2_select_padding_callback2 select_padding_callback2;
+  /**
+   * Deprecated.  Use read_length_callback2 instead.  The callback
+   * function used to determine the length allowed in
    * `nghttp2_data_source_read_callback()`
    */
   nghttp2_data_source_read_length_callback read_length_callback;
   /**
+   * The callback function used to determine the length allowed in
+   * `nghttp2_data_source_read_callback2()`
+   */
+  nghttp2_data_source_read_length_callback2 read_length_callback2;
+  /**
    * 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;
+  /**
+   * Deprecated.  Use pack_extension_callback2 instead.
+   */
   nghttp2_pack_extension_callback pack_extension_callback;
+  nghttp2_pack_extension_callback2 pack_extension_callback2;
   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;
+  nghttp2_rand_callback rand_callback;
 };
 
-#endif /* NGHTTP2_CALLBACKS_H */
+#endif /* !defined(NGHTTP2_CALLBACKS_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_debug.c b/Utilities/cmnghttp2/lib/nghttp2_debug.c
index cb27797..b5f33ef 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_debug.c
+++ b/Utilities/cmnghttp2/lib/nghttp2_debug.c
@@ -34,7 +34,7 @@
 }
 
 static nghttp2_debug_vprintf_callback static_debug_vprintf_callback =
-    nghttp2_default_debug_vfprintf_callback;
+  nghttp2_default_debug_vfprintf_callback;
 
 void nghttp2_debug_vprintf(const char *format, ...) {
   if (static_debug_vprintf_callback) {
@@ -46,15 +46,15 @@
 }
 
 void nghttp2_set_debug_vprintf_callback(
-    nghttp2_debug_vprintf_callback debug_vprintf_callback) {
+  nghttp2_debug_vprintf_callback debug_vprintf_callback) {
   static_debug_vprintf_callback = debug_vprintf_callback;
 }
 
-#else /* !DEBUGBUILD */
+#else /* !defined(DEBUGBUILD) */
 
 void nghttp2_set_debug_vprintf_callback(
-    nghttp2_debug_vprintf_callback debug_vprintf_callback) {
+  nghttp2_debug_vprintf_callback debug_vprintf_callback) {
   (void)debug_vprintf_callback;
 }
 
-#endif /* !DEBUGBUILD */
+#endif /* !defined(DEBUGBUILD) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_debug.h b/Utilities/cmnghttp2/lib/nghttp2_debug.h
index cbb4dd5..26566a6 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_debug.h
+++ b/Utilities/cmnghttp2/lib/nghttp2_debug.h
@@ -27,17 +27,17 @@
 
 #ifdef HAVE_CONFIG_H
 #  include <config.h>
-#endif /* HAVE_CONFIG_H */
+#endif /* defined(HAVE_CONFIG_H) */
 
 #include <nghttp2/nghttp2.h>
 
 #ifdef DEBUGBUILD
 #  define DEBUGF(...) nghttp2_debug_vprintf(__VA_ARGS__)
 void nghttp2_debug_vprintf(const char *format, ...);
-#else
+#else /* !defined(DEBUGBUILD) */
 #  define DEBUGF(...)                                                          \
     do {                                                                       \
     } while (0)
-#endif
+#endif /* !defined(DEBUGBUILD) */
 
-#endif /* NGHTTP2_DEBUG_H */
+#endif /* !defined(NGHTTP2_DEBUG_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_extpri.c b/Utilities/cmnghttp2/lib/nghttp2_extpri.c
index 3fd9b78..ba0263e 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_extpri.c
+++ b/Utilities/cmnghttp2/lib/nghttp2_extpri.c
@@ -24,6 +24,7 @@
  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 #include "nghttp2_extpri.h"
+#include "nghttp2_http.h"
 
 uint8_t nghttp2_extpri_to_uint8(const nghttp2_extpri *extpri) {
   return (uint8_t)((uint32_t)extpri->inc << 7 | extpri->urgency);
@@ -33,3 +34,8 @@
   extpri->urgency = nghttp2_extpri_uint8_urgency(u8extpri);
   extpri->inc = nghttp2_extpri_uint8_inc(u8extpri);
 }
+
+int nghttp2_extpri_parse_priority(nghttp2_extpri *extpri, const uint8_t *value,
+                                  size_t len) {
+  return nghttp2_http_parse_priority(extpri, value, len);
+}
diff --git a/Utilities/cmnghttp2/lib/nghttp2_extpri.h b/Utilities/cmnghttp2/lib/nghttp2_extpri.h
index 23c6ddc..2e03916 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_extpri.h
+++ b/Utilities/cmnghttp2/lib/nghttp2_extpri.h
@@ -28,7 +28,7 @@
 
 #ifdef HAVE_CONFIG_H
 #  include <config.h>
-#endif /* HAVE_CONFIG_H */
+#endif /* defined(HAVE_CONFIG_H) */
 
 #include <nghttp2/nghttp2.h>
 
@@ -60,6 +60,6 @@
  * nghttp2_extpri_uint8_inc extracts inc from |PRI| which is supposed to
  * be constructed by nghttp2_extpri_to_uint8.
  */
-#define nghttp2_extpri_uint8_inc(PRI) (((PRI)&NGHTTP2_EXTPRI_INC_MASK) != 0)
+#define nghttp2_extpri_uint8_inc(PRI) (((PRI) & NGHTTP2_EXTPRI_INC_MASK) != 0)
 
-#endif /* NGHTTP2_EXTPRI_H */
+#endif /* !defined(NGHTTP2_EXTPRI_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_frame.c b/Utilities/cmnghttp2/lib/nghttp2_frame.c
index 35072c1..edc2aaa 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_frame.c
+++ b/Utilities/cmnghttp2/lib/nghttp2_frame.c
@@ -418,8 +418,8 @@
   nghttp2_priority_spec_init(pri_spec, dep_stream_id, weight, exclusive);
 }
 
-int nghttp2_frame_unpack_headers_payload(nghttp2_headers *frame,
-                                         const uint8_t *payload) {
+void 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 {
@@ -428,11 +428,9 @@
 
   frame->nva = NULL;
   frame->nvlen = 0;
-
-  return 0;
 }
 
-int nghttp2_frame_pack_priority(nghttp2_bufs *bufs, nghttp2_priority *frame) {
+void nghttp2_frame_pack_priority(nghttp2_bufs *bufs, nghttp2_priority *frame) {
   nghttp2_buf *buf;
 
   assert(bufs->head == bufs->cur);
@@ -448,8 +446,6 @@
   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,
@@ -457,8 +453,8 @@
   nghttp2_frame_unpack_priority_spec(&frame->pri_spec, payload);
 }
 
-int nghttp2_frame_pack_rst_stream(nghttp2_bufs *bufs,
-                                  nghttp2_rst_stream *frame) {
+void nghttp2_frame_pack_rst_stream(nghttp2_bufs *bufs,
+                                   nghttp2_rst_stream *frame) {
   nghttp2_buf *buf;
 
   assert(bufs->head == bufs->cur);
@@ -473,8 +469,6 @@
 
   nghttp2_put_uint32be(buf->last, frame->error_code);
   buf->last += 4;
-
-  return 0;
 }
 
 void nghttp2_frame_unpack_rst_stream_payload(nghttp2_rst_stream *frame,
@@ -498,7 +492,7 @@
   nghttp2_frame_pack_frame_hd(buf->pos, &frame->hd);
 
   buf->last +=
-      nghttp2_frame_pack_settings_payload(buf->last, frame->iv, frame->niv);
+    nghttp2_frame_pack_settings_payload(buf->last, frame->iv, frame->niv);
 
   return 0;
 }
@@ -543,7 +537,7 @@
   }
 
   *iv_ptr =
-      nghttp2_mem_malloc(mem, (*niv_ptr) * sizeof(nghttp2_settings_entry));
+    nghttp2_mem_malloc(mem, (*niv_ptr) * sizeof(nghttp2_settings_entry));
 
   if (*iv_ptr == NULL) {
     return NGHTTP2_ERR_NOMEM;
@@ -592,16 +586,15 @@
   return frame_pack_headers_shared(bufs, &frame->hd);
 }
 
-int nghttp2_frame_unpack_push_promise_payload(nghttp2_push_promise *frame,
-                                              const uint8_t *payload) {
+void 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;
+    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) {
+void nghttp2_frame_pack_ping(nghttp2_bufs *bufs, nghttp2_ping *frame) {
   nghttp2_buf *buf;
 
   assert(bufs->head == bufs->cur);
@@ -615,9 +608,7 @@
   nghttp2_frame_pack_frame_hd(buf->pos, &frame->hd);
 
   buf->last =
-      nghttp2_cpymem(buf->last, frame->opaque_data, sizeof(frame->opaque_data));
-
-  return 0;
+    nghttp2_cpymem(buf->last, frame->opaque_data, sizeof(frame->opaque_data));
 }
 
 void nghttp2_frame_unpack_ping_payload(nghttp2_ping *frame,
@@ -697,8 +688,8 @@
   return 0;
 }
 
-int nghttp2_frame_pack_window_update(nghttp2_bufs *bufs,
-                                     nghttp2_window_update *frame) {
+void nghttp2_frame_pack_window_update(nghttp2_bufs *bufs,
+                                      nghttp2_window_update *frame) {
   nghttp2_buf *buf;
 
   assert(bufs->head == bufs->cur);
@@ -713,17 +704,15 @@
 
   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;
+    nghttp2_get_uint32(payload) & NGHTTP2_WINDOW_SIZE_INCREMENT_MASK;
 }
 
-int nghttp2_frame_pack_altsvc(nghttp2_bufs *bufs, nghttp2_extension *frame) {
+void nghttp2_frame_pack_altsvc(nghttp2_bufs *bufs, nghttp2_extension *frame) {
   int rv;
   nghttp2_buf *buf;
   nghttp2_ext_altsvc *altsvc;
@@ -752,8 +741,6 @@
   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,
@@ -901,8 +888,8 @@
   return 0;
 }
 
-int nghttp2_frame_pack_priority_update(nghttp2_bufs *bufs,
-                                       nghttp2_extension *frame) {
+void nghttp2_frame_pack_priority_update(nghttp2_bufs *bufs,
+                                        nghttp2_extension *frame) {
   int rv;
   nghttp2_buf *buf;
   nghttp2_ext_priority_update *priority_update;
@@ -927,8 +914,6 @@
                         priority_update->field_value_len);
 
   assert(rv == 0);
-
-  return 0;
 }
 
 void nghttp2_frame_unpack_priority_update_payload(nghttp2_extension *frame,
@@ -941,7 +926,7 @@
   priority_update = frame->payload;
 
   priority_update->stream_id =
-      nghttp2_get_uint32(payload) & NGHTTP2_STREAM_ID_MASK;
+    nghttp2_get_uint32(payload) & NGHTTP2_STREAM_ID_MASK;
 
   if (payloadlen > 4) {
     priority_update->field_value = payload + 4;
@@ -1186,14 +1171,14 @@
   buf->last += trail_padlen;
 }
 
-int nghttp2_frame_add_pad(nghttp2_bufs *bufs, nghttp2_frame_hd *hd,
-                          size_t padlen, int framehd_only) {
+void 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;
+    return;
   }
 
   /*
@@ -1226,6 +1211,4 @@
   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
index 5f6152b..ed4ab2c 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_frame.h
+++ b/Utilities/cmnghttp2/lib/nghttp2_frame.h
@@ -27,7 +27,7 @@
 
 #ifdef HAVE_CONFIG_H
 #  include <config.h>
-#endif /* HAVE_CONFIG_H */
+#endif /* defined(HAVE_CONFIG_H) */
 
 #include <nghttp2/nghttp2.h>
 #include "nghttp2_hd.h"
@@ -143,11 +143,9 @@
  * 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);
+void nghttp2_frame_unpack_headers_payload(nghttp2_headers *frame,
+                                          const uint8_t *payload);
 
 /*
  * Packs PRIORITY frame |frame| in wire format and store it in
@@ -155,10 +153,8 @@
  *
  * 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);
+void nghttp2_frame_pack_priority(nghttp2_bufs *bufs, nghttp2_priority *frame);
 
 /*
  * Unpacks PRIORITY wire format into |frame|.
@@ -172,11 +168,9 @@
  *
  * 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);
+void nghttp2_frame_pack_rst_stream(nghttp2_bufs *bufs,
+                                   nghttp2_rst_stream *frame);
 
 /*
  * Unpacks RST_STREAM frame byte sequence into |frame|.
@@ -265,15 +259,9 @@
  * 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);
+void 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
@@ -281,10 +269,8 @@
  *
  * 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);
+void nghttp2_frame_pack_ping(nghttp2_bufs *bufs, nghttp2_ping *frame);
 
 /*
  * Unpacks PING wire format into |frame|.
@@ -343,11 +329,9 @@
  *
  * 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);
+void nghttp2_frame_pack_window_update(nghttp2_bufs *bufs,
+                                      nghttp2_window_update *frame);
 
 /*
  * Unpacks WINDOW_UPDATE frame byte sequence into |frame|.
@@ -361,17 +345,13 @@
  *
  * 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);
+void 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,
@@ -431,19 +411,15 @@
  *
  * 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_update(nghttp2_bufs *bufs,
-                                       nghttp2_extension *ext);
+void nghttp2_frame_pack_priority_update(nghttp2_bufs *bufs,
+                                        nghttp2_extension *ext);
 
 /*
  * Unpacks PRIORITY_UPDATE wire format into |frame|.  The |payload| of
  * |payloadlen| bytes contains frame payload.  This function assumes
  * that frame->payload points to the nghttp2_ext_priority_update
  * object.
- *
- * This function always succeeds and returns 0.
  */
 void nghttp2_frame_unpack_priority_update_payload(nghttp2_extension *frame,
                                                   uint8_t *payload,
@@ -654,16 +630,8 @@
  * |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);
+void nghttp2_frame_add_pad(nghttp2_bufs *bufs, nghttp2_frame_hd *hd,
+                           size_t padlen, int framehd_only);
 
-#endif /* NGHTTP2_FRAME_H */
+#endif /* !defined(NGHTTP2_FRAME_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_hd.c b/Utilities/cmnghttp2/lib/nghttp2_hd.c
index 8a2bda6..ad85eed 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_hd.c
+++ b/Utilities/cmnghttp2/lib/nghttp2_hd.c
@@ -36,9 +36,10 @@
 #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                                                                   \
+    {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 */
@@ -46,67 +47,67 @@
    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),
+  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) {
@@ -593,8 +594,19 @@
 static int hd_ringbuf_init(nghttp2_hd_ringbuf *ringbuf, size_t bufsize,
                            nghttp2_mem *mem) {
   size_t size;
+  const size_t max_size = SIZE_MAX / sizeof(nghttp2_hd_entry *);
+
+  if (bufsize > max_size) {
+    return NGHTTP2_ERR_NOMEM;
+  }
+
   for (size = 1; size < bufsize; size <<= 1)
     ;
+
+  if (size > max_size) {
+    return NGHTTP2_ERR_NOMEM;
+  }
+
   ringbuf->buffer = nghttp2_mem_malloc(mem, sizeof(nghttp2_hd_entry *) * size);
   if (ringbuf->buffer == NULL) {
     return NGHTTP2_ERR_NOMEM;
@@ -677,8 +689,8 @@
   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);
+    &context->hd_table,
+    context->hd_table_bufsize_max / NGHTTP2_HD_ENTRY_OVERHEAD, mem);
   if (rv != 0) {
     return rv;
   }
@@ -695,7 +707,7 @@
 
 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);
+    deflater, NGHTTP2_HD_DEFAULT_MAX_DEFLATE_BUFFER_SIZE, mem);
 }
 
 int nghttp2_hd_deflate_init2(nghttp2_hd_deflater *deflater,
@@ -850,9 +862,10 @@
  * 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) {
+static nghttp2_ssize 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;
@@ -871,7 +884,7 @@
 
     if (++in == last) {
       *res = n;
-      return (ssize_t)(in - start);
+      return (nghttp2_ssize)(in - start);
     }
   }
 
@@ -906,12 +919,12 @@
 
   if (in == last) {
     *res = n;
-    return (ssize_t)(in - start);
+    return (nghttp2_ssize)(in - start);
   }
 
   *res = n;
   *fin = 1;
-  return (ssize_t)(in + 1 - start);
+  return (nghttp2_ssize)(in + 1 - start);
 }
 
 static int emit_table_size(nghttp2_bufs *bufs, size_t table_size) {
@@ -1076,8 +1089,8 @@
   int rv;
 
   DEBUGF(
-      "deflatehd: emit newname namelen=%zu, valuelen=%zu, indexing_mode=%d\n",
-      nv->namelen, nv->valuelen, indexing_mode);
+    "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) {
@@ -1110,12 +1123,11 @@
 
   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);
+      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);
@@ -1164,7 +1176,7 @@
 }
 
 typedef struct {
-  ssize_t index;
+  nghttp2_ssize index;
   /* Nonzero if both name and value are matched. */
   int name_value_match;
 } search_result;
@@ -1213,8 +1225,8 @@
     return res;
   }
 
-  res.index =
-      (ssize_t)(context->next_seq - 1 - ent->seq + NGHTTP2_STATIC_TABLE_LENGTH);
+  res.index = (nghttp2_ssize)(context->next_seq - 1 - ent->seq +
+                              NGHTTP2_STATIC_TABLE_LENGTH);
   res.name_value_match = exact_match;
 
   return res;
@@ -1231,7 +1243,7 @@
     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);
+      entry_room(ent->nv.name->len, ent->nv.value->len);
     hd_ringbuf_pop_back(&context->hd_table);
     if (map) {
       hd_map_remove(map, ent);
@@ -1243,14 +1255,14 @@
 }
 
 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);
+  nghttp2_hd_deflater *deflater, size_t settings_max_dynamic_table_size) {
+  size_t next_bufsize = nghttp2_min_size(
+    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);
+    nghttp2_min_size(deflater->min_hd_table_bufsize_max, next_bufsize);
 
   deflater->notify_table_size_change = 1;
 
@@ -1259,7 +1271,7 @@
 }
 
 int nghttp2_hd_inflate_change_table_size(
-    nghttp2_hd_inflater *inflater, size_t settings_max_dynamic_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:
@@ -1302,7 +1314,7 @@
   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;
+      ->nv;
   } else {
     const nghttp2_hd_static_entry *ent = &static_table[idx];
     nghttp2_hd_nv nv = {(nghttp2_rcbuf *)&ent->name,
@@ -1318,7 +1330,7 @@
   if (idx >= NGHTTP2_STATIC_TABLE_LENGTH) {
     return &hd_ringbuf_get(&context->hd_table,
                            idx - NGHTTP2_STATIC_TABLE_LENGTH)
-                ->cnv;
+              ->cnv;
   }
 
   return &static_table[idx].cnv;
@@ -1332,7 +1344,7 @@
       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) {
+        deflater->ctx.hd_table_bufsize_max * 3 / 4) {
     return NGHTTP2_HD_WITHOUT_INDEXING;
   }
 
@@ -1343,7 +1355,7 @@
                       const nghttp2_nv *nv) {
   int rv;
   search_result res;
-  ssize_t idx;
+  nghttp2_ssize idx;
   int indexing_mode;
   int32_t token;
   nghttp2_mem *mem;
@@ -1365,12 +1377,11 @@
      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);
+  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);
@@ -1378,8 +1389,7 @@
   idx = res.index;
 
   if (res.name_value_match) {
-
-    DEBUGF("deflatehd: name/value match index=%zd\n", idx);
+    DEBUGF("deflatehd: name/value match index=%td\n", idx);
 
     rv = emit_indexed_block(bufs, (size_t)idx);
     if (rv != 0) {
@@ -1390,7 +1400,7 @@
   }
 
   if (res.index != -1) {
-    DEBUGF("deflatehd: name match index=%zd\n", res.index);
+    DEBUGF("deflatehd: name match index=%td\n", res.index);
   }
 
   if (indexing_mode == NGHTTP2_HD_WITH_INDEXING) {
@@ -1456,7 +1466,6 @@
     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) {
@@ -1491,6 +1500,12 @@
 ssize_t nghttp2_hd_deflate_hd(nghttp2_hd_deflater *deflater, uint8_t *buf,
                               size_t buflen, const nghttp2_nv *nv,
                               size_t nvlen) {
+  return (ssize_t)nghttp2_hd_deflate_hd2(deflater, buf, buflen, nv, nvlen);
+}
+
+nghttp2_ssize nghttp2_hd_deflate_hd2(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;
@@ -1517,12 +1532,18 @@
     return rv;
   }
 
-  return (ssize_t)buflen;
+  return (nghttp2_ssize)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) {
+  return (ssize_t)nghttp2_hd_deflate_hd_vec2(deflater, vec, veclen, nv, nvlen);
+}
+
+nghttp2_ssize nghttp2_hd_deflate_hd_vec2(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;
@@ -1550,7 +1571,7 @@
     return rv;
   }
 
-  return (ssize_t)buflen;
+  return (nghttp2_ssize)buflen;
 }
 
 size_t nghttp2_hd_deflate_bound(nghttp2_hd_deflater *deflater,
@@ -1643,10 +1664,11 @@
  * 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;
+static nghttp2_ssize hd_inflate_read_len(nghttp2_hd_inflater *inflater,
+                                         int *rfin, const uint8_t *in,
+                                         const uint8_t *last, size_t prefix,
+                                         size_t maxlen) {
+  nghttp2_ssize rv;
   uint32_t out;
 
   *rfin = 0;
@@ -1684,10 +1706,10 @@
  * 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;
+static nghttp2_ssize hd_inflate_read_huff(nghttp2_hd_inflater *inflater,
+                                          nghttp2_buf *buf, const uint8_t *in,
+                                          const uint8_t *last) {
+  nghttp2_ssize readlen;
   int fin = 0;
   if ((size_t)(last - in) >= inflater->left) {
     last = in + inflater->left;
@@ -1721,14 +1743,15 @@
  * 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);
+static nghttp2_ssize hd_inflate_read(nghttp2_hd_inflater *inflater,
+                                     nghttp2_buf *buf, const uint8_t *in,
+                                     const uint8_t *last) {
+  size_t len = nghttp2_min_size((size_t)(last - in), inflater->left);
 
   buf->last = nghttp2_cpymem(buf->last, in, len);
 
   inflater->left -= len;
-  return (ssize_t)len;
+  return (nghttp2_ssize)len;
 }
 
 /*
@@ -1843,7 +1866,15 @@
 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;
+  return (nghttp2_ssize)nghttp2_hd_inflate_hd3(inflater, nv_out, inflate_flags,
+                                               in, inlen, in_final);
+}
+
+nghttp2_ssize nghttp2_hd_inflate_hd3(nghttp2_hd_inflater *inflater,
+                                     nghttp2_nv *nv_out, int *inflate_flags,
+                                     const uint8_t *in, size_t inlen,
+                                     int in_final) {
+  nghttp2_ssize rv;
   nghttp2_hd_nv hd_nv;
 
   rv = nghttp2_hd_inflate_hd_nv(inflater, &hd_nv, inflate_flags, in, inlen,
@@ -1866,11 +1897,11 @@
   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;
+nghttp2_ssize 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) {
+  nghttp2_ssize rv = 0;
   const uint8_t *first = in;
   const uint8_t *last = in + inlen;
   int rfin = 0;
@@ -1938,9 +1969,9 @@
     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));
+        inflater, &rfin, in, last, 5,
+        nghttp2_min_size(inflater->min_hd_table_bufsize_max,
+                         inflater->settings_hd_table_bufsize_max));
       if (rv < 0) {
         goto fail;
       }
@@ -1992,7 +2023,7 @@
 
         inflater->state = NGHTTP2_HD_STATE_OPCODE;
         *inflate_flags |= NGHTTP2_HD_INFLATE_EMIT;
-        return (ssize_t)(in - first);
+        return (nghttp2_ssize)(in - first);
       } else {
         inflater->index = inflater->left;
         --inflater->index;
@@ -2027,8 +2058,8 @@
 
         inflater->state = NGHTTP2_HD_STATE_NEWNAME_READ_NAMEHUFF;
 
-        rv = nghttp2_rcbuf_new(&inflater->namercbuf, inflater->left * 2 + 1,
-                               mem);
+        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);
@@ -2050,7 +2081,7 @@
 
       in += rv;
 
-      DEBUGF("inflatehd: %zd bytes read\n", rv);
+      DEBUGF("inflatehd: %td bytes read\n", rv);
 
       if (inflater->left) {
         DEBUGF("inflatehd: still %zu bytes to go\n", inflater->left);
@@ -2072,7 +2103,7 @@
 
       in += rv;
 
-      DEBUGF("inflatehd: %zd bytes read\n", rv);
+      DEBUGF("inflatehd: %td bytes read\n", rv);
       if (inflater->left) {
         DEBUGF("inflatehd: still %zu bytes to go\n", inflater->left);
 
@@ -2112,8 +2143,8 @@
 
         inflater->state = NGHTTP2_HD_STATE_READ_VALUEHUFF;
 
-        rv = nghttp2_rcbuf_new(&inflater->valuercbuf, inflater->left * 2 + 1,
-                               mem);
+        rv =
+          nghttp2_rcbuf_new(&inflater->valuercbuf, inflater->left * 2 + 1, mem);
       } else {
         inflater->state = NGHTTP2_HD_STATE_READ_VALUE;
 
@@ -2138,7 +2169,7 @@
 
       in += rv;
 
-      DEBUGF("inflatehd: %zd bytes read\n", rv);
+      DEBUGF("inflatehd: %td bytes read\n", rv);
 
       if (inflater->left) {
         DEBUGF("inflatehd: still %zu bytes to go\n", inflater->left);
@@ -2162,18 +2193,18 @@
       inflater->state = NGHTTP2_HD_STATE_OPCODE;
       *inflate_flags |= NGHTTP2_HD_INFLATE_EMIT;
 
-      return (ssize_t)(in - first);
+      return (nghttp2_ssize)(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,
+        DEBUGF("inflatehd: value read failure %td: %s\n", rv,
                nghttp2_strerror((int)rv));
         goto fail;
       }
 
       in += rv;
 
-      DEBUGF("inflatehd: %zd bytes read\n", rv);
+      DEBUGF("inflatehd: %td bytes read\n", rv);
 
       if (inflater->left) {
         DEBUGF("inflatehd: still %zu bytes to go\n", inflater->left);
@@ -2196,7 +2227,7 @@
       inflater->state = NGHTTP2_HD_STATE_OPCODE;
       *inflate_flags |= NGHTTP2_HD_INFLATE_EMIT;
 
-      return (ssize_t)(in - first);
+      return (nghttp2_ssize)(in - first);
     }
   }
 
@@ -2216,7 +2247,7 @@
     }
     *inflate_flags |= NGHTTP2_HD_INFLATE_FINAL;
   }
-  return (ssize_t)(in - first);
+  return (nghttp2_ssize)(in - first);
 
 almost_ok:
   if (in_final) {
@@ -2226,10 +2257,10 @@
 
     goto fail;
   }
-  return (ssize_t)(in - first);
+  return (nghttp2_ssize)(in - first);
 
 fail:
-  DEBUGF("inflatehd: error return %zd\n", rv);
+  DEBUGF("inflatehd: error return %td\n", rv);
 
   inflater->ctx.bad = 1;
   return rv;
@@ -2284,7 +2315,6 @@
 
 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);
 }
 
@@ -2297,9 +2327,10 @@
   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) {
+nghttp2_ssize 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);
 }
 
diff --git a/Utilities/cmnghttp2/lib/nghttp2_hd.h b/Utilities/cmnghttp2/lib/nghttp2_hd.h
index 6de0052..bdc7fad 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_hd.h
+++ b/Utilities/cmnghttp2/lib/nghttp2_hd.h
@@ -27,7 +27,7 @@
 
 #ifdef HAVE_CONFIG_H
 #  include <config.h>
-#endif /* HAVE_CONFIG_H */
+#endif /* defined(HAVE_CONFIG_H) */
 
 #include <nghttp2/nghttp2.h>
 
@@ -357,9 +357,10 @@
  * 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);
+nghttp2_ssize 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,
@@ -376,9 +377,10 @@
 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);
+nghttp2_ssize 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 */
 
@@ -427,9 +429,9 @@
  * 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_ssize 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|
@@ -437,4 +439,4 @@
  */
 int nghttp2_hd_huff_decode_failure_state(nghttp2_hd_huff_decode_context *ctx);
 
-#endif /* NGHTTP2_HD_H */
+#endif /* !defined(NGHTTP2_HD_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_hd_huffman.c b/Utilities/cmnghttp2/lib/nghttp2_hd_huffman.c
index ac90f49..de26200 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_hd_huffman.c
+++ b/Utilities/cmnghttp2/lib/nghttp2_hd_huffman.c
@@ -94,7 +94,7 @@
 
   if (nbits) {
     rv = nghttp2_bufs_addb(
-        bufs, (uint8_t)((uint8_t)(code >> 56) | ((1 << (8 - nbits)) - 1)));
+      bufs, (uint8_t)((uint8_t)(code >> 56) | ((1 << (8 - nbits)) - 1)));
     if (rv != 0) {
       return rv;
     }
@@ -107,16 +107,18 @@
   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) {
+nghttp2_ssize 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 */
+      - http://graphics.ics.uci.edu/pub/Prefix.pdf [!!! NO LONGER VALID !!!]
+      - https://ics.uci.edu/~dan/pubs/Prefix.pdf
+      - https://github.com/nghttp2/nghttp2/files/15141264/Prefix.pdf */
   for (; src != end;) {
     c = *src++;
     t = &huff_decode_table[t->fstate & 0x1ff][c >> 4];
@@ -136,7 +138,7 @@
     return NGHTTP2_ERR_HEADER_COMP;
   }
 
-  return (ssize_t)srclen;
+  return (nghttp2_ssize)srclen;
 }
 
 int nghttp2_hd_huff_decode_failure_state(nghttp2_hd_huff_decode_context *ctx) {
diff --git a/Utilities/cmnghttp2/lib/nghttp2_hd_huffman.h b/Utilities/cmnghttp2/lib/nghttp2_hd_huffman.h
index 2bfd531..df037a8 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_hd_huffman.h
+++ b/Utilities/cmnghttp2/lib/nghttp2_hd_huffman.h
@@ -27,7 +27,7 @@
 
 #ifdef HAVE_CONFIG_H
 #  include <config.h>
-#endif /* HAVE_CONFIG_H */
+#endif /* defined(HAVE_CONFIG_H) */
 
 #include <nghttp2/nghttp2.h>
 
@@ -69,4 +69,4 @@
 extern const nghttp2_huff_sym huff_sym_table[];
 extern const nghttp2_huff_decode huff_decode_table[][16];
 
-#endif /* NGHTTP2_HD_HUFFMAN_H */
+#endif /* !defined(NGHTTP2_HD_HUFFMAN_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_hd_huffman_data.c b/Utilities/cmnghttp2/lib/nghttp2_hd_huffman_data.c
index 2e2e13f..c8f4a6f 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_hd_huffman_data.c
+++ b/Utilities/cmnghttp2/lib/nghttp2_hd_huffman_data.c
@@ -27,4954 +27,4954 @@
 /* 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}};
+  {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},
-    },
+  /* 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
index 93dd475..f54f37c 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_helper.c
+++ b/Utilities/cmnghttp2/lib/nghttp2_helper.c
@@ -53,70 +53,70 @@
 
 /* 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 */,
+  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) {
@@ -160,7 +160,7 @@
     int32_t recv_reduction_delta;
     int32_t delta;
     int32_t new_recv_window_size =
-        nghttp2_max(0, *recv_window_size_ptr) - *delta_ptr;
+      nghttp2_max_int32(0, *recv_window_size_ptr) - *delta_ptr;
 
     if (new_recv_window_size >= 0) {
       *recv_window_size_ptr = new_recv_window_size;
@@ -177,7 +177,7 @@
     *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_delta = nghttp2_min_int32(*recv_reduction_ptr, delta);
     *recv_reduction_ptr -= recv_reduction_delta;
     if (*recv_window_size_ptr < 0) {
       *recv_window_size_ptr += recv_reduction_delta;
@@ -233,7 +233,7 @@
   *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_delta = nghttp2_min_int32(*recv_reduction_ptr, delta);
   *recv_reduction_ptr -= recv_reduction_delta;
 
   *recv_window_size_ptr += recv_reduction_delta;
@@ -336,6 +336,8 @@
            "closed";
   case NGHTTP2_ERR_TOO_MANY_SETTINGS:
     return "SETTINGS frame contained more than the maximum allowed entries";
+  case NGHTTP2_ERR_TOO_MANY_CONTINUATIONS:
+    return "Too many CONTINUATION frames following a HEADER frame";
   default:
     return "Unknown error code";
   }
@@ -343,70 +345,70 @@
 
 /* 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 */
+  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) {
@@ -431,70 +433,70 @@
 
 /* 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 */
+  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) {
@@ -522,70 +524,70 @@
 
 /* Generated by genmethodchartbl.py */
 static char VALID_METHOD_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 /* @    */, 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 /* ^    */, 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 */
+  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 /* @    */, 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 /* ^    */, 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_method(const uint8_t *value, size_t len) {
@@ -603,70 +605,70 @@
 
 /* Generated by genpathchartbl.py */
 static char VALID_PATH_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 /* !    */, 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 */
+  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 /* !    */, 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_path(const uint8_t *value, size_t len) {
@@ -681,70 +683,70 @@
 
 /* Generated by genauthoritychartbl.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 */
+  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) {
diff --git a/Utilities/cmnghttp2/lib/nghttp2_helper.h b/Utilities/cmnghttp2/lib/nghttp2_helper.h
index b1f18ce..7d64076 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_helper.h
+++ b/Utilities/cmnghttp2/lib/nghttp2_helper.h
@@ -27,7 +27,7 @@
 
 #ifdef HAVE_CONFIG_H
 #  include <config.h>
-#endif /* HAVE_CONFIG_H */
+#endif /* defined(HAVE_CONFIG_H) */
 
 #include <string.h>
 #include <stddef.h>
@@ -35,13 +35,36 @@
 #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 nghttp2_max_def(SUFFIX, T)                                             \
+  static inline T nghttp2_max_##SUFFIX(T a, T b) { return a < b ? b : a; }
+
+nghttp2_max_def(int8, int8_t)
+nghttp2_max_def(int16, int16_t)
+nghttp2_max_def(int32, int32_t)
+nghttp2_max_def(int64, int64_t)
+nghttp2_max_def(uint8, uint8_t)
+nghttp2_max_def(uint16, uint16_t)
+nghttp2_max_def(uint32, uint32_t)
+nghttp2_max_def(uint64, uint64_t)
+nghttp2_max_def(size, size_t)
+
+#define nghttp2_min_def(SUFFIX, T)                                             \
+  static inline T nghttp2_min_##SUFFIX(T a, T b) { return a < b ? a : b; }
+
+nghttp2_min_def(int8, int8_t)
+nghttp2_min_def(int16, int16_t)
+nghttp2_min_def(int32, int32_t)
+nghttp2_min_def(int64, int64_t)
+nghttp2_min_def(uint8, uint8_t)
+nghttp2_min_def(uint16, uint16_t)
+nghttp2_min_def(uint32, uint32_t)
+nghttp2_min_def(uint64, uint64_t)
+nghttp2_min_def(size, size_t)
 
 #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)))
+  ((type *)(void *)((char *)(ptr) - offsetof(type, member)))
 
 /*
  * Copies 2 byte unsigned integer |n| in host byte order to |buf| in
@@ -119,4 +142,4 @@
  */
 uint8_t *nghttp2_cpymem(uint8_t *dest, const void *src, size_t len);
 
-#endif /* NGHTTP2_HELPER_H */
+#endif /* !defined(NGHTTP2_HELPER_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_http.c b/Utilities/cmnghttp2/lib/nghttp2_http.c
index 83e5e66..60a0b01 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_http.c
+++ b/Utilities/cmnghttp2/lib/nghttp2_http.c
@@ -31,6 +31,7 @@
 #include "nghttp2_hd.h"
 #include "nghttp2_helper.h"
 #include "nghttp2_extpri.h"
+#include "sfparse.h"
 
 static uint8_t downcase(uint8_t c) {
   return 'A' <= c && c <= 'Z' ? (uint8_t)(c - 'A' + 'a') : c;
@@ -206,7 +207,6 @@
     if (!trailer &&
         /* Do not parse the header field in PUSH_PROMISE. */
         (stream->stream_id & 1) &&
-        (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) &&
         !(stream->http_flags & NGHTTP2_HTTP_FLAG_BAD_PRIORITY)) {
       nghttp2_extpri_from_uint8(&extpri, stream->http_extpri);
       if (nghttp2_http_parse_priority(&extpri, nv->value->base,
@@ -346,6 +346,84 @@
   return 1;
 }
 
+/* Generated by genauthoritychartbl.py, but '@' is not allowed */
+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 /* ?    */,
+  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    */, 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 */
+};
+
+static int 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;
+}
+
 int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream,
                            nghttp2_frame *frame, nghttp2_hd_nv *nv,
                            int trailer) {
@@ -387,10 +465,10 @@
   case NGHTTP2_TOKEN__AUTHORITY:
   case NGHTTP2_TOKEN_HOST:
     if (session->server || frame->hd.type == NGHTTP2_PUSH_PROMISE) {
-      rv = nghttp2_check_authority(nv->value->base, nv->value->len);
+      rv = check_authority(nv->value->base, nv->value->len);
     } else if (
-        stream->flags &
-        NGHTTP2_STREAM_FLAG_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION) {
+      stream->flags &
+      NGHTTP2_STREAM_FLAG_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION) {
       rv = nghttp2_check_header_value(nv->value->base, nv->value->len);
     } else {
       rv = nghttp2_check_header_value_rfc9113(nv->value->base, nv->value->len);
@@ -434,7 +512,7 @@
   if (session->server || frame->hd.type == NGHTTP2_PUSH_PROMISE) {
     return http_request_on_header(stream, nv, trailer,
                                   session->server &&
-                                      session->pending_enable_connect_protocol);
+                                    session->pending_enable_connect_protocol);
   }
 
   return http_response_on_header(stream, nv, trailer);
@@ -452,7 +530,7 @@
     stream->content_length = -1;
   } else {
     if ((stream->http_flags & NGHTTP2_HTTP_FLAG_REQ_HEADERS) !=
-            NGHTTP2_HTTP_FLAG_REQ_HEADERS ||
+          NGHTTP2_HTTP_FLAG_REQ_HEADERS ||
         (stream->http_flags &
          (NGHTTP2_HTTP_FLAG__AUTHORITY | NGHTTP2_HTTP_FLAG_HOST)) == 0) {
       return -1;
@@ -492,7 +570,7 @@
   }
 
   stream->http_flags =
-      stream->http_flags & (uint32_t)~NGHTTP2_HTTP_FLAG_EXPECT_FINAL_RESPONSE;
+    stream->http_flags & (uint32_t)~NGHTTP2_HTTP_FLAG_EXPECT_FINAL_RESPONSE;
 
   if (!expect_response_body(stream)) {
     stream->content_length = 0;
@@ -578,713 +656,52 @@
   }
 }
 
-/* Generated by genchartbl.py */
-static const int SF_KEY_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  */, 0 /* !    */, 0 /* "    */,
-    0 /* #    */, 0 /* $    */, 0 /* %    */, 0 /* &    */, 0 /* '    */,
-    0 /* (    */, 0 /* )    */, 1 /* *    */, 0 /* +    */, 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 /* ]    */, 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 /* }    */, 0 /* ~    */, 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 */,
-};
-
-static ssize_t sf_parse_key(const uint8_t *begin, const uint8_t *end) {
-  const uint8_t *p = begin;
-
-  if ((*p < 'a' || 'z' < *p) && *p != '*') {
-    return -1;
-  }
-
-  for (; p != end && SF_KEY_CHARS[*p]; ++p)
-    ;
-
-  return p - begin;
-}
-
-static ssize_t sf_parse_integer_or_decimal(nghttp2_sf_value *dest,
-                                           const uint8_t *begin,
-                                           const uint8_t *end) {
-  const uint8_t *p = begin;
-  int sign = 1;
-  int64_t value = 0;
-  int type = NGHTTP2_SF_VALUE_TYPE_INTEGER;
-  size_t len = 0;
-  size_t fpos = 0;
-  size_t i;
-
-  if (*p == '-') {
-    if (++p == end) {
-      return -1;
-    }
-
-    sign = -1;
-  }
-
-  if (*p < '0' || '9' < *p) {
-    return -1;
-  }
-
-  for (; p != end; ++p) {
-    switch (*p) {
-    case '0':
-    case '1':
-    case '2':
-    case '3':
-    case '4':
-    case '5':
-    case '6':
-    case '7':
-    case '8':
-    case '9':
-      value *= 10;
-      value += *p - '0';
-
-      if (++len > 15) {
-        return -1;
-      }
-
-      break;
-    case '.':
-      if (type != NGHTTP2_SF_VALUE_TYPE_INTEGER) {
-        goto fin;
-      }
-
-      if (len > 12) {
-        return -1;
-      }
-      fpos = len;
-      type = NGHTTP2_SF_VALUE_TYPE_DECIMAL;
-
-      break;
-    default:
-      goto fin;
-    };
-  }
-
-fin:
-  switch (type) {
-  case NGHTTP2_SF_VALUE_TYPE_INTEGER:
-    if (dest) {
-      dest->type = (uint8_t)type;
-      dest->i = value * sign;
-    }
-
-    return p - begin;
-  case NGHTTP2_SF_VALUE_TYPE_DECIMAL:
-    if (fpos == len || len - fpos > 3) {
-      return -1;
-    }
-
-    if (dest) {
-      dest->type = (uint8_t)type;
-      dest->d = (double)value;
-      for (i = len - fpos; i > 0; --i) {
-        dest->d /= (double)10;
-      }
-      dest->d *= sign;
-    }
-
-    return p - begin;
-  default:
-    assert(0);
-    abort();
-  }
-}
-
-/* Generated by genchartbl.py */
-static const int SF_DQUOTE_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   */, 1 /* SPC  */, 1 /* !    */, 0 /* "    */,
-    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 /* [    */, 0 /* \    */, 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  */, 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 */,
-};
-
-static ssize_t sf_parse_string(nghttp2_sf_value *dest, const uint8_t *begin,
-                               const uint8_t *end) {
-  const uint8_t *p = begin;
-
-  if (*p++ != '"') {
-    return -1;
-  }
-
-  for (; p != end; ++p) {
-    switch (*p) {
-    case '\\':
-      if (++p == end) {
-        return -1;
-      }
-
-      switch (*p) {
-      case '"':
-      case '\\':
-        break;
-      default:
-        return -1;
-      }
-
-      break;
-    case '"':
-      if (dest) {
-        dest->type = NGHTTP2_SF_VALUE_TYPE_STRING;
-        dest->s.base = begin + 1;
-        dest->s.len = (size_t)(p - dest->s.base);
-      }
-
-      ++p;
-
-      return p - begin;
-    default:
-      if (!SF_DQUOTE_CHARS[*p]) {
-        return -1;
-      }
-    }
-  }
-
-  return -1;
-}
-
-/* Generated by genchartbl.py */
-static const int SF_TOKEN_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 /* .    */, 1 /* /    */, 1 /* 0    */, 1 /* 1    */,
-    1 /* 2    */, 1 /* 3    */, 1 /* 4    */, 1 /* 5    */, 1 /* 6    */,
-    1 /* 7    */, 1 /* 8    */, 1 /* 9    */, 1 /* :    */, 0 /* ;    */,
-    0 /* <    */, 0 /* =    */, 0 /* >    */, 0 /* ?    */, 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 /* ^    */,
-    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 */,
-};
-
-static ssize_t sf_parse_token(nghttp2_sf_value *dest, const uint8_t *begin,
-                              const uint8_t *end) {
-  const uint8_t *p = begin;
-
-  if ((*p < 'A' || 'Z' < *p) && (*p < 'a' || 'z' < *p) && *p != '*') {
-    return -1;
-  }
-
-  for (; p != end && SF_TOKEN_CHARS[*p]; ++p)
-    ;
-
-  if (dest) {
-    dest->type = NGHTTP2_SF_VALUE_TYPE_TOKEN;
-    dest->s.base = begin;
-    dest->s.len = (size_t)(p - begin);
-  }
-
-  return p - begin;
-}
-
-/* Generated by genchartbl.py */
-static const int SF_BYTESEQ_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  */, 0 /* !    */, 0 /* "    */,
-    0 /* #    */, 0 /* $    */, 0 /* %    */, 0 /* &    */, 0 /* '    */,
-    0 /* (    */, 0 /* )    */, 0 /* *    */, 1 /* +    */, 0 /* ,    */,
-    0 /* -    */, 0 /* .    */, 1 /* /    */, 1 /* 0    */, 1 /* 1    */,
-    1 /* 2    */, 1 /* 3    */, 1 /* 4    */, 1 /* 5    */, 1 /* 6    */,
-    1 /* 7    */, 1 /* 8    */, 1 /* 9    */, 0 /* :    */, 0 /* ;    */,
-    0 /* <    */, 1 /* =    */, 0 /* >    */, 0 /* ?    */, 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 /* ]    */, 0 /* ^    */,
-    0 /* _    */, 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 /* }    */, 0 /* ~    */, 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 */,
-};
-
-static ssize_t sf_parse_byteseq(nghttp2_sf_value *dest, const uint8_t *begin,
-                                const uint8_t *end) {
-  const uint8_t *p = begin;
-
-  if (*p++ != ':') {
-    return -1;
-  }
-
-  for (; p != end; ++p) {
-    switch (*p) {
-    case ':':
-      if (dest) {
-        dest->type = NGHTTP2_SF_VALUE_TYPE_BYTESEQ;
-        dest->s.base = begin + 1;
-        dest->s.len = (size_t)(p - dest->s.base);
-      }
-
-      ++p;
-
-      return p - begin;
-    default:
-      if (!SF_BYTESEQ_CHARS[*p]) {
-        return -1;
-      }
-    }
-  }
-
-  return -1;
-}
-
-static ssize_t sf_parse_boolean(nghttp2_sf_value *dest, const uint8_t *begin,
-                                const uint8_t *end) {
-  const uint8_t *p = begin;
-  int b;
-
-  if (*p++ != '?') {
-    return -1;
-  }
-
-  if (p == end) {
-    return -1;
-  }
-
-  switch (*p++) {
-  case '0':
-    b = 0;
-    break;
-  case '1':
-    b = 1;
-    break;
-  default:
-    return -1;
-  }
-
-  if (dest) {
-    dest->type = NGHTTP2_SF_VALUE_TYPE_BOOLEAN;
-    dest->b = b;
-  }
-
-  return p - begin;
-}
-
-static ssize_t sf_parse_bare_item(nghttp2_sf_value *dest, const uint8_t *begin,
-                                  const uint8_t *end) {
-  switch (*begin) {
-  case '-':
-  case '0':
-  case '1':
-  case '2':
-  case '3':
-  case '4':
-  case '5':
-  case '6':
-  case '7':
-  case '8':
-  case '9':
-    return sf_parse_integer_or_decimal(dest, begin, end);
-  case '"':
-    return sf_parse_string(dest, begin, end);
-  case '*':
-    return sf_parse_token(dest, begin, end);
-  case ':':
-    return sf_parse_byteseq(dest, begin, end);
-  case '?':
-    return sf_parse_boolean(dest, begin, end);
-  default:
-    if (('A' <= *begin && *begin <= 'Z') || ('a' <= *begin && *begin <= 'z')) {
-      return sf_parse_token(dest, begin, end);
-    }
-    return -1;
-  }
-}
-
-#define sf_discard_sp_end_err(BEGIN, END, ERR)                                 \
-  for (;; ++(BEGIN)) {                                                         \
-    if ((BEGIN) == (END)) {                                                    \
-      return (ERR);                                                            \
-    }                                                                          \
-    if (*(BEGIN) != ' ') {                                                     \
-      break;                                                                   \
-    }                                                                          \
-  }
-
-static ssize_t sf_parse_params(const uint8_t *begin, const uint8_t *end) {
-  const uint8_t *p = begin;
-  ssize_t slen;
-
-  for (; p != end && *p == ';';) {
-    ++p;
-
-    sf_discard_sp_end_err(p, end, -1);
-
-    slen = sf_parse_key(p, end);
-    if (slen < 0) {
-      return -1;
-    }
-
-    p += slen;
-
-    if (p == end || *p != '=') {
-      /* Boolean true */
-    } else if (++p == end) {
-      return -1;
-    } else {
-      slen = sf_parse_bare_item(NULL, p, end);
-      if (slen < 0) {
-        return -1;
-      }
-
-      p += slen;
-    }
-  }
-
-  return p - begin;
-}
-
-static ssize_t sf_parse_item(nghttp2_sf_value *dest, const uint8_t *begin,
-                             const uint8_t *end) {
-  const uint8_t *p = begin;
-  ssize_t slen;
-
-  slen = sf_parse_bare_item(dest, p, end);
-  if (slen < 0) {
-    return -1;
-  }
-
-  p += slen;
-
-  slen = sf_parse_params(p, end);
-  if (slen < 0) {
-    return -1;
-  }
-
-  p += slen;
-
-  return p - begin;
-}
-
-ssize_t nghttp2_sf_parse_item(nghttp2_sf_value *dest, const uint8_t *begin,
-                              const uint8_t *end) {
-  return sf_parse_item(dest, begin, end);
-}
-
-static ssize_t sf_parse_inner_list(nghttp2_sf_value *dest, const uint8_t *begin,
-                                   const uint8_t *end) {
-  const uint8_t *p = begin;
-  ssize_t slen;
-
-  if (*p++ != '(') {
-    return -1;
-  }
-
-  for (;;) {
-    sf_discard_sp_end_err(p, end, -1);
-
-    if (*p == ')') {
-      ++p;
-
-      slen = sf_parse_params(p, end);
-      if (slen < 0) {
-        return -1;
-      }
-
-      p += slen;
-
-      if (dest) {
-        dest->type = NGHTTP2_SF_VALUE_TYPE_INNER_LIST;
-      }
-
-      return p - begin;
-    }
-
-    slen = sf_parse_item(NULL, p, end);
-    if (slen < 0) {
-      return -1;
-    }
-
-    p += slen;
-
-    if (p == end || (*p != ' ' && *p != ')')) {
-      return -1;
-    }
-  }
-}
-
-ssize_t nghttp2_sf_parse_inner_list(nghttp2_sf_value *dest,
-                                    const uint8_t *begin, const uint8_t *end) {
-  return sf_parse_inner_list(dest, begin, end);
-}
-
-static ssize_t sf_parse_item_or_inner_list(nghttp2_sf_value *dest,
-                                           const uint8_t *begin,
-                                           const uint8_t *end) {
-  if (*begin == '(') {
-    return sf_parse_inner_list(dest, begin, end);
-  }
-
-  return sf_parse_item(dest, begin, end);
-}
-
-#define sf_discard_ows(BEGIN, END)                                             \
-  for (;; ++(BEGIN)) {                                                         \
-    if ((BEGIN) == (END)) {                                                    \
-      goto fin;                                                                \
-    }                                                                          \
-    if (*(BEGIN) != ' ' && *(BEGIN) != '\t') {                                 \
-      break;                                                                   \
-    }                                                                          \
-  }
-
-#define sf_discard_ows_end_err(BEGIN, END, ERR)                                \
-  for (;; ++(BEGIN)) {                                                         \
-    if ((BEGIN) == (END)) {                                                    \
-      return (ERR);                                                            \
-    }                                                                          \
-    if (*(BEGIN) != ' ' && *(BEGIN) != '\t') {                                 \
-      break;                                                                   \
-    }                                                                          \
-  }
-
 int nghttp2_http_parse_priority(nghttp2_extpri *dest, const uint8_t *value,
                                 size_t valuelen) {
-  const uint8_t *p = value, *end = value + valuelen;
-  ssize_t slen;
-  nghttp2_sf_value val;
   nghttp2_extpri pri = *dest;
-  const uint8_t *key;
-  size_t keylen;
+  sfparse_parser sfp;
+  sfparse_vec key;
+  sfparse_value val;
+  int rv;
 
-  for (; p != end && *p == ' '; ++p)
-    ;
+  sfparse_parser_init(&sfp, value, valuelen);
 
-  for (; p != end;) {
-    slen = sf_parse_key(p, end);
-    if (slen < 0) {
-      return NGHTTP2_ERR_INVALID_ARGUMENT;
-    }
-
-    key = p;
-    keylen = (size_t)slen;
-
-    p += slen;
-
-    if (p == end || *p != '=') {
-      /* Boolean true */
-      val.type = NGHTTP2_SF_VALUE_TYPE_BOOLEAN;
-      val.b = 1;
-
-      slen = sf_parse_params(p, end);
-      if (slen < 0) {
-        return NGHTTP2_ERR_INVALID_ARGUMENT;
-      }
-    } else if (++p == end) {
-      return NGHTTP2_ERR_INVALID_ARGUMENT;
-    } else {
-      slen = sf_parse_item_or_inner_list(&val, p, end);
-      if (slen < 0) {
-        return NGHTTP2_ERR_INVALID_ARGUMENT;
-      }
-    }
-
-    p += slen;
-
-    if (keylen == 1) {
-      switch (key[0]) {
-      case 'i':
-        if (val.type != NGHTTP2_SF_VALUE_TYPE_BOOLEAN) {
-          return NGHTTP2_ERR_INVALID_ARGUMENT;
-        }
-
-        pri.inc = val.b;
-
-        break;
-      case 'u':
-        if (val.type != NGHTTP2_SF_VALUE_TYPE_INTEGER ||
-            val.i < NGHTTP2_EXTPRI_URGENCY_HIGH ||
-            NGHTTP2_EXTPRI_URGENCY_LOW < val.i) {
-          return NGHTTP2_ERR_INVALID_ARGUMENT;
-        }
-
-        pri.urgency = (uint32_t)val.i;
-
+  for (;;) {
+    rv = sfparse_parser_dict(&sfp, &key, &val);
+    if (rv != 0) {
+      if (rv == SFPARSE_ERR_EOF) {
         break;
       }
-    }
 
-    sf_discard_ows(p, end);
-
-    if (*p++ != ',') {
       return NGHTTP2_ERR_INVALID_ARGUMENT;
     }
 
-    sf_discard_ows_end_err(p, end, NGHTTP2_ERR_INVALID_ARGUMENT);
+    if (key.len != 1) {
+      continue;
+    }
+
+    switch (key.base[0]) {
+    case 'i':
+      if (val.type != SFPARSE_TYPE_BOOLEAN) {
+        return NGHTTP2_ERR_INVALID_ARGUMENT;
+      }
+
+      pri.inc = val.boolean;
+
+      break;
+    case 'u':
+      if (val.type != SFPARSE_TYPE_INTEGER ||
+          val.integer < NGHTTP2_EXTPRI_URGENCY_HIGH ||
+          NGHTTP2_EXTPRI_URGENCY_LOW < val.integer) {
+        return NGHTTP2_ERR_INVALID_ARGUMENT;
+      }
+
+      pri.urgency = (uint32_t)val.integer;
+
+      break;
+    }
   }
 
-fin:
   *dest = pri;
 
   return 0;
diff --git a/Utilities/cmnghttp2/lib/nghttp2_http.h b/Utilities/cmnghttp2/lib/nghttp2_http.h
index 0c3a78e..2925334 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_http.h
+++ b/Utilities/cmnghttp2/lib/nghttp2_http.h
@@ -27,7 +27,7 @@
 
 #ifdef HAVE_CONFIG_H
 #  include <config.h>
-#endif /* HAVE_CONFIG_H */
+#endif /* defined(HAVE_CONFIG_H) */
 
 #include <nghttp2/nghttp2.h>
 #include "nghttp2_session.h"
@@ -94,55 +94,7 @@
 void nghttp2_http_record_request_method(nghttp2_stream *stream,
                                         nghttp2_frame *frame);
 
-/*
- * RFC 8941 Structured Field Values.
- */
-typedef enum nghttp2_sf_value_type {
-  NGHTTP2_SF_VALUE_TYPE_BOOLEAN,
-  NGHTTP2_SF_VALUE_TYPE_INTEGER,
-  NGHTTP2_SF_VALUE_TYPE_DECIMAL,
-  NGHTTP2_SF_VALUE_TYPE_STRING,
-  NGHTTP2_SF_VALUE_TYPE_TOKEN,
-  NGHTTP2_SF_VALUE_TYPE_BYTESEQ,
-  NGHTTP2_SF_VALUE_TYPE_INNER_LIST,
-} nghttp2_sf_value_type;
-
-/*
- * nghttp2_sf_value stores Structured Field Values item.  For Inner
- * List, only type is set to NGHTTP2_SF_VALUE_TYPE_INNER_LIST.
- */
-typedef struct nghttp2_sf_value {
-  uint8_t type;
-  union {
-    int b;
-    int64_t i;
-    double d;
-    struct {
-      const uint8_t *base;
-      size_t len;
-    } s;
-  };
-} nghttp2_sf_value;
-
-/*
- * nghttp2_sf_parse_item parses the input sequence [|begin|, |end|)
- * and stores the parsed an Item in |dest|.  It returns the number of
- * bytes consumed if it succeeds, or -1.  This function is declared
- * here for unit tests.
- */
-ssize_t nghttp2_sf_parse_item(nghttp2_sf_value *dest, const uint8_t *begin,
-                              const uint8_t *end);
-
-/*
- * nghttp2_sf_parse_inner_list parses the input sequence [|begin|, |end|)
- * and stores the parsed an Inner List in |dest|.  It returns the number of
- * bytes consumed if it succeeds, or -1.  This function is declared
- * here for unit tests.
- */
-ssize_t nghttp2_sf_parse_inner_list(nghttp2_sf_value *dest,
-                                    const uint8_t *begin, const uint8_t *end);
-
 int nghttp2_http_parse_priority(nghttp2_extpri *dest, const uint8_t *value,
                                 size_t valuelen);
 
-#endif /* NGHTTP2_HTTP_H */
+#endif /* !defined(NGHTTP2_HTTP_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_int.h b/Utilities/cmnghttp2/lib/nghttp2_int.h
index b23585c..d89cf15 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_int.h
+++ b/Utilities/cmnghttp2/lib/nghttp2_int.h
@@ -27,7 +27,7 @@
 
 #ifdef HAVE_CONFIG_H
 #  include <config.h>
-#endif /* HAVE_CONFIG_H */
+#endif /* defined(HAVE_CONFIG_H) */
 
 #include <nghttp2/nghttp2.h>
 
@@ -52,7 +52,11 @@
    * Unlike NGHTTP2_ERR_IGN_HTTP_HEADER, this does not invoke
    * nghttp2_on_invalid_header_callback.
    */
-  NGHTTP2_ERR_REMOVE_HTTP_HEADER = -106
+  NGHTTP2_ERR_REMOVE_HTTP_HEADER = -106,
+  /*
+   * Cancel pushed stream.
+   */
+  NGHTTP2_ERR_PUSH_CANCEL = -107,
 } nghttp2_internal_error;
 
-#endif /* NGHTTP2_INT_H */
+#endif /* !defined(NGHTTP2_INT_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_map.c b/Utilities/cmnghttp2/lib/nghttp2_map.c
index e5db168..f89f310 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_map.c
+++ b/Utilities/cmnghttp2/lib/nghttp2_map.c
@@ -31,21 +31,14 @@
 
 #include "nghttp2_helper.h"
 
-#define NGHTTP2_INITIAL_TABLE_LENBITS 8
+#define NGHTTP2_INITIAL_HASHBITS 4
 
-int nghttp2_map_init(nghttp2_map *map, nghttp2_mem *mem) {
+void nghttp2_map_init(nghttp2_map *map, uint32_t seed, nghttp2_mem *mem) {
   map->mem = mem;
-  map->tablelen = 1 << NGHTTP2_INITIAL_TABLE_LENBITS;
-  map->tablelenbits = NGHTTP2_INITIAL_TABLE_LENBITS;
-  map->table =
-      nghttp2_mem_calloc(mem, map->tablelen, sizeof(nghttp2_map_bucket));
-  if (map->table == NULL) {
-    return NGHTTP2_ERR_NOMEM;
-  }
-
+  map->hashbits = 0;
+  map->table = NULL;
+  map->seed = seed;
   map->size = 0;
-
-  return 0;
 }
 
 void nghttp2_map_free(nghttp2_map *map) {
@@ -56,29 +49,20 @@
   nghttp2_mem_free(map->mem, map->table);
 }
 
-void nghttp2_map_each_free(nghttp2_map *map, int (*func)(void *data, void *ptr),
-                           void *ptr) {
-  uint32_t i;
-  nghttp2_map_bucket *bkt;
-
-  for (i = 0; i < map->tablelen; ++i) {
-    bkt = &map->table[i];
-
-    if (bkt->data == NULL) {
-      continue;
-    }
-
-    func(bkt->data, ptr);
-  }
-}
-
-int nghttp2_map_each(nghttp2_map *map, int (*func)(void *data, void *ptr),
+int nghttp2_map_each(const nghttp2_map *map, int (*func)(void *data, void *ptr),
                      void *ptr) {
   int rv;
-  uint32_t i;
+  size_t i;
   nghttp2_map_bucket *bkt;
+  size_t tablelen;
 
-  for (i = 0; i < map->tablelen; ++i) {
+  if (map->size == 0) {
+    return 0;
+  }
+
+  tablelen = 1u << map->hashbits;
+
+  for (i = 0; i < tablelen; ++i) {
     bkt = &map->table[i];
 
     if (bkt->data == NULL) {
@@ -94,80 +78,70 @@
   return 0;
 }
 
-static uint32_t hash(nghttp2_map_key_type key) {
-  return (uint32_t)key * 2654435769u;
+static size_t map_hash(const nghttp2_map *map, nghttp2_map_key_type key) {
+  /* hasher from
+     https://github.com/rust-lang/rustc-hash/blob/dc5c33f1283de2da64d8d7a06401d91aded03ad4/src/lib.rs
+     We do not perform finalization here because we use top bits
+     anyway. */
+  uint32_t h = ((uint32_t)key + map->seed) * 0x93d765dd;
+  return (size_t)((h * 2654435769u) >> (32 - map->hashbits));
 }
 
-static size_t h2idx(uint32_t hash, uint32_t bits) {
-  return hash >> (32 - bits);
+static void map_bucket_swap(nghttp2_map_bucket *a, nghttp2_map_bucket *b) {
+  nghttp2_map_bucket c = *a;
+
+  *a = *b;
+  *b = c;
 }
 
-static size_t distance(uint32_t tablelen, uint32_t tablelenbits,
-                       nghttp2_map_bucket *bkt, size_t idx) {
-  return (idx - h2idx(bkt->hash, tablelenbits)) & (tablelen - 1);
-}
-
-static void map_bucket_swap(nghttp2_map_bucket *bkt, uint32_t *phash,
-                            nghttp2_map_key_type *pkey, void **pdata) {
-  uint32_t h = bkt->hash;
-  nghttp2_map_key_type key = bkt->key;
-  void *data = bkt->data;
-
-  bkt->hash = *phash;
-  bkt->key = *pkey;
-  bkt->data = *pdata;
-
-  *phash = h;
-  *pkey = key;
-  *pdata = data;
-}
-
-static void map_bucket_set_data(nghttp2_map_bucket *bkt, uint32_t hash,
-                                nghttp2_map_key_type key, void *data) {
-  bkt->hash = hash;
-  bkt->key = key;
-  bkt->data = data;
-}
-
-void nghttp2_map_print_distance(nghttp2_map *map) {
-  uint32_t i;
+#ifndef WIN32
+void nghttp2_map_print_distance(const nghttp2_map *map) {
+  size_t i;
   size_t idx;
   nghttp2_map_bucket *bkt;
+  size_t tablelen;
 
-  for (i = 0; i < map->tablelen; ++i) {
+  if (map->size == 0) {
+    return;
+  }
+
+  tablelen = 1u << map->hashbits;
+
+  for (i = 0; i < tablelen; ++i) {
     bkt = &map->table[i];
 
     if (bkt->data == NULL) {
-      fprintf(stderr, "@%u <EMPTY>\n", i);
+      fprintf(stderr, "@%zu <EMPTY>\n", i);
       continue;
     }
 
-    idx = h2idx(bkt->hash, map->tablelenbits);
-    fprintf(stderr, "@%u hash=%08x key=%d base=%zu distance=%zu\n", i,
-            bkt->hash, bkt->key, idx,
-            distance(map->tablelen, map->tablelenbits, bkt, idx));
+    idx = map_hash(map, bkt->key);
+    fprintf(stderr, "@%zu hash=%zu key=%d base=%zu distance=%u\n", i,
+            map_hash(map, bkt->key), bkt->key, idx, bkt->psl);
   }
 }
+#endif /* !defined(WIN32) */
 
-static int insert(nghttp2_map_bucket *table, uint32_t tablelen,
-                  uint32_t tablelenbits, uint32_t hash,
-                  nghttp2_map_key_type key, void *data) {
-  size_t idx = h2idx(hash, tablelenbits);
-  size_t d = 0, dd;
+static int map_insert(nghttp2_map *map, nghttp2_map_key_type key, void *data) {
+  size_t idx = map_hash(map, key);
+  nghttp2_map_bucket b = {
+    .key = key,
+    .data = data,
+  };
   nghttp2_map_bucket *bkt;
+  size_t mask = (1u << map->hashbits) - 1;
 
   for (;;) {
-    bkt = &table[idx];
+    bkt = &map->table[idx];
 
     if (bkt->data == NULL) {
-      map_bucket_set_data(bkt, hash, key, data);
+      *bkt = b;
+      ++map->size;
       return 0;
     }
 
-    dd = distance(tablelen, tablelenbits, bkt, idx);
-    if (d > dd) {
-      map_bucket_swap(bkt, &hash, &key, &data);
-      d = dd;
+    if (b.psl > bkt->psl) {
+      map_bucket_swap(bkt, &b);
     } else if (bkt->key == key) {
       /* TODO This check is just a waste after first swap or if this
          function is called from map_resize.  That said, there is no
@@ -176,42 +150,47 @@
       return NGHTTP2_ERR_INVALID_ARGUMENT;
     }
 
-    ++d;
-    idx = (idx + 1) & (tablelen - 1);
+    ++b.psl;
+    idx = (idx + 1) & mask;
   }
 }
 
-/* new_tablelen must be power of 2 and new_tablelen == (1 <<
-   new_tablelenbits) must hold. */
-static int map_resize(nghttp2_map *map, uint32_t new_tablelen,
-                      uint32_t new_tablelenbits) {
-  uint32_t i;
-  nghttp2_map_bucket *new_table;
+static int map_resize(nghttp2_map *map, size_t new_hashbits) {
+  size_t i;
   nghttp2_map_bucket *bkt;
+  size_t tablelen;
   int rv;
+  nghttp2_map new_map = {
+    .table = nghttp2_mem_calloc(map->mem, 1u << new_hashbits,
+                                sizeof(nghttp2_map_bucket)),
+    .mem = map->mem,
+    .seed = map->seed,
+    .hashbits = new_hashbits,
+  };
   (void)rv;
 
-  new_table =
-      nghttp2_mem_calloc(map->mem, new_tablelen, sizeof(nghttp2_map_bucket));
-  if (new_table == NULL) {
+  if (new_map.table == NULL) {
     return NGHTTP2_ERR_NOMEM;
   }
 
-  for (i = 0; i < map->tablelen; ++i) {
-    bkt = &map->table[i];
-    if (bkt->data == NULL) {
-      continue;
-    }
-    rv = insert(new_table, new_tablelen, new_tablelenbits, bkt->hash, bkt->key,
-                bkt->data);
+  if (map->size) {
+    tablelen = 1u << map->hashbits;
 
-    assert(0 == rv);
+    for (i = 0; i < tablelen; ++i) {
+      bkt = &map->table[i];
+      if (bkt->data == NULL) {
+        continue;
+      }
+
+      rv = map_insert(&new_map, bkt->key, bkt->data);
+
+      assert(0 == rv);
+    }
   }
 
   nghttp2_mem_free(map->mem, map->table);
-  map->tablelen = new_tablelen;
-  map->tablelenbits = new_tablelenbits;
-  map->table = new_table;
+  map->table = new_map.table;
+  map->hashbits = new_hashbits;
 
   return 0;
 }
@@ -221,34 +200,48 @@
 
   assert(data);
 
-  /* Load factor is 0.75 */
-  if ((map->size + 1) * 4 > map->tablelen * 3) {
-    rv = map_resize(map, map->tablelen * 2, map->tablelenbits + 1);
-    if (rv != 0) {
-      return rv;
+  /* Load factor is 7/8 */
+  /* Under the very initial condition, that is map->size == 0 and
+     map->hashbits == 0, 8 > 7 still holds nicely. */
+  if ((map->size + 1) * 8 > (1u << map->hashbits) * 7) {
+    if (map->hashbits) {
+      rv = map_resize(map, map->hashbits + 1);
+      if (rv != 0) {
+        return rv;
+      }
+    } else {
+      rv = map_resize(map, NGHTTP2_INITIAL_HASHBITS);
+      if (rv != 0) {
+        return rv;
+      }
     }
   }
 
-  rv = insert(map->table, map->tablelen, map->tablelenbits, hash(key), key,
-              data);
+  rv = map_insert(map, key, data);
   if (rv != 0) {
     return rv;
   }
-  ++map->size;
+
   return 0;
 }
 
-void *nghttp2_map_find(nghttp2_map *map, nghttp2_map_key_type key) {
-  uint32_t h = hash(key);
-  size_t idx = h2idx(h, map->tablelenbits);
+void *nghttp2_map_find(const nghttp2_map *map, nghttp2_map_key_type key) {
+  size_t idx;
   nghttp2_map_bucket *bkt;
-  size_t d = 0;
+  size_t psl = 0;
+  size_t mask;
+
+  if (map->size == 0) {
+    return NULL;
+  }
+
+  idx = map_hash(map, key);
+  mask = (1u << map->hashbits) - 1;
 
   for (;;) {
     bkt = &map->table[idx];
 
-    if (bkt->data == NULL ||
-        d > distance(map->tablelen, map->tablelenbits, bkt, idx)) {
+    if (bkt->data == NULL || psl > bkt->psl) {
       return NULL;
     }
 
@@ -256,43 +249,47 @@
       return bkt->data;
     }
 
-    ++d;
-    idx = (idx + 1) & (map->tablelen - 1);
+    ++psl;
+    idx = (idx + 1) & mask;
   }
 }
 
 int nghttp2_map_remove(nghttp2_map *map, nghttp2_map_key_type key) {
-  uint32_t h = hash(key);
-  size_t idx = h2idx(h, map->tablelenbits), didx;
-  nghttp2_map_bucket *bkt;
-  size_t d = 0;
+  size_t idx;
+  nghttp2_map_bucket *b, *bkt;
+  size_t psl = 0;
+  size_t mask;
+
+  if (map->size == 0) {
+    return NGHTTP2_ERR_INVALID_ARGUMENT;
+  }
+
+  idx = map_hash(map, key);
+  mask = (1u << map->hashbits) - 1;
 
   for (;;) {
     bkt = &map->table[idx];
 
-    if (bkt->data == NULL ||
-        d > distance(map->tablelen, map->tablelenbits, bkt, idx)) {
+    if (bkt->data == NULL || psl > bkt->psl) {
       return NGHTTP2_ERR_INVALID_ARGUMENT;
     }
 
     if (bkt->key == key) {
-      map_bucket_set_data(bkt, 0, 0, NULL);
-
-      didx = idx;
-      idx = (idx + 1) & (map->tablelen - 1);
+      b = bkt;
+      idx = (idx + 1) & mask;
 
       for (;;) {
         bkt = &map->table[idx];
-        if (bkt->data == NULL ||
-            distance(map->tablelen, map->tablelenbits, bkt, idx) == 0) {
+        if (bkt->data == NULL || bkt->psl == 0) {
+          b->data = NULL;
           break;
         }
 
-        map->table[didx] = *bkt;
-        map_bucket_set_data(bkt, 0, 0, NULL);
-        didx = idx;
+        --bkt->psl;
+        *b = *bkt;
+        b = bkt;
 
-        idx = (idx + 1) & (map->tablelen - 1);
+        idx = (idx + 1) & mask;
       }
 
       --map->size;
@@ -300,14 +297,18 @@
       return 0;
     }
 
-    ++d;
-    idx = (idx + 1) & (map->tablelen - 1);
+    ++psl;
+    idx = (idx + 1) & mask;
   }
 }
 
 void nghttp2_map_clear(nghttp2_map *map) {
-  memset(map->table, 0, sizeof(*map->table) * map->tablelen);
+  if (map->size == 0) {
+    return;
+  }
+
+  memset(map->table, 0, sizeof(*map->table) * (1u << map->hashbits));
   map->size = 0;
 }
 
-size_t nghttp2_map_size(nghttp2_map *map) { return map->size; }
+size_t nghttp2_map_size(const nghttp2_map *map) { return map->size; }
diff --git a/Utilities/cmnghttp2/lib/nghttp2_map.h b/Utilities/cmnghttp2/lib/nghttp2_map.h
index 1419a09..e45685b 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_map.h
+++ b/Utilities/cmnghttp2/lib/nghttp2_map.h
@@ -28,7 +28,7 @@
 
 #ifdef HAVE_CONFIG_H
 #  include <config.h>
-#endif /* HAVE_CONFIG_H */
+#endif /* defined(HAVE_CONFIG_H) */
 
 #include <nghttp2/nghttp2.h>
 
@@ -39,7 +39,7 @@
 typedef int32_t nghttp2_map_key_type;
 
 typedef struct nghttp2_map_bucket {
-  uint32_t hash;
+  uint32_t psl;
   nghttp2_map_key_type key;
   void *data;
 } nghttp2_map_bucket;
@@ -47,40 +47,26 @@
 typedef struct nghttp2_map {
   nghttp2_map_bucket *table;
   nghttp2_mem *mem;
+  uint32_t seed;
   size_t size;
-  uint32_t tablelen;
-  uint32_t tablelenbits;
+  size_t hashbits;
 } 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
+ * nghttp2_map_init initializes the map |map|.
  */
-int nghttp2_map_init(nghttp2_map *map, nghttp2_mem *mem);
+void nghttp2_map_init(nghttp2_map *map, uint32_t seed, 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.
+ * nghttp2_map_free deallocates any resources allocated for |map|.
+ * The stored entries are not freed by this function.  Use
+ * nghttp2_map_each() to free each entry.
  */
 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 |data| 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)(void *data, void *ptr),
-                           void *ptr);
-
-/*
- * Inserts the new |data| with the |key| to the map |map|.
+ * nghttp2_map_insert inserts the new |data| with the |key| to the map
+ * |map|.
  *
  * This function returns 0 if it succeeds, or one of the following
  * negative error codes:
@@ -88,55 +74,56 @@
  * NGHTTP2_ERR_INVALID_ARGUMENT
  *     The item associated by |key| already exists.
  * NGHTTP2_ERR_NOMEM
- *   Out of memory
+ *     Out of memory
  */
 int nghttp2_map_insert(nghttp2_map *map, nghttp2_map_key_type key, void *data);
 
 /*
- * Returns the data associated by the key |key|.  If there is no such
- * data, this function returns NULL.
+ * nghttp2_map_find returns the entry associated by the key |key|.  If
+ * there is no such entry, this function returns NULL.
  */
-void *nghttp2_map_find(nghttp2_map *map, nghttp2_map_key_type key);
+void *nghttp2_map_find(const nghttp2_map *map, nghttp2_map_key_type key);
 
 /*
- * Removes the data associated by the key |key| from the |map|.  The
- * removed data is not freed by this function.
+ * nghttp2_map_remove 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 data associated by |key| does not exist.
+ *     The entry associated by |key| does not exist.
  */
 int nghttp2_map_remove(nghttp2_map *map, nghttp2_map_key_type key);
 
 /*
- * Removes all entries from |map|.
+ * nghttp2_map_clear removes all entries from |map|.  The removed
+ * entry is not freed by this function.
  */
 void nghttp2_map_clear(nghttp2_map *map);
 
 /*
- * Returns the number of items stored in the map |map|.
+ * nghttp2_map_size returns the number of items stored in the map
+ * |map|.
  */
-size_t nghttp2_map_size(nghttp2_map *map);
+size_t nghttp2_map_size(const nghttp2_map *map);
 
 /*
- * Applies the function |func| to each data in the |map| with the
- * optional user supplied pointer |ptr|.
+ * nghttp2_map_each 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 data.  If the |func| returns nonzero, it will not call 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 data. Use
- * nghttp2_map_each_free() instead.
  */
-int nghttp2_map_each(nghttp2_map *map, int (*func)(void *data, void *ptr),
+int nghttp2_map_each(const nghttp2_map *map, int (*func)(void *data, void *ptr),
                      void *ptr);
 
-void nghttp2_map_print_distance(nghttp2_map *map);
+#ifndef WIN32
+void nghttp2_map_print_distance(const nghttp2_map *map);
+#endif /* !defined(WIN32) */
 
-#endif /* NGHTTP2_MAP_H */
+#endif /* !defined(NGHTTP2_MAP_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_mem.h b/Utilities/cmnghttp2/lib/nghttp2_mem.h
index f83dbcb..10af7c6 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_mem.h
+++ b/Utilities/cmnghttp2/lib/nghttp2_mem.h
@@ -27,7 +27,7 @@
 
 #ifdef HAVE_CONFIG_H
 #  include <config.h>
-#endif /* HAVE_CONFIG_H */
+#endif /* defined(HAVE_CONFIG_H) */
 
 #include <nghttp2/nghttp2.h>
 
@@ -42,4 +42,4 @@
 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 */
+#endif /* !defined(NGHTTP2_MEM_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_net.h b/Utilities/cmnghttp2/lib/nghttp2_net.h
index 521f981..0c57d94 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_net.h
+++ b/Utilities/cmnghttp2/lib/nghttp2_net.h
@@ -27,28 +27,28 @@
 
 #ifdef HAVE_CONFIG_H
 #  include <config.h>
-#endif /* HAVE_CONFIG_H */
+#endif /* defined(HAVE_CONFIG_H) */
 
 #ifdef HAVE_ARPA_INET_H
 #  include <arpa/inet.h>
-#endif /* HAVE_ARPA_INET_H */
+#endif /* defined(HAVE_ARPA_INET_H) */
 
 #ifdef HAVE_NETINET_IN_H
 #  include <netinet/in.h>
-#endif /* HAVE_NETINET_IN_H */
+#endif /* defined(HAVE_NETINET_IN_H) */
 
 #include <nghttp2/nghttp2.h>
 
-#if defined(WIN32)
+#ifdef WIN32
 /* Windows requires ws2_32 library for ntonl family functions.  We
    define inline functions for those function so that we don't have
    dependency on that lib. */
 
 #  ifdef _MSC_VER
 #    define STIN static __inline
-#  else
+#  else /* !defined(_MSC_VER) */
 #    define STIN static inline
-#  endif
+#  endif /* !defined(_MSC_VER) */
 
 STIN uint32_t htonl(uint32_t hostlong) {
   uint32_t res;
@@ -86,6 +86,6 @@
   return res;
 }
 
-#endif /* WIN32 */
+#endif /* defined(WIN32) */
 
-#endif /* NGHTTP2_NET_H */
+#endif /* !defined(NGHTTP2_NET_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_option.c b/Utilities/cmnghttp2/lib/nghttp2_option.c
index ee0cd0f..7e44a24 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_option.c
+++ b/Utilities/cmnghttp2/lib/nghttp2_option.c
@@ -132,14 +132,33 @@
 }
 
 void nghttp2_option_set_server_fallback_rfc7540_priorities(
-    nghttp2_option *option, int val) {
+  nghttp2_option *option, int val) {
   option->opt_set_mask |= NGHTTP2_OPT_SERVER_FALLBACK_RFC7540_PRIORITIES;
   option->server_fallback_rfc7540_priorities = val;
 }
 
 void nghttp2_option_set_no_rfc9113_leading_and_trailing_ws_validation(
-    nghttp2_option *option, int val) {
+  nghttp2_option *option, int val) {
   option->opt_set_mask |=
-      NGHTTP2_OPT_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION;
+    NGHTTP2_OPT_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION;
   option->no_rfc9113_leading_and_trailing_ws_validation = val;
 }
+
+void nghttp2_option_set_stream_reset_rate_limit(nghttp2_option *option,
+                                                uint64_t burst, uint64_t rate) {
+  option->opt_set_mask |= NGHTTP2_OPT_STREAM_RESET_RATE_LIMIT;
+  option->stream_reset_burst = burst;
+  option->stream_reset_rate = rate;
+}
+
+void nghttp2_option_set_max_continuations(nghttp2_option *option, size_t val) {
+  option->opt_set_mask |= NGHTTP2_OPT_MAX_CONTINUATIONS;
+  option->max_continuations = val;
+}
+
+void nghttp2_option_set_glitch_rate_limit(nghttp2_option *option,
+                                          uint64_t burst, uint64_t rate) {
+  option->opt_set_mask |= NGHTTP2_OPT_GLITCH_RATE_LIMIT;
+  option->glitch_burst = burst;
+  option->glitch_rate = rate;
+}
diff --git a/Utilities/cmnghttp2/lib/nghttp2_option.h b/Utilities/cmnghttp2/lib/nghttp2_option.h
index b228a07..711185b 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_option.h
+++ b/Utilities/cmnghttp2/lib/nghttp2_option.h
@@ -27,7 +27,7 @@
 
 #ifdef HAVE_CONFIG_H
 #  include <config.h>
-#endif /* HAVE_CONFIG_H */
+#endif /* defined(HAVE_CONFIG_H) */
 
 #include <nghttp2/nghttp2.h>
 
@@ -70,6 +70,9 @@
   NGHTTP2_OPT_MAX_SETTINGS = 1 << 12,
   NGHTTP2_OPT_SERVER_FALLBACK_RFC7540_PRIORITIES = 1 << 13,
   NGHTTP2_OPT_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION = 1 << 14,
+  NGHTTP2_OPT_STREAM_RESET_RATE_LIMIT = 1 << 15,
+  NGHTTP2_OPT_MAX_CONTINUATIONS = 1 << 16,
+  NGHTTP2_OPT_GLITCH_RATE_LIMIT = 1 << 17,
 } nghttp2_option_flag;
 
 /**
@@ -77,6 +80,16 @@
  */
 struct nghttp2_option {
   /**
+   * NGHTTP2_OPT_STREAM_RESET_RATE_LIMIT
+   */
+  uint64_t stream_reset_burst;
+  uint64_t stream_reset_rate;
+  /**
+   * NGHTTP2_OPT_GLITCH_RATE_LIMIT
+   */
+  uint64_t glitch_burst;
+  uint64_t glitch_rate;
+  /**
    * NGHTTP2_OPT_MAX_SEND_HEADER_BLOCK_LENGTH
    */
   size_t max_send_header_block_length;
@@ -93,6 +106,10 @@
    */
   size_t max_settings;
   /**
+   * NGHTTP2_OPT_MAX_CONTINUATIONS
+   */
+  size_t max_continuations;
+  /**
    * Bitwise OR of nghttp2_option_flag to determine that which fields
    * are specified.
    */
@@ -143,4 +160,4 @@
   uint8_t user_recv_ext_types[32];
 };
 
-#endif /* NGHTTP2_OPTION_H */
+#endif /* !defined(NGHTTP2_OPTION_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_outbound_item.c b/Utilities/cmnghttp2/lib/nghttp2_outbound_item.c
index 2a3041d..a9e9f76 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_outbound_item.c
+++ b/Utilities/cmnghttp2/lib/nghttp2_outbound_item.c
@@ -27,6 +27,32 @@
 #include <assert.h>
 #include <string.h>
 
+nghttp2_data_provider_wrap *
+nghttp2_data_provider_wrap_v1(nghttp2_data_provider_wrap *dpw,
+                              const nghttp2_data_provider *data_prd) {
+  if (!data_prd) {
+    return NULL;
+  }
+
+  dpw->version = NGHTTP2_DATA_PROVIDER_V1;
+  dpw->data_prd.v1 = *data_prd;
+
+  return dpw;
+}
+
+nghttp2_data_provider_wrap *
+nghttp2_data_provider_wrap_v2(nghttp2_data_provider_wrap *dpw,
+                              const nghttp2_data_provider2 *data_prd) {
+  if (!data_prd) {
+    return NULL;
+  }
+
+  dpw->version = NGHTTP2_DATA_PROVIDER_V2;
+  dpw->data_prd.v2 = *data_prd;
+
+  return dpw;
+}
+
 void nghttp2_outbound_item_init(nghttp2_outbound_item *item) {
   item->cycle = 0;
   item->qnext = NULL;
diff --git a/Utilities/cmnghttp2/lib/nghttp2_outbound_item.h b/Utilities/cmnghttp2/lib/nghttp2_outbound_item.h
index bd4611b..6e8e310 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_outbound_item.h
+++ b/Utilities/cmnghttp2/lib/nghttp2_outbound_item.h
@@ -27,15 +27,38 @@
 
 #ifdef HAVE_CONFIG_H
 #  include <config.h>
-#endif /* HAVE_CONFIG_H */
+#endif /* defined(HAVE_CONFIG_H) */
 
 #include <nghttp2/nghttp2.h>
 #include "nghttp2_frame.h"
 #include "nghttp2_mem.h"
 
+#define NGHTTP2_DATA_PROVIDER_V1 1
+#define NGHTTP2_DATA_PROVIDER_V2 2
+
+typedef struct nghttp2_data_provider_wrap {
+  int version;
+  union {
+    struct {
+      nghttp2_data_source source;
+      void *read_callback;
+    };
+    nghttp2_data_provider v1;
+    nghttp2_data_provider2 v2;
+  } data_prd;
+} nghttp2_data_provider_wrap;
+
+nghttp2_data_provider_wrap *
+nghttp2_data_provider_wrap_v1(nghttp2_data_provider_wrap *dpw,
+                              const nghttp2_data_provider *data_prd);
+
+nghttp2_data_provider_wrap *
+nghttp2_data_provider_wrap_v2(nghttp2_data_provider_wrap *dpw,
+                              const nghttp2_data_provider2 *data_prd);
+
 /* struct used for HEADERS and PUSH_PROMISE frame */
 typedef struct {
-  nghttp2_data_provider data_prd;
+  nghttp2_data_provider_wrap dpw;
   void *stream_user_data;
   /* error code when request HEADERS is canceled by RST_STREAM while
      it is in queue. */
@@ -50,7 +73,7 @@
   /**
    * The data to be sent for this DATA frame.
    */
-  nghttp2_data_provider data_prd;
+  nghttp2_data_provider_wrap dpw;
   /**
    * The flags of DATA frame.  We use separate flags here and
    * nghttp2_data frame.  The latter contains flags actually sent to
@@ -163,4 +186,4 @@
 /* Returns the size of the queue */
 #define nghttp2_outbound_queue_size(Q) ((Q)->n)
 
-#endif /* NGHTTP2_OUTBOUND_ITEM_H */
+#endif /* !defined(NGHTTP2_OUTBOUND_ITEM_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_pq.c b/Utilities/cmnghttp2/lib/nghttp2_pq.c
index 64353ac..e79ba83 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_pq.c
+++ b/Utilities/cmnghttp2/lib/nghttp2_pq.c
@@ -69,7 +69,7 @@
     void *nq;
     size_t ncapacity;
 
-    ncapacity = nghttp2_max(4, (pq->capacity * 2));
+    ncapacity = nghttp2_max_size(4, (pq->capacity * 2));
 
     nq = nghttp2_mem_realloc(pq->mem, pq->q,
                              ncapacity * sizeof(nghttp2_pq_entry *));
diff --git a/Utilities/cmnghttp2/lib/nghttp2_pq.h b/Utilities/cmnghttp2/lib/nghttp2_pq.h
index c8d90ef..5dd863f 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_pq.h
+++ b/Utilities/cmnghttp2/lib/nghttp2_pq.h
@@ -27,7 +27,7 @@
 
 #ifdef HAVE_CONFIG_H
 #  include <config.h>
-#endif /* HAVE_CONFIG_H */
+#endif /* defined(HAVE_CONFIG_H) */
 
 #include <nghttp2/nghttp2.h>
 #include "nghttp2_int.h"
@@ -121,4 +121,4 @@
  */
 void nghttp2_pq_remove(nghttp2_pq *pq, nghttp2_pq_entry *item);
 
-#endif /* NGHTTP2_PQ_H */
+#endif /* !defined(NGHTTP2_PQ_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_priority_spec.h b/Utilities/cmnghttp2/lib/nghttp2_priority_spec.h
index 92ece82..158e0dc 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_priority_spec.h
+++ b/Utilities/cmnghttp2/lib/nghttp2_priority_spec.h
@@ -27,7 +27,7 @@
 
 #ifdef HAVE_CONFIG_H
 #  include <config.h>
-#endif /* HAVE_CONFIG_H */
+#endif /* defined(HAVE_CONFIG_H) */
 
 #include <nghttp2/nghttp2.h>
 
@@ -39,4 +39,4 @@
  */
 void nghttp2_priority_spec_normalize_weight(nghttp2_priority_spec *pri_spec);
 
-#endif /* NGHTTP2_PRIORITY_SPEC_H */
+#endif /* !defined(NGHTTP2_PRIORITY_SPEC_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_queue.c b/Utilities/cmnghttp2/lib/nghttp2_queue.c
index 055eb69..3b63158 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_queue.c
+++ b/Utilities/cmnghttp2/lib/nghttp2_queue.c
@@ -46,7 +46,7 @@
 
 int nghttp2_queue_push(nghttp2_queue *queue, void *data) {
   nghttp2_queue_cell *new_cell =
-      (nghttp2_queue_cell *)malloc(sizeof(nghttp2_queue_cell));
+    (nghttp2_queue_cell *)malloc(sizeof(nghttp2_queue_cell));
   if (!new_cell) {
     return NGHTTP2_ERR_NOMEM;
   }
diff --git a/Utilities/cmnghttp2/lib/nghttp2_queue.h b/Utilities/cmnghttp2/lib/nghttp2_queue.h
index a06fa6c..c63897c 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_queue.h
+++ b/Utilities/cmnghttp2/lib/nghttp2_queue.h
@@ -27,7 +27,7 @@
 
 #ifdef HAVE_CONFIG_H
 #  include "config.h"
-#endif /* HAVE_CONFIG_H */
+#endif /* defined(HAVE_CONFIG_H) */
 
 #include <nghttp2/nghttp2.h>
 
@@ -48,4 +48,4 @@
 void *nghttp2_queue_back(nghttp2_queue *queue);
 int nghttp2_queue_empty(nghttp2_queue *queue);
 
-#endif /* NGHTTP2_QUEUE_H */
+#endif /* !defined(NGHTTP2_QUEUE_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_ratelim.c b/Utilities/cmnghttp2/lib/nghttp2_ratelim.c
new file mode 100644
index 0000000..604ac08
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_ratelim.c
@@ -0,0 +1,75 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2023 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.
+ */
+#include "nghttp2_ratelim.h"
+#include "nghttp2_helper.h"
+
+void nghttp2_ratelim_init(nghttp2_ratelim *rl, uint64_t burst, uint64_t rate) {
+  rl->val = rl->burst = burst;
+  rl->rate = rate;
+  rl->tstamp = 0;
+}
+
+void nghttp2_ratelim_update(nghttp2_ratelim *rl, uint64_t tstamp) {
+  uint64_t d, gain;
+
+  if (tstamp == rl->tstamp) {
+    return;
+  }
+
+  if (tstamp > rl->tstamp) {
+    d = tstamp - rl->tstamp;
+  } else {
+    d = 1;
+  }
+
+  rl->tstamp = tstamp;
+
+  if (UINT64_MAX / d < rl->rate) {
+    rl->val = rl->burst;
+
+    return;
+  }
+
+  gain = rl->rate * d;
+
+  if (UINT64_MAX - gain < rl->val) {
+    rl->val = rl->burst;
+
+    return;
+  }
+
+  rl->val += gain;
+  rl->val = nghttp2_min_uint64(rl->val, rl->burst);
+}
+
+int nghttp2_ratelim_drain(nghttp2_ratelim *rl, uint64_t n) {
+  if (rl->val < n) {
+    return -1;
+  }
+
+  rl->val -= n;
+
+  return 0;
+}
diff --git a/Utilities/cmnghttp2/lib/nghttp2_ratelim.h b/Utilities/cmnghttp2/lib/nghttp2_ratelim.h
new file mode 100644
index 0000000..d1097f2
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_ratelim.h
@@ -0,0 +1,57 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2023 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.
+ */
+#ifndef NGHTTP2_RATELIM_H
+#define NGHTTP2_RATELIM_H
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif /* defined(HAVE_CONFIG_H) */
+
+#include <nghttp2/nghttp2.h>
+
+typedef struct nghttp2_ratelim {
+  /* burst is the maximum value of val. */
+  uint64_t burst;
+  /* rate is the amount of value that is regenerated per 1 tstamp. */
+  uint64_t rate;
+  /* val is the amount of value available to drain. */
+  uint64_t val;
+  /* tstamp is the last timestamp in second resolution that is known
+     to this object. */
+  uint64_t tstamp;
+} nghttp2_ratelim;
+
+/* nghttp2_ratelim_init initializes |rl| with the given parameters. */
+void nghttp2_ratelim_init(nghttp2_ratelim *rl, uint64_t burst, uint64_t rate);
+
+/* nghttp2_ratelim_update updates rl->val with the current |tstamp|
+   given in second resolution. */
+void nghttp2_ratelim_update(nghttp2_ratelim *rl, uint64_t tstamp);
+
+/* nghttp2_ratelim_drain drains |n| from rl->val.  It returns 0 if it
+   succeeds, or -1. */
+int nghttp2_ratelim_drain(nghttp2_ratelim *rl, uint64_t n);
+
+#endif /* !defined(NGHTTP2_RATELIM_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_rcbuf.h b/Utilities/cmnghttp2/lib/nghttp2_rcbuf.h
index 6814e70..ef82e1b 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_rcbuf.h
+++ b/Utilities/cmnghttp2/lib/nghttp2_rcbuf.h
@@ -27,7 +27,7 @@
 
 #ifdef HAVE_CONFIG_H
 #  include <config.h>
-#endif /* HAVE_CONFIG_H */
+#endif /* defined(HAVE_CONFIG_H) */
 
 #include <nghttp2/nghttp2.h>
 
@@ -77,4 +77,4 @@
  */
 void nghttp2_rcbuf_del(nghttp2_rcbuf *rcbuf);
 
-#endif /* NGHTTP2_RCBUF_H */
+#endif /* !defined(NGHTTP2_RCBUF_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_session.c b/Utilities/cmnghttp2/lib/nghttp2_session.c
index 93f3f07..1f4ea54 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_session.c
+++ b/Utilities/cmnghttp2/lib/nghttp2_session.c
@@ -37,7 +37,11 @@
 #include "nghttp2_http.h"
 #include "nghttp2_pq.h"
 #include "nghttp2_extpri.h"
+#include "nghttp2_time.h"
 #include "nghttp2_debug.h"
+#include "nghttp2_submit.h"
+
+nghttp2_stream nghttp2_stream_root;
 
 /*
  * Returns non-zero if the number of outgoing opened streams is larger
@@ -144,11 +148,6 @@
   return 0;
 }
 
-static int session_no_rfc7540_pri_no_fallback(nghttp2_session *session) {
-  return session->pending_no_rfc7540_priorities == 1 &&
-         !session->fallback_rfc7540_priorities;
-}
-
 static int check_ext_type_set(const uint8_t *ext_types, uint8_t type) {
   return (ext_types[type / 8] & (1 << (type & 0x7))) > 0;
 }
@@ -237,9 +236,9 @@
     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);
+  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;
@@ -437,8 +436,9 @@
   int rv;
   size_t nbuffer;
   size_t max_deflate_dynamic_table_size =
-      NGHTTP2_HD_DEFAULT_MAX_DEFLATE_BUFFER_SIZE;
+    NGHTTP2_HD_DEFAULT_MAX_DEFLATE_BUFFER_SIZE;
   size_t i;
+  uint32_t map_seed;
 
   if (mem == NULL) {
     mem = nghttp2_mem_default();
@@ -456,10 +456,6 @@
   /* 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;
@@ -471,10 +467,18 @@
   (*session_ptr)->remote_last_stream_id = (1u << 31) - 1;
 
   (*session_ptr)->pending_local_max_concurrent_stream =
-      NGHTTP2_DEFAULT_MAX_CONCURRENT_STREAMS;
+    NGHTTP2_DEFAULT_MAX_CONCURRENT_STREAMS;
   (*session_ptr)->pending_enable_push = 1;
   (*session_ptr)->pending_no_rfc7540_priorities = UINT8_MAX;
 
+  nghttp2_ratelim_init(&(*session_ptr)->stream_reset_ratelim,
+                       NGHTTP2_DEFAULT_STREAM_RESET_BURST,
+                       NGHTTP2_DEFAULT_STREAM_RESET_RATE);
+
+  nghttp2_ratelim_init(&(*session_ptr)->glitch_ratelim,
+                       NGHTTP2_DEFAULT_GLITCH_BURST,
+                       NGHTTP2_DEFAULT_GLITCH_RATE);
+
   if (server) {
     (*session_ptr)->server = 1;
   }
@@ -483,7 +487,7 @@
   init_settings(&(*session_ptr)->local_settings);
 
   (*session_ptr)->max_incoming_reserved_streams =
-      NGHTTP2_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;
@@ -491,35 +495,31 @@
   (*session_ptr)->max_send_header_block_length = NGHTTP2_MAX_HEADERSLEN;
   (*session_ptr)->max_outbound_ack = NGHTTP2_DEFAULT_MAX_OBQ_FLOOD_ITEM;
   (*session_ptr)->max_settings = NGHTTP2_DEFAULT_MAX_SETTINGS;
+  (*session_ptr)->max_continuations = NGHTTP2_DEFAULT_MAX_CONTINUATIONS;
 
   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;
+        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;
+        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;
     }
 
@@ -539,18 +539,13 @@
 
     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;
+        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;
     }
@@ -561,17 +556,25 @@
     }
 
     if ((option->opt_set_mask &
-         NGHTTP2_OPT_SERVER_FALLBACK_RFC7540_PRIORITIES) &&
-        option->server_fallback_rfc7540_priorities) {
-      (*session_ptr)->opt_flags |=
-          NGHTTP2_OPTMASK_SERVER_FALLBACK_RFC7540_PRIORITIES;
-    }
-
-    if ((option->opt_set_mask &
          NGHTTP2_OPT_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION) &&
         option->no_rfc9113_leading_and_trailing_ws_validation) {
       (*session_ptr)->opt_flags |=
-          NGHTTP2_OPTMASK_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION;
+        NGHTTP2_OPTMASK_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION;
+    }
+
+    if (option->opt_set_mask & NGHTTP2_OPT_STREAM_RESET_RATE_LIMIT) {
+      nghttp2_ratelim_init(&(*session_ptr)->stream_reset_ratelim,
+                           option->stream_reset_burst,
+                           option->stream_reset_rate);
+    }
+
+    if (option->opt_set_mask & NGHTTP2_OPT_MAX_CONTINUATIONS) {
+      (*session_ptr)->max_continuations = option->max_continuations;
+    }
+
+    if (option->opt_set_mask & NGHTTP2_OPT_GLITCH_RATE_LIMIT) {
+      nghttp2_ratelim_init(&(*session_ptr)->glitch_ratelim,
+                           option->glitch_burst, option->glitch_rate);
     }
   }
 
@@ -584,10 +587,6 @@
   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) /
@@ -605,6 +604,14 @@
     goto fail_aob_framebuf;
   }
 
+  if (callbacks->rand_callback) {
+    callbacks->rand_callback((uint8_t *)&map_seed, sizeof(map_seed));
+  } else {
+    map_seed = 0;
+  }
+
+  nghttp2_map_init(&(*session_ptr)->streams, map_seed, mem);
+
   active_outbound_item_reset(&(*session_ptr)->aob, mem);
 
   (*session_ptr)->callbacks = *callbacks;
@@ -637,8 +644,6 @@
   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);
@@ -802,11 +807,10 @@
   for (i = 0; i < NGHTTP2_EXTPRI_URGENCY_LEVELS; ++i) {
     nghttp2_pq_free(&session->sched[i].ob_data);
   }
-  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_each(&session->streams, free_streams, session);
   nghttp2_map_free(&session->streams);
 
   ob_q_free(&session->ob_urgent, mem);
@@ -821,83 +825,6 @@
   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((!session->server && session->pending_no_rfc7540_priorities != 1) ||
-         (session->server && !session_no_rfc7540_pri_no_fallback(session)));
-  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;
-}
-
 static uint64_t pq_get_first_cycle(nghttp2_pq *pq) {
   nghttp2_stream *stream;
 
@@ -916,7 +843,6 @@
   int inc;
   nghttp2_pq *pq;
 
-  assert(stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES);
   assert(stream->queued == 0);
 
   urgency = nghttp2_extpri_uint8_urgency(stream->extpri);
@@ -941,11 +867,10 @@
   return 0;
 }
 
-static int session_ob_data_remove(nghttp2_session *session,
-                                  nghttp2_stream *stream) {
+static void session_ob_data_remove(nghttp2_session *session,
+                                   nghttp2_stream *stream) {
   uint32_t urgency;
 
-  assert(stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES);
   assert(stream->queued == 1);
 
   urgency = nghttp2_extpri_uint8_urgency(stream->extpri);
@@ -955,8 +880,6 @@
   nghttp2_pq_remove(&session->sched[urgency].ob_data, &stream->pq_entry);
 
   stream->queued = 0;
-
-  return 0;
 }
 
 static int session_attach_stream_item(nghttp2_session *session,
@@ -964,64 +887,46 @@
                                       nghttp2_outbound_item *item) {
   int rv;
 
-  rv = nghttp2_stream_attach_item(stream, item);
+  nghttp2_stream_attach_item(stream, item);
+
+  rv = session_ob_data_push(session, stream);
   if (rv != 0) {
+    nghttp2_stream_detach_item(stream);
+
     return rv;
   }
 
-  if (!(stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES)) {
-    return 0;
-  }
-
-  return session_ob_data_push(session, stream);
+  return 0;
 }
 
-static int session_detach_stream_item(nghttp2_session *session,
-                                      nghttp2_stream *stream) {
-  int rv;
+static void session_detach_stream_item(nghttp2_session *session,
+                                       nghttp2_stream *stream) {
+  nghttp2_stream_detach_item(stream);
 
-  rv = nghttp2_stream_detach_item(stream);
-  if (rv != 0) {
-    return rv;
+  if (!stream->queued) {
+    return;
   }
 
-  if (!(stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) ||
-      !stream->queued) {
-    return 0;
-  }
-
-  return session_ob_data_remove(session, stream);
+  session_ob_data_remove(session, stream);
 }
 
-static int session_defer_stream_item(nghttp2_session *session,
-                                     nghttp2_stream *stream, uint8_t flags) {
-  int rv;
+static void session_defer_stream_item(nghttp2_session *session,
+                                      nghttp2_stream *stream, uint8_t flags) {
+  nghttp2_stream_defer_item(stream, flags);
 
-  rv = nghttp2_stream_defer_item(stream, flags);
-  if (rv != 0) {
-    return rv;
+  if (!stream->queued) {
+    return;
   }
 
-  if (!(stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) ||
-      !stream->queued) {
-    return 0;
-  }
-
-  return session_ob_data_remove(session, stream);
+  session_ob_data_remove(session, stream);
 }
 
 static int session_resume_deferred_stream_item(nghttp2_session *session,
                                                nghttp2_stream *stream,
                                                uint8_t flags) {
-  int rv;
+  nghttp2_stream_resume_deferred_item(stream, flags);
 
-  rv = nghttp2_stream_resume_deferred_item(stream, flags);
-  if (rv != 0) {
-    return rv;
-  }
-
-  if (!(stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) ||
-      (stream->flags & NGHTTP2_STREAM_FLAG_DEFERRED_ALL)) {
+  if (stream->flags & NGHTTP2_STREAM_FLAG_DEFERRED_ALL) {
     return 0;
   }
 
@@ -1166,7 +1071,6 @@
     return 0;
   case NGHTTP2_PUSH_PROMISE: {
     nghttp2_headers_aux_data *aux_data;
-    nghttp2_priority_spec pri_spec;
 
     aux_data = &item->aux_data.headers;
 
@@ -1174,20 +1078,13 @@
       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)) {
+          session, frame->push_promise.promised_stream_id,
+          NGHTTP2_STREAM_FLAG_NONE, 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;
 
@@ -1211,6 +1108,15 @@
 
 int nghttp2_session_add_rst_stream(nghttp2_session *session, int32_t stream_id,
                                    uint32_t error_code) {
+  return nghttp2_session_add_rst_stream_continue(
+    session, stream_id, error_code,
+    /* continue_without_stream = */ 1);
+}
+
+int nghttp2_session_add_rst_stream_continue(nghttp2_session *session,
+                                            int32_t stream_id,
+                                            uint32_t error_code,
+                                            int continue_without_stream) {
   int rv;
   nghttp2_outbound_item *item;
   nghttp2_frame *frame;
@@ -1246,7 +1152,6 @@
     assert(headers_frame->hd.type == NGHTTP2_HEADERS);
 
     if (headers_frame->hd.stream_id <= stream_id) {
-
       for (item = session->ob_syn.head; item; item = item->qnext) {
         aux_data = &item->aux_data.headers;
 
@@ -1268,6 +1173,12 @@
     }
   }
 
+  /* To keep the old behaviour, do not fail if stream was not
+     found. */
+  if (!continue_without_stream && !stream) {
+    return 0;
+  }
+
   item = nghttp2_mem_malloc(mem, sizeof(nghttp2_outbound_item));
   if (item == NULL) {
     return NGHTTP2_ERR_NOMEM;
@@ -1289,15 +1200,11 @@
 
 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;
@@ -1310,21 +1217,9 @@
 
   if (stream) {
     assert(stream->state == NGHTTP2_STREAM_IDLE);
-    assert((stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) ||
-           nghttp2_stream_in_dep_tree(stream));
+    assert(initial_state != NGHTTP2_STREAM_IDLE);
 
-    if (nghttp2_stream_in_dep_tree(stream)) {
-      assert(!(stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES));
-      nghttp2_session_detach_idle_stream(session, stream);
-      rv = nghttp2_stream_dep_remove(stream);
-      if (rv != 0) {
-        return NULL;
-      }
-
-      if (session_no_rfc7540_pri_no_fallback(session)) {
-        stream->flags |= NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES;
-      }
-    }
+    --session->num_idle_streams;
   } else {
     stream = nghttp2_mem_malloc(mem, sizeof(nghttp2_stream));
     if (stream == NULL) {
@@ -1334,69 +1229,16 @@
     stream_alloc = 1;
   }
 
-  if (session_no_rfc7540_pri_no_fallback(session) ||
-      session->remote_settings.no_rfc7540_priorities == 1) {
-    /* For client which has not received server
-       SETTINGS_NO_RFC7540_PRIORITIES = 1, send a priority signal
-       opportunistically. */
-    if (session->server ||
-        session->remote_settings.no_rfc7540_priorities == 1) {
-      nghttp2_priority_spec_default_init(&pri_spec_default);
-      pri_spec = &pri_spec_default;
-    }
-
-    if (session->pending_no_rfc7540_priorities == 1) {
-      flags |= NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES;
-    }
-  } else 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);
-
-    if (session_no_rfc7540_pri_no_fallback(session)) {
-      stream->seq = session->stream_seq++;
-    }
+                        stream_user_data);
+    stream->seq = session->stream_seq++;
 
     rv = nghttp2_map_insert(&session->streams, stream_id, stream);
     if (rv != 0) {
@@ -1407,7 +1249,6 @@
   } else {
     stream->flags = flags;
     stream->state = initial_state;
-    stream->weight = pri_spec->weight;
     stream->stream_user_data = stream_user_data;
   }
 
@@ -1425,9 +1266,7 @@
        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);
+    ++session->num_idle_streams;
     break;
   default:
     if (nghttp2_session_is_my_stream_id(session, stream_id)) {
@@ -1437,31 +1276,11 @@
     }
   }
 
-  if (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) {
-    return stream;
-  }
-
-  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;
@@ -1475,27 +1294,6 @@
 
   DEBUGF("stream: stream(%p)=%d close\n", stream, stream->stream_id);
 
-  if (stream->item) {
-    nghttp2_outbound_item *item;
-
-    item = stream->item;
-
-    rv = session_detach_stream_item(session, 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
@@ -1505,12 +1303,28 @@
 
   if (session->callbacks.on_stream_close_callback) {
     if (session->callbacks.on_stream_close_callback(
-            session, stream_id, error_code, session->user_data) != 0) {
-
+          session, stream_id, error_code, session->user_data) != 0) {
       return NGHTTP2_ERR_CALLBACK_FAILURE;
     }
   }
 
+  if (stream->item) {
+    nghttp2_outbound_item *item;
+
+    item = stream->item;
+
+    session_detach_stream_item(session, stream);
+
+    /* 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);
+    }
+  }
+
   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
@@ -1530,201 +1344,26 @@
   /* Closes both directions just in case they are not closed yet */
   stream->flags |= NGHTTP2_STREAM_FLAG_CLOSED;
 
-  if (session->pending_no_rfc7540_priorities == 1) {
-    return nghttp2_session_destroy_stream(session, stream);
-  }
-
-  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;
-    }
-  }
+  nghttp2_session_destroy_stream(session, stream);
 
   return 0;
 }
 
-int nghttp2_session_destroy_stream(nghttp2_session *session,
-                                   nghttp2_stream *stream) {
+void 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;
-    }
+  if (stream->queued) {
+    session_ob_data_remove(session, stream);
   }
 
   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;
 }
 
 /*
@@ -2112,19 +1751,19 @@
 
 /* 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) {
+static nghttp2_ssize nghttp2_session_enforce_flow_control_limits(
+  nghttp2_session *session, nghttp2_stream *stream,
+  nghttp2_ssize 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);
+  return nghttp2_min_int32(
+    nghttp2_min_int32(nghttp2_min_int32((int32_t)requested_window_size,
+                                        stream->remote_window_size),
+                      session->remote_window_size),
+    (int32_t)session->remote_settings.max_frame_size);
 }
 
 /*
@@ -2135,12 +1774,12 @@
  */
 static size_t nghttp2_session_next_data_read(nghttp2_session *session,
                                              nghttp2_stream *stream) {
-  ssize_t window_size;
+  nghttp2_ssize window_size;
 
   window_size = nghttp2_session_enforce_flow_control_limits(
-      session, stream, NGHTTP2_DATA_PAYLOADLEN);
+    session, stream, NGHTTP2_DATA_PAYLOADLEN);
 
-  DEBUGF("send: available window=%zd\n", window_size);
+  DEBUGF("send: available window=%td\n", window_size);
 
   return window_size > 0 ? (size_t)window_size : 0;
 }
@@ -2195,29 +1834,33 @@
   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;
+static nghttp2_ssize session_call_select_padding(nghttp2_session *session,
+                                                 const nghttp2_frame *frame,
+                                                 size_t max_payloadlen) {
+  nghttp2_ssize rv;
+  size_t max_paddedlen;
 
-  if (frame->hd.length >= max_payloadlen) {
-    return (ssize_t)frame->hd.length;
+  if (frame->hd.length >= max_payloadlen ||
+      (!session->callbacks.select_padding_callback2 &&
+       !session->callbacks.select_padding_callback)) {
+    return (nghttp2_ssize)frame->hd.length;
   }
 
-  if (session->callbacks.select_padding_callback) {
-    size_t max_paddedlen;
+  max_paddedlen =
+    nghttp2_min_size(frame->hd.length + NGHTTP2_MAX_PADLEN, max_payloadlen);
 
-    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;
+  if (session->callbacks.select_padding_callback2) {
+    rv = session->callbacks.select_padding_callback2(
+      session, frame, max_paddedlen, session->user_data);
+  } else {
+    rv = (nghttp2_ssize)session->callbacks.select_padding_callback(
+      session, frame, max_paddedlen, session->user_data);
   }
-  return (ssize_t)frame->hd.length;
+  if (rv < (nghttp2_ssize)frame->hd.length ||
+      rv > (nghttp2_ssize)max_paddedlen) {
+    return NGHTTP2_ERR_CALLBACK_FAILURE;
+  }
+  return rv;
 }
 
 /* Add padding to HEADERS or PUSH_PROMISE. We use
@@ -2225,8 +1868,7 @@
    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_ssize padded_payloadlen;
   nghttp2_active_outbound_item *aob;
   nghttp2_bufs *framebufs;
   size_t padlen;
@@ -2235,11 +1877,11 @@
   aob = &session->aob;
   framebufs = &aob->framebufs;
 
-  max_payloadlen = nghttp2_min(NGHTTP2_MAX_PAYLOADLEN,
-                               frame->hd.length + NGHTTP2_MAX_PADLEN);
+  max_payloadlen = nghttp2_min_size(NGHTTP2_MAX_PAYLOADLEN,
+                                    frame->hd.length + NGHTTP2_MAX_PADLEN);
 
   padded_payloadlen =
-      session_call_select_padding(session, frame, max_payloadlen);
+    session_call_select_padding(session, frame, max_payloadlen);
 
   if (nghttp2_is_fatal((int)padded_payloadlen)) {
     return (int)padded_payloadlen;
@@ -2247,14 +1889,10 @@
 
   padlen = (size_t)padded_payloadlen - frame->hd.length;
 
-  DEBUGF("send: padding selected: payloadlen=%zd, padlen=%zu\n",
+  DEBUGF("send: padding selected: payloadlen=%td, padlen=%zu\n",
          padded_payloadlen, padlen);
 
-  rv = nghttp2_frame_add_pad(framebufs, &frame->hd, padlen, 0);
-
-  if (rv != 0) {
-    return rv;
-  }
+  nghttp2_frame_add_pad(framebufs, &frame->hd, padlen, 0);
 
   frame->headers.padlen = padlen;
 
@@ -2271,18 +1909,24 @@
 
 static int session_pack_extension(nghttp2_session *session, nghttp2_bufs *bufs,
                                   nghttp2_frame *frame) {
-  ssize_t rv;
+  nghttp2_ssize rv;
   nghttp2_buf *buf;
   size_t buflen;
   size_t framelen;
 
-  assert(session->callbacks.pack_extension_callback);
+  assert(session->callbacks.pack_extension_callback2 ||
+         session->callbacks.pack_extension_callback);
 
   buf = &bufs->head->buf;
-  buflen = nghttp2_min(nghttp2_buf_avail(buf), NGHTTP2_MAX_PAYLOADLEN);
+  buflen = nghttp2_min_size(nghttp2_buf_avail(buf), NGHTTP2_MAX_PAYLOADLEN);
 
-  rv = session->callbacks.pack_extension_callback(session, buf->last, buflen,
-                                                  frame, session->user_data);
+  if (session->callbacks.pack_extension_callback2) {
+    rv = session->callbacks.pack_extension_callback2(session, buf->last, buflen,
+                                                     frame, session->user_data);
+  } else {
+    rv = (nghttp2_ssize)session->callbacks.pack_extension_callback(
+      session, buf->last, buflen, frame, session->user_data);
+  }
   if (rv == NGHTTP2_ERR_CANCEL) {
     return (int)rv;
   }
@@ -2337,13 +1981,7 @@
       // Search stream including closed again.
       stream = nghttp2_session_get_stream_raw(session, frame->hd.stream_id);
       if (stream) {
-        int rv2;
-
-        rv2 = session_detach_stream_item(session, stream);
-
-        if (nghttp2_is_fatal(rv2)) {
-          return rv2;
-        }
+        session_detach_stream_item(session, stream);
       }
 
       return rv;
@@ -2353,47 +1991,34 @@
     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 = session_defer_stream_item(session, stream,
-                                     NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL);
-
-      if (nghttp2_is_fatal(rv)) {
-        return rv;
-      }
+      session_defer_stream_item(session, stream,
+                                NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL);
 
       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);
+    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 = session_defer_stream_item(session, stream,
-                                     NGHTTP2_STREAM_FLAG_DEFERRED_USER);
-
-      if (nghttp2_is_fatal(rv)) {
-        return rv;
-      }
+      session_defer_stream_item(session, stream,
+                                NGHTTP2_STREAM_FLAG_DEFERRED_USER);
 
       session->aob.item = NULL;
       active_outbound_item_reset(&session->aob, mem);
       return NGHTTP2_ERR_DEFERRED;
     }
     if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
-      rv = session_detach_stream_item(session, stream);
-
-      if (nghttp2_is_fatal(rv)) {
-        return rv;
-      }
+      session_detach_stream_item(session, stream);
 
       rv = nghttp2_session_add_rst_stream(session, frame->hd.stream_id,
                                           NGHTTP2_INTERNAL_ERROR);
@@ -2403,13 +2028,7 @@
       return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
     }
     if (rv != 0) {
-      int rv2;
-
-      rv2 = session_detach_stream_item(session, stream);
-
-      if (nghttp2_is_fatal(rv2)) {
-        return rv2;
-      }
+      session_detach_stream_item(session, stream);
 
       return rv;
     }
@@ -2426,17 +2045,13 @@
       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);
+        session, frame->hd.stream_id, NGHTTP2_STREAM_FLAG_NONE,
+        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;
@@ -2475,8 +2090,8 @@
     }
 
     estimated_payloadlen = session_estimate_headers_payload(
-        session, frame->headers.nva, frame->headers.nvlen,
-        NGHTTP2_PRIORITY_SPECLEN);
+      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;
@@ -2489,7 +2104,7 @@
       return rv;
     }
 
-    DEBUGF("send: before padding, HEADERS serialized in %zd bytes\n",
+    DEBUGF("send: before padding, HEADERS serialized in %zu bytes\n",
            nghttp2_bufs_len(&session->aob.framebufs));
 
     rv = session_headers_add_pad(session, frame);
@@ -2498,7 +2113,7 @@
       return rv;
     }
 
-    DEBUGF("send: HEADERS finally serialized in %zd bytes\n",
+    DEBUGF("send: HEADERS finally serialized in %zu bytes\n",
            nghttp2_bufs_len(&session->aob.framebufs));
 
     if (frame->headers.cat == NGHTTP2_HCAT_REQUEST) {
@@ -2564,14 +2179,14 @@
     assert(stream);
 
     estimated_payloadlen = session_estimate_headers_payload(
-        session, frame->push_promise.nva, frame->push_promise.nvlen, 0);
+      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);
+      &session->aob.framebufs, &frame->push_promise, &session->hd_deflater);
     if (rv != 0) {
       return rv;
     }
@@ -2678,8 +2293,6 @@
 
 nghttp2_outbound_item *
 nghttp2_session_get_next_ob_item(nghttp2_session *session) {
-  nghttp2_outbound_item *item;
-
   if (nghttp2_outbound_queue_top(&session->ob_urgent)) {
     return nghttp2_outbound_queue_top(&session->ob_urgent);
   }
@@ -2695,11 +2308,6 @@
   }
 
   if (session->remote_window_size > 0) {
-    item = nghttp2_stream_next_outbound_item(&session->root);
-    if (item) {
-      return item;
-    }
-
     return session_sched_get_next_outbound_item(session);
   }
 
@@ -2734,11 +2342,6 @@
   }
 
   if (session->remote_window_size > 0) {
-    item = nghttp2_stream_next_outbound_item(&session->root);
-    if (item) {
-      return item;
-    }
-
     return session_sched_get_next_outbound_item(session);
   }
 
@@ -2797,7 +2400,6 @@
        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;
@@ -2853,11 +2455,6 @@
                                       nghttp2_stream *stream) {
   stream->last_writelen = stream->item->frame.hd.length;
 
-  if (!(stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES)) {
-    nghttp2_stream_reschedule(stream);
-    return;
-  }
-
   if (!session->server) {
     return;
   }
@@ -2911,14 +2508,11 @@
     }
 
     if (stream && aux_data->eof) {
-      rv = session_detach_stream_item(session, stream);
-      if (nghttp2_is_fatal(rv)) {
-        return rv;
-      }
+      session_detach_stream_item(session, stream);
 
       /* Call on_frame_send_callback after
          nghttp2_stream_detach_item(), so that application can issue
-         nghttp2_submit_data() in the callback. */
+         nghttp2_submit_data2() in the callback. */
       if (session->callbacks.on_frame_send_callback) {
         rv = session_call_on_frame_send(session, frame);
         if (nghttp2_is_fatal(rv)) {
@@ -2930,7 +2524,7 @@
         int stream_closed;
 
         stream_closed =
-            (stream->shut_flags & NGHTTP2_SHUT_RDWR) == NGHTTP2_SHUT_RDWR;
+          (stream->shut_flags & NGHTTP2_SHUT_RDWR) == NGHTTP2_SHUT_RDWR;
 
         nghttp2_stream_shutdown(stream, NGHTTP2_SHUT_WR);
 
@@ -2990,15 +2584,17 @@
       }
       /* 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 (aux_data->dpw.data_prd.read_callback) {
+        /* nghttp2_submit_data_shared() makes a copy of
+           aux_data->dpw */
+        rv = nghttp2_submit_data_shared(session, NGHTTP2_FLAG_END_STREAM,
+                                        frame->hd.stream_id, &aux_data->dpw);
         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. */
+        /* TODO nghttp2_submit_data_shared() may fail if stream has
+           already DATA frame item.  We might have to handle it
+           here. */
       }
       return 0;
     }
@@ -3019,14 +2615,15 @@
       }
       /* 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 (aux_data->dpw.data_prd.read_callback) {
+        rv = nghttp2_submit_data_shared(session, NGHTTP2_FLAG_END_STREAM,
+                                        frame->hd.stream_id, &aux_data->dpw);
         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. */
+        /* TODO nghttp2_submit_data_shared() may fail if stream has
+           already DATA frame item.  We might have to handle it
+           here. */
       }
       return 0;
     default:
@@ -3036,37 +2633,6 @@
     }
   }
   case NGHTTP2_PRIORITY:
-    if (session->server || session->pending_no_rfc7540_priorities == 1) {
-      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,
@@ -3081,7 +2647,6 @@
     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;
       }
@@ -3131,7 +2696,7 @@
       rv = session_update_stream_consumed_size(session, stream, 0);
     } else {
       rv =
-          nghttp2_session_update_recv_stream_window_size(session, stream, 0, 1);
+        nghttp2_session_update_recv_stream_window_size(session, stream, 0, 1);
     }
 
     if (nghttp2_is_fatal(rv)) {
@@ -3147,17 +2712,8 @@
 /*
  * 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;
+static void session_after_frame_sent2(nghttp2_session *session) {
   nghttp2_active_outbound_item *aob = &session->aob;
   nghttp2_outbound_item *item = aob->item;
   nghttp2_bufs *framebufs = &aob->framebufs;
@@ -3170,23 +2726,21 @@
   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;
+        return;
       }
     }
 
     active_outbound_item_reset(&session->aob, mem);
 
-    return 0;
+    return;
   }
 
   /* DATA frame */
@@ -3194,13 +2748,13 @@
   aux_data = &item->aux_data.data;
 
   /* On EOF, we have already detached data.  Please note that
-     application may issue nghttp2_submit_data() in
+     application may issue nghttp2_submit_data2() 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;
+    return;
   }
 
   /* Reset no_copy here because next write may not use this. */
@@ -3212,22 +2766,18 @@
      further data. */
   if (nghttp2_session_predicate_data_send(session, stream) != 0) {
     if (stream) {
-      rv = session_detach_stream_item(session, stream);
-
-      if (nghttp2_is_fatal(rv)) {
-        return rv;
-      }
+      session_detach_stream_item(session, stream);
     }
 
     active_outbound_item_reset(aob, mem);
 
-    return 0;
+    return;
   }
 
   aob->item = NULL;
   active_outbound_item_reset(&session->aob, mem);
 
-  return 0;
+  return;
 }
 
 static int session_call_send_data(nghttp2_session *session,
@@ -3245,7 +2795,7 @@
   aux_data = &item->aux_data.data;
 
   rv = session->callbacks.send_data_callback(session, frame, buf->pos, length,
-                                             &aux_data->data_prd.source,
+                                             &aux_data->dpw.data_prd.source,
                                              session->user_data);
 
   switch (rv) {
@@ -3259,9 +2809,9 @@
   }
 }
 
-static ssize_t nghttp2_session_mem_send_internal(nghttp2_session *session,
-                                                 const uint8_t **data_ptr,
-                                                 int fast_cb) {
+static nghttp2_ssize 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;
@@ -3271,14 +2821,6 @@
   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: {
@@ -3300,6 +2842,7 @@
       if (rv < 0) {
         int32_t opened_stream_id = 0;
         uint32_t error_code = NGHTTP2_INTERNAL_ERROR;
+        int rv2 = 0;
 
         DEBUGF("send: frame preparation failed with %s\n",
                nghttp2_strerror(rv));
@@ -3313,8 +2856,7 @@
              it. */
           if (frame->hd.type != NGHTTP2_WINDOW_UPDATE &&
               session->callbacks.on_frame_not_send_callback(
-                  session, frame, rv, session->user_data) != 0) {
-
+                session, frame, rv, session->user_data) != 0) {
             nghttp2_outbound_item_free(item, mem);
             nghttp2_mem_free(mem, item);
 
@@ -3342,24 +2884,23 @@
         }
         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;
-          }
+          rv2 =
+            nghttp2_session_close_stream(session, opened_stream_id, error_code);
         }
 
         nghttp2_outbound_item_free(item, mem);
         nghttp2_mem_free(mem, item);
         active_outbound_item_reset(aob, mem);
 
+        if (nghttp2_is_fatal(rv2)) {
+          return rv2;
+        }
+
         if (rv == NGHTTP2_ERR_HEADER_COMP) {
-          /* If header compression error occurred, should terminiate
+          /* If header compression error occurred, should terminate
              connection. */
-          rv = nghttp2_session_terminate_session(session,
-                                                 NGHTTP2_INTERNAL_ERROR);
+          rv =
+            nghttp2_session_terminate_session(session, NGHTTP2_INTERNAL_ERROR);
         }
         if (nghttp2_is_fatal(rv)) {
           return rv;
@@ -3392,7 +2933,7 @@
 
           if (session->callbacks.on_frame_not_send_callback) {
             if (session->callbacks.on_frame_not_send_callback(
-                    session, frame, rv, session->user_data) != 0) {
+                  session, frame, rv, session->user_data) != 0) {
               return NGHTTP2_ERR_CALLBACK_FAILURE;
             }
           }
@@ -3439,7 +2980,7 @@
         }
       }
 
-      DEBUGF("send: start transmitting frame type=%u, length=%zd\n",
+      DEBUGF("send: start transmitting frame type=%u, length=%td\n",
              framebufs->cur->buf.pos[3],
              framebufs->cur->buf.last - framebufs->cur->buf.pos);
 
@@ -3458,7 +2999,7 @@
 
         /* Frame has completely sent */
         if (fast_cb) {
-          rv = session_after_frame_sent2(session);
+          session_after_frame_sent2(session);
         } else {
           rv = session_after_frame_sent1(session);
           if (rv < 0) {
@@ -3466,12 +3007,7 @@
             assert(nghttp2_is_fatal(rv));
             return rv;
           }
-          rv = session_after_frame_sent2(session);
-        }
-        if (rv < 0) {
-          /* FATAL */
-          assert(nghttp2_is_fatal(rv));
-          return rv;
+          session_after_frame_sent2(session);
         }
         /* We have already adjusted the next state */
         break;
@@ -3484,7 +3020,7 @@
          everything, we will adjust it. */
       buf->pos += datalen;
 
-      return (ssize_t)datalen;
+      return (nghttp2_ssize)datalen;
     }
     case NGHTTP2_OB_SEND_NO_COPY: {
       nghttp2_stream *stream;
@@ -3510,11 +3046,7 @@
       }
 
       if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
-        rv = session_detach_stream_item(session, stream);
-
-        if (nghttp2_is_fatal(rv)) {
-          return rv;
-        }
+        session_detach_stream_item(session, stream);
 
         rv = nghttp2_session_add_rst_stream(session, frame->hd.stream_id,
                                             NGHTTP2_INTERNAL_ERROR);
@@ -3538,11 +3070,7 @@
         assert(nghttp2_is_fatal(rv));
         return rv;
       }
-      rv = session_after_frame_sent2(session);
-      if (rv < 0) {
-        assert(nghttp2_is_fatal(rv));
-        return rv;
-      }
+      session_after_frame_sent2(session);
 
       /* We have already adjusted the next state */
 
@@ -3569,7 +3097,7 @@
 
       buf->pos += datalen;
 
-      return (ssize_t)datalen;
+      return (nghttp2_ssize)datalen;
     }
     }
   }
@@ -3577,8 +3105,13 @@
 
 ssize_t nghttp2_session_mem_send(nghttp2_session *session,
                                  const uint8_t **data_ptr) {
+  return (ssize_t)nghttp2_session_mem_send2(session, data_ptr);
+}
+
+nghttp2_ssize nghttp2_session_mem_send2(nghttp2_session *session,
+                                        const uint8_t **data_ptr) {
   int rv;
-  ssize_t len;
+  nghttp2_ssize len;
 
   *data_ptr = NULL;
 
@@ -3595,7 +3128,7 @@
     rv = session_after_frame_sent1(session);
     if (rv < 0) {
       assert(nghttp2_is_fatal(rv));
-      return (ssize_t)rv;
+      return (nghttp2_ssize)rv;
     }
   }
 
@@ -3604,8 +3137,8 @@
 
 int nghttp2_session_send(nghttp2_session *session) {
   const uint8_t *data = NULL;
-  ssize_t datalen;
-  ssize_t sentlen;
+  nghttp2_ssize datalen;
+  nghttp2_ssize sentlen;
   nghttp2_bufs *framebufs;
 
   framebufs = &session->aob.framebufs;
@@ -3615,8 +3148,13 @@
     if (datalen <= 0) {
       return (int)datalen;
     }
-    sentlen = session->callbacks.send_callback(session, data, (size_t)datalen,
-                                               0, session->user_data);
+    if (session->callbacks.send_callback2) {
+      sentlen = session->callbacks.send_callback2(
+        session, data, (size_t)datalen, 0, session->user_data);
+    } else {
+      sentlen = (nghttp2_ssize)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 */
@@ -3631,11 +3169,17 @@
   }
 }
 
-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);
+static nghttp2_ssize session_recv(nghttp2_session *session, uint8_t *buf,
+                                  size_t len) {
+  nghttp2_ssize rv;
+
+  if (session->callbacks.recv_callback2) {
+    rv = session->callbacks.recv_callback2(session, buf, len, 0,
+                                           session->user_data);
+  } else {
+    rv = (nghttp2_ssize)session->callbacks.recv_callback(session, buf, len, 0,
+                                                         session->user_data);
+  }
   if (rv > 0) {
     if ((size_t)rv > len) {
       return NGHTTP2_ERR_CALLBACK_FAILURE;
@@ -3651,7 +3195,6 @@
   int rv;
 
   if (session->callbacks.on_begin_frame_callback) {
-
     rv = session->callbacks.on_begin_frame_callback(session, hd,
                                                     session->user_data);
 
@@ -3700,11 +3243,11 @@
   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);
+      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);
+      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) {
@@ -3723,13 +3266,15 @@
   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);
+      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);
+      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 both callbacks are not set, the invalid field nv is
+       ignored. */
+    return 0;
   }
 
   if (rv == NGHTTP2_ERR_PAUSE || rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
@@ -3751,7 +3296,7 @@
 
   if (session->callbacks.on_extension_chunk_recv_callback) {
     rv = session->callbacks.on_extension_chunk_recv_callback(
-        session, &frame->hd, data, len, session->user_data);
+      session, &frame->hd, data, len, session->user_data);
     if (rv == NGHTTP2_ERR_CANCEL) {
       return rv;
     }
@@ -3770,7 +3315,7 @@
   void *payload = NULL;
 
   rv = session->callbacks.unpack_extension_callback(
-      session, &payload, &frame->hd, session->user_data);
+    session, &payload, &frame->hd, session->user_data);
   if (rv == NGHTTP2_ERR_CANCEL) {
     return rv;
   }
@@ -3814,6 +3359,10 @@
   case NGHTTP2_ERR_HTTP_HEADER:
   case NGHTTP2_ERR_HTTP_MESSAGING:
     return NGHTTP2_PROTOCOL_ERROR;
+  case NGHTTP2_ERR_INTERNAL:
+    return NGHTTP2_INTERNAL_ERROR;
+  case NGHTTP2_ERR_PUSH_CANCEL:
+    return NGHTTP2_CANCEL;
   default:
     return NGHTTP2_INTERNAL_ERROR;
   }
@@ -3833,26 +3382,41 @@
                                                        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) {
+          session, frame, lib_error_code, session->user_data) != 0) {
       return NGHTTP2_ERR_CALLBACK_FAILURE;
     }
   }
   return 0;
 }
 
+static int session_update_glitch_ratelim(nghttp2_session *session) {
+  if (session->goaway_flags & NGHTTP2_GOAWAY_TERM_ON_SEND) {
+    return 0;
+  }
+
+  nghttp2_ratelim_update(&session->glitch_ratelim, nghttp2_time_now_sec());
+
+  if (nghttp2_ratelim_drain(&session->glitch_ratelim, 1) == 0) {
+    return 0;
+  }
+
+  return nghttp2_session_terminate_session(session, NGHTTP2_ENHANCE_YOUR_CALM);
+}
+
 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));
+    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 (frame && session->callbacks.on_invalid_frame_recv_callback) {
     if (session->callbacks.on_invalid_frame_recv_callback(
-            session, frame, lib_error_code, session->user_data) != 0) {
+          session, frame, lib_error_code, session->user_data) != 0) {
       return NGHTTP2_ERR_CALLBACK_FAILURE;
     }
   }
@@ -3886,12 +3450,12 @@
                                              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) {
+          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);
+    session, get_error_code_from_lib_error_code(lib_error_code), reason);
 }
 
 static int session_inflate_handle_invalid_connection(nghttp2_session *session,
@@ -3900,7 +3464,7 @@
                                                      const char *reason) {
   int rv;
   rv =
-      session_handle_invalid_connection(session, frame, lib_error_code, reason);
+    session_handle_invalid_connection(session, frame, lib_error_code, reason);
   if (nghttp2_is_fatal(rv)) {
     return rv;
   }
@@ -3937,7 +3501,7 @@
 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;
+  nghttp2_ssize proclen;
   int rv;
   int inflate_flags;
   nghttp2_hd_nv nv;
@@ -3950,7 +3514,7 @@
 
   if (frame->hd.type == NGHTTP2_PUSH_PROMISE) {
     subject_stream = nghttp2_session_get_stream(
-        session, frame->push_promise.promised_stream_id);
+      session, frame->push_promise.promised_stream_id);
   } else {
     subject_stream = stream;
     trailer = session_trailer_headers(session, stream, frame);
@@ -3971,7 +3535,7 @@
              from invoking subsequent callbacks for the same stream
              ID. */
           rv = nghttp2_session_add_rst_stream(
-              session, subject_stream->stream_id, NGHTTP2_COMPRESSION_ERROR);
+            session, subject_stream->stream_id, NGHTTP2_COMPRESSION_ERROR);
 
           if (nghttp2_is_fatal(rv)) {
             return rv;
@@ -3979,7 +3543,7 @@
         }
       }
       rv =
-          nghttp2_session_terminate_session(session, NGHTTP2_COMPRESSION_ERROR);
+        nghttp2_session_terminate_session(session, NGHTTP2_COMPRESSION_ERROR);
       if (nghttp2_is_fatal(rv)) {
         return rv;
       }
@@ -3990,7 +3554,7 @@
     inlen -= (size_t)proclen;
     *readlen_ptr += (size_t)proclen;
 
-    DEBUGF("recv: proclen=%zd\n", proclen);
+    DEBUGF("recv: proclen=%td\n", proclen);
 
     if (call_header_cb && (inflate_flags & NGHTTP2_HD_INFLATE_EMIT)) {
       rv = 0;
@@ -4005,7 +3569,29 @@
 
             rv2 = session_call_on_invalid_header(session, frame, &nv);
             if (rv2 == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
-              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;
             } else {
               if (rv2 != 0) {
                 return rv2;
@@ -4017,11 +3603,11 @@
                      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);
+                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;
@@ -4035,23 +3621,18 @@
                    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);
+              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;
+            return nghttp2_session_terminate_session(session,
+                                                     NGHTTP2_PROTOCOL_ERROR);
           }
         }
         if (rv == 0) {
@@ -4095,7 +3676,6 @@
 
   if (session->server && session_enforce_http_messaging(session) &&
       frame->headers.cat == NGHTTP2_HCAT_REQUEST &&
-      (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) &&
       !(stream->flags & NGHTTP2_STREAM_FLAG_IGNORE_CLIENT_PRIORITIES) &&
       (stream->http_flags & NGHTTP2_HTTP_FLAG_PRIORITY)) {
     rv = session_update_stream_priority(session, stream, stream->http_extpri);
@@ -4135,7 +3715,7 @@
       nghttp2_stream *subject_stream;
 
       subject_stream = nghttp2_session_get_stream(
-          session, frame->push_promise.promised_stream_id);
+        session, frame->push_promise.promised_stream_id);
       if (subject_stream) {
         rv = nghttp2_http_on_request_headers(subject_stream, frame);
       }
@@ -4165,27 +3745,7 @@
       }
     }
     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;
+      return nghttp2_session_terminate_session(session, NGHTTP2_PROTOCOL_ERROR);
     }
   }
 
@@ -4207,7 +3767,7 @@
   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");
+      session, frame, NGHTTP2_ERR_PROTO, "request HEADERS: stream_id == 0");
   }
 
   /* If client receives idle stream from server, it is invalid
@@ -4216,8 +3776,8 @@
   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");
+        session, frame, NGHTTP2_ERR_PROTO,
+        "request HEADERS: client received request");
     }
 
     return NGHTTP2_ERR_IGN_HEADER_BLOCK;
@@ -4229,8 +3789,8 @@
     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");
+        session, frame, NGHTTP2_ERR_PROTO,
+        "request HEADERS: invalid stream_id");
     }
 
     /* RFC 7540 says if an endpoint receives a HEADERS with invalid
@@ -4256,7 +3816,7 @@
     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");
+        session, frame, NGHTTP2_ERR_STREAM_CLOSED, "HEADERS: stream closed");
     }
 
     return NGHTTP2_ERR_IGN_HEADER_BLOCK;
@@ -4265,8 +3825,8 @@
 
   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");
+      session, frame, NGHTTP2_ERR_PROTO,
+      "request HEADERS: max concurrent streams exceeded");
   }
 
   if (!session_allow_incoming_new_stream(session)) {
@@ -4276,7 +3836,7 @@
 
   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");
+      session, frame, NGHTTP2_ERR_PROTO, "request HEADERS: depend on itself");
   }
 
   if (session_is_incoming_concurrent_streams_pending_max(session)) {
@@ -4284,18 +3844,13 @@
                                                  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);
+  stream = nghttp2_session_open_stream(session, frame->hd.stream_id,
+                                       NGHTTP2_STREAM_FLAG_NONE,
+                                       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);
@@ -4315,7 +3870,7 @@
          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");
+      session, frame, NGHTTP2_ERR_PROTO, "response HEADERS: stream_id == 0");
   }
   if (stream->shut_flags & NGHTTP2_SHUT_RD) {
     /* half closed (remote): from the spec:
@@ -4327,7 +3882,7 @@
        We go further, and make it connection error.
     */
     return session_inflate_handle_invalid_connection(
-        session, frame, NGHTTP2_ERR_STREAM_CLOSED, "HEADERS: stream closed");
+      session, frame, NGHTTP2_ERR_STREAM_CLOSED, "HEADERS: stream closed");
   }
   stream->state = NGHTTP2_STREAM_OPENED;
   rv = session_call_on_begin_headers(session, frame);
@@ -4344,20 +3899,20 @@
   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");
+      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");
+      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");
+      session, frame, NGHTTP2_ERR_PROTO,
+      "push response HEADERS: max concurrent streams exceeded");
   }
 
   if (!session_allow_incoming_new_stream(session)) {
@@ -4388,7 +3943,7 @@
   int rv = 0;
   if (frame->hd.stream_id == 0) {
     return session_inflate_handle_invalid_connection(
-        session, frame, NGHTTP2_ERR_PROTO, "HEADERS: stream_id == 0");
+      session, frame, NGHTTP2_ERR_PROTO, "HEADERS: stream_id == 0");
   }
   if ((stream->shut_flags & NGHTTP2_SHUT_RD)) {
     /* half closed (remote): from the spec:
@@ -4400,7 +3955,7 @@
        we go further, and make it connection error.
     */
     return session_inflate_handle_invalid_connection(
-        session, frame, NGHTTP2_ERR_STREAM_CLOSED, "HEADERS: stream closed");
+      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) {
@@ -4428,17 +3983,12 @@
 }
 
 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);
+  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;
@@ -4461,75 +4011,21 @@
   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;
-
-  assert(!session_no_rfc7540_pri_no_fallback(session));
-
-  if (frame->hd.stream_id == 0) {
-    return session_handle_invalid_connection(session, frame, NGHTTP2_ERR_PROTO,
-                                             "PRIORITY: stream_id == 0");
+static int session_update_stream_reset_ratelim(nghttp2_session *session) {
+  if (!session->server || (session->goaway_flags & NGHTTP2_GOAWAY_SUBMITTED)) {
+    return 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");
+  nghttp2_ratelim_update(&session->stream_reset_ratelim,
+                         nghttp2_time_now_sec());
+
+  if (nghttp2_ratelim_drain(&session->stream_reset_ratelim, 1) == 0) {
+    return 0;
   }
 
-  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;
-
-  assert(!session_no_rfc7540_pri_no_fallback(session));
-
-  nghttp2_frame_unpack_priority_payload(&frame->priority, iframe->sbuf.pos);
-
-  return nghttp2_session_on_priority_received(session, frame);
+  return nghttp2_session_add_goaway(session, session->last_recv_stream_id,
+                                    NGHTTP2_INTERNAL_ERROR, NULL, 0,
+                                    NGHTTP2_GOAWAY_AUX_NONE);
 }
 
 int nghttp2_session_on_rst_stream_received(nghttp2_session *session,
@@ -4561,7 +4057,8 @@
   if (nghttp2_is_fatal(rv)) {
     return rv;
   }
-  return 0;
+
+  return session_update_stream_reset_ratelim(session);
 }
 
 static int session_process_rst_stream_frame(nghttp2_session *session) {
@@ -4582,19 +4079,17 @@
   stream = (nghttp2_stream *)entry;
 
   rv = nghttp2_stream_update_remote_initial_window_size(
-      stream, arg->new_window_size, arg->old_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);
+    return NGHTTP2_ERR_FLOW_CONTROL;
   }
 
   /* 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 = session_resume_deferred_stream_item(
-        arg->session, stream, NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL);
+      arg->session, stream, NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL);
 
     if (nghttp2_is_fatal(rv)) {
       return rv;
@@ -4612,6 +4107,8 @@
  *
  * NGHTTP2_ERR_NOMEM
  *     Out of memory.
+ * NGHTTP2_ERR_FLOW_CONTROL
+ *     Window size gets out of range.
  */
 static int
 session_update_remote_initial_window_size(nghttp2_session *session,
@@ -4633,10 +4130,9 @@
   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);
+    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);
+    return NGHTTP2_ERR_FLOW_CONTROL;
   }
 
   if (stream->window_update_queued) {
@@ -4649,7 +4145,6 @@
 
   if (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);
@@ -4671,6 +4166,8 @@
  *
  * NGHTTP2_ERR_NOMEM
  *     Out of memory.
+ * NGHTTP2_ERR_FLOW_CONTROL
+ *     Window size gets out of range.
  */
 static int
 session_update_local_initial_window_size(nghttp2_session *session,
@@ -4714,7 +4211,8 @@
     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);
+      min_header_table_size =
+        nghttp2_min_uint32(min_header_table_size, iv[i].value);
       break;
     case NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE:
       new_initial_window_size = (int32_t)iv[i].value;
@@ -4738,8 +4236,8 @@
   }
   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);
+      session, new_initial_window_size,
+      (int32_t)session->local_settings.initial_window_size);
     if (rv != 0) {
       return rv;
     }
@@ -4793,15 +4291,15 @@
   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");
+        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");
+        session, frame, NGHTTP2_ERR_PROTO, "SETTINGS: unexpected ACK");
     }
 
     rv = nghttp2_session_update_local_settings(session, settings->iv,
@@ -4822,7 +4320,7 @@
 
   if (!session->remote_settings_received) {
     session->remote_settings.max_concurrent_streams =
-        NGHTTP2_DEFAULT_MAX_CONCURRENT_STREAMS;
+      NGHTTP2_DEFAULT_MAX_CONCURRENT_STREAMS;
     session->remote_settings_received = 1;
   }
 
@@ -4839,7 +4337,7 @@
           return rv;
         } else {
           return session_handle_invalid_connection(
-              session, frame, NGHTTP2_ERR_HEADER_COMP, NULL);
+            session, frame, NGHTTP2_ERR_HEADER_COMP, NULL);
         }
       }
 
@@ -4850,14 +4348,14 @@
 
       if (entry->value != 0 && entry->value != 1) {
         return session_handle_invalid_connection(
-            session, frame, NGHTTP2_ERR_PROTO,
-            "SETTINGS: invalid SETTINGS_ENBLE_PUSH");
+          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, frame, NGHTTP2_ERR_PROTO,
+          "SETTINGS: server attempted to enable push");
       }
 
       session->remote_settings.enable_push = entry->value;
@@ -4874,8 +4372,8 @@
       /* 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");
+          session, frame, NGHTTP2_ERR_FLOW_CONTROL,
+          "SETTINGS: too large SETTINGS_INITIAL_WINDOW_SIZE");
       }
 
       rv = session_update_remote_initial_window_size(session,
@@ -4887,7 +4385,7 @@
 
       if (rv != 0) {
         return session_handle_invalid_connection(
-            session, frame, NGHTTP2_ERR_FLOW_CONTROL, NULL);
+          session, frame, NGHTTP2_ERR_FLOW_CONTROL, NULL);
       }
 
       session->remote_settings.initial_window_size = entry->value;
@@ -4898,8 +4396,8 @@
       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, frame, NGHTTP2_ERR_PROTO,
+          "SETTINGS: invalid SETTINGS_MAX_FRAME_SIZE");
       }
 
       session->remote_settings.max_frame_size = entry->value;
@@ -4914,17 +4412,17 @@
 
       if (entry->value != 0 && entry->value != 1) {
         return session_handle_invalid_connection(
-            session, frame, NGHTTP2_ERR_PROTO,
-            "SETTINGS: invalid SETTINGS_ENABLE_CONNECT_PROTOCOL");
+          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, frame, NGHTTP2_ERR_PROTO,
+          "SETTINGS: server attempted to disable "
+          "SETTINGS_ENABLE_CONNECT_PROTOCOL");
       }
 
       session->remote_settings.enable_connect_protocol = entry->value;
@@ -4934,15 +4432,15 @@
 
       if (entry->value != 0 && entry->value != 1) {
         return session_handle_invalid_connection(
-            session, frame, NGHTTP2_ERR_PROTO,
-            "SETTINGS: invalid SETTINGS_NO_RFC7540_PRIORITIES");
+          session, frame, NGHTTP2_ERR_PROTO,
+          "SETTINGS: invalid SETTINGS_NO_RFC7540_PRIORITIES");
       }
 
       if (session->remote_settings.no_rfc7540_priorities != UINT32_MAX &&
           session->remote_settings.no_rfc7540_priorities != entry->value) {
         return session_handle_invalid_connection(
-            session, frame, NGHTTP2_ERR_PROTO,
-            "SETTINGS: SETTINGS_NO_RFC7540_PRIORITIES cannot be changed");
+          session, frame, NGHTTP2_ERR_PROTO,
+          "SETTINGS: SETTINGS_NO_RFC7540_PRIORITIES cannot be changed");
       }
 
       session->remote_settings.no_rfc7540_priorities = entry->value;
@@ -4953,12 +4451,6 @@
 
   if (session->remote_settings.no_rfc7540_priorities == UINT32_MAX) {
     session->remote_settings.no_rfc7540_priorities = 0;
-
-    if (session->server && session->pending_no_rfc7540_priorities &&
-        (session->opt_flags &
-         NGHTTP2_OPTMASK_SERVER_FALLBACK_RFC7540_PRIORITIES)) {
-      session->fallback_rfc7540_priorities = 1;
-    }
   }
 
   if (!noack && !session_is_closing(session)) {
@@ -5019,20 +4511,19 @@
   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");
+      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");
+      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");
+      session, frame, NGHTTP2_ERR_PROTO, "PUSH_PROMISE: invalid stream_id");
   }
 
   if (!session_allow_incoming_new_stream(session)) {
@@ -5046,13 +4537,13 @@
        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");
+      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, frame, NGHTTP2_ERR_PROTO, "PUSH_PROMISE: stream in idle");
   }
 
   session->last_recv_stream_id = frame->push_promise.promised_stream_id;
@@ -5060,12 +4551,12 @@
   if (!stream || stream->state == NGHTTP2_STREAM_CLOSING ||
       !session->pending_enable_push ||
       session->num_incoming_reserved_streams >=
-          session->max_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);
+    rv = session_handle_invalid_stream2(session,
+                                        frame->push_promise.promised_stream_id,
+                                        NULL, NGHTTP2_ERR_PUSH_CANCEL);
     if (rv != 0) {
       return rv;
     }
@@ -5074,24 +4565,17 @@
 
   if (stream->shut_flags & NGHTTP2_SHUT_RD) {
     return session_inflate_handle_invalid_connection(
-        session, frame, NGHTTP2_ERR_STREAM_CLOSED,
-        "PUSH_PROMISE: stream closed");
+      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);
+    session, frame->push_promise.promised_stream_id, NGHTTP2_STREAM_FLAG_NONE,
+    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) {
@@ -5101,17 +4585,11 @@
 }
 
 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");
-  }
+  nghttp2_frame_unpack_push_promise_payload(&frame->push_promise,
+                                            iframe->sbuf.pos);
 
   return nghttp2_session_on_push_promise_received(session, frame);
 }
@@ -5196,8 +4674,8 @@
   /* 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");
+      session, frame, NGHTTP2_ERR_PROTO,
+      "WINDOW_UPDATE: window_size_increment == 0");
   }
 
   if (NGHTTP2_MAX_WINDOW_SIZE - frame->window_update.window_size_increment <
@@ -5226,25 +4704,25 @@
   }
   if (state_reserved_remote(session, stream)) {
     return session_handle_invalid_connection(
-        session, frame, NGHTTP2_ERR_PROTO, "WINDOW_UPADATE to reserved stream");
+      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");
+      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);
+    return session_handle_invalid_connection(
+      session, frame, NGHTTP2_ERR_FLOW_CONTROL,
+      "WINDOW_UPDATE: window size overflow");
   }
   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 = session_resume_deferred_stream_item(
-        session, stream, NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL);
+      session, stream, NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL);
 
     if (nghttp2_is_fatal(rv)) {
       return rv;
@@ -5319,7 +4797,6 @@
                                                 nghttp2_frame *frame) {
   nghttp2_ext_priority_update *priority_update;
   nghttp2_stream *stream;
-  nghttp2_priority_spec pri_spec;
   nghttp2_extpri extpri;
   int rv;
 
@@ -5335,8 +4812,8 @@
   if (nghttp2_session_is_my_stream_id(session, priority_update->stream_id)) {
     if (session_detect_idle_stream(session, priority_update->stream_id)) {
       return session_handle_invalid_connection(
-          session, frame, NGHTTP2_ERR_PROTO,
-          "PRIORITY_UPDATE: prioritizing idle push is not allowed");
+        session, frame, NGHTTP2_ERR_PROTO,
+        "PRIORITY_UPDATE: prioritizing idle push is not allowed");
     }
 
     /* TODO Ignore priority signal to a push stream for now */
@@ -5353,14 +4830,13 @@
     if (session->num_idle_streams + session->num_incoming_streams >=
         session->local_settings.max_concurrent_streams) {
       return session_handle_invalid_connection(
-          session, frame, NGHTTP2_ERR_PROTO,
-          "PRIORITY_UPDATE: max concurrent streams exceeded");
+        session, frame, NGHTTP2_ERR_PROTO,
+        "PRIORITY_UPDATE: max concurrent streams exceeded");
     }
 
-    nghttp2_priority_spec_default_init(&pri_spec);
-    stream = nghttp2_session_open_stream(session, priority_update->stream_id,
-                                         NGHTTP2_FLAG_NONE, &pri_spec,
-                                         NGHTTP2_STREAM_IDLE, NULL);
+    stream =
+      nghttp2_session_open_stream(session, priority_update->stream_id,
+                                  NGHTTP2_FLAG_NONE, NGHTTP2_STREAM_IDLE, NULL);
     if (!stream) {
       return NGHTTP2_ERR_NOMEM;
     }
@@ -5394,8 +4870,8 @@
   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));
+    &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 */
@@ -5469,16 +4945,7 @@
   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;
+      return nghttp2_session_terminate_session(session, NGHTTP2_PROTOCOL_ERROR);
     }
   }
 
@@ -5536,8 +5003,8 @@
   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);
+    return nghttp2_session_terminate_session(session,
+                                             NGHTTP2_FLOW_CONTROL_ERROR);
   }
   /* We don't have to send WINDOW_UPDATE if the data received is the
      last chunk in the incoming stream. */
@@ -5548,9 +5015,8 @@
       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);
+    rv = nghttp2_session_add_window_update(
+      session, NGHTTP2_FLAG_NONE, stream->stream_id, stream->recv_window_size);
     if (rv != 0) {
       return rv;
     }
@@ -5606,7 +5072,7 @@
     /* 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);
+    recv_size = nghttp2_min_int32(*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,
@@ -5628,16 +5094,16 @@
                                                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);
+    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);
+    session, &session->consumed_size, &session->recv_window_size,
+    session->window_update_queued, 0, delta_size, session->local_window_size);
 }
 
 /*
@@ -5729,7 +5195,7 @@
 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);
+  return nghttp2_min_size((size_t)(last - in), iframe->payloadleft);
 }
 
 /*
@@ -5744,8 +5210,8 @@
                                      const uint8_t *in, const uint8_t *last) {
   size_t readlen;
 
-  readlen =
-      nghttp2_min((size_t)(last - in), nghttp2_buf_mark_avail(&iframe->sbuf));
+  readlen = nghttp2_min_size((size_t)(last - in),
+                             nghttp2_buf_mark_avail(&iframe->sbuf));
 
   iframe->sbuf.last = nghttp2_cpymem(iframe->sbuf.last, in, readlen);
 
@@ -5823,7 +5289,7 @@
  * 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) {
+static nghttp2_ssize inbound_frame_compute_pad(nghttp2_inbound_frame *iframe) {
   size_t padlen;
 
   /* 1 for Pad Length field */
@@ -5838,7 +5304,7 @@
 
   iframe->padlen = padlen;
 
-  return (ssize_t)padlen;
+  return (nghttp2_ssize)padlen;
 }
 
 /*
@@ -5847,11 +5313,11 @@
  * |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) {
+static nghttp2_ssize
+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);
+    nghttp2_frame_trail_padlen(&iframe->frame, iframe->padlen);
 
   if (trail_padlen > payloadleft) {
     size_t padlen;
@@ -5859,19 +5325,24 @@
     if (readlen < padlen) {
       return -1;
     }
-    return (ssize_t)(readlen - padlen);
+    return (nghttp2_ssize)(readlen - padlen);
   }
-  return (ssize_t)(readlen);
+  return (nghttp2_ssize)(readlen);
 }
 
 static const uint8_t static_in[] = {0};
 
 ssize_t nghttp2_session_mem_recv(nghttp2_session *session, const uint8_t *in,
                                  size_t inlen) {
+  return (ssize_t)nghttp2_session_mem_recv2(session, in, inlen);
+}
+
+nghttp2_ssize nghttp2_session_mem_recv2(nghttp2_session *session,
+                                        const uint8_t *in, size_t inlen) {
   const uint8_t *first, *last;
   nghttp2_inbound_frame *iframe = &session->iframe;
   size_t readlen;
-  ssize_t padlen;
+  nghttp2_ssize padlen;
   int rv;
   int busy = 0;
   nghttp2_frame_hd cont_hd;
@@ -5892,22 +5363,14 @@
 
   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;
+    return (nghttp2_ssize)inlen;
   }
 
   for (;;) {
     switch (iframe->state) {
     case NGHTTP2_IB_READ_CLIENT_MAGIC:
-      readlen = nghttp2_min(inlen, iframe->payloadleft);
+      readlen = nghttp2_min_size(inlen, iframe->payloadleft);
 
       if (memcmp(&NGHTTP2_CLIENT_MAGIC[NGHTTP2_CLIENT_MAGIC_LEN -
                                        iframe->payloadleft],
@@ -5931,29 +5394,29 @@
       in += readlen;
 
       if (nghttp2_buf_mark_avail(&iframe->sbuf)) {
-        return in - first;
+        return (nghttp2_ssize)(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.");
+          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");
+          session, NGHTTP2_PROTOCOL_ERROR, "SETTINGS expected");
 
         if (nghttp2_is_fatal(rv)) {
           return rv;
         }
 
-        return (ssize_t)inlen;
+        return (nghttp2_ssize)inlen;
       }
 
       iframe->state = NGHTTP2_IB_READ_HEAD;
@@ -5968,7 +5431,7 @@
       in += readlen;
 
       if (nghttp2_buf_mark_avail(&iframe->sbuf)) {
-        return in - first;
+        return (nghttp2_ssize)(in - first);
       }
 
       nghttp2_frame_unpack_frame_hd(&iframe->frame.hd, iframe->sbuf.pos);
@@ -5983,13 +5446,13 @@
                session->local_settings.max_frame_size);
 
         rv = nghttp2_session_terminate_session_with_reason(
-            session, NGHTTP2_FRAME_SIZE_ERROR, "too large frame size");
+          session, NGHTTP2_FRAME_SIZE_ERROR, "too large frame size");
 
         if (nghttp2_is_fatal(rv)) {
           return rv;
         }
 
-        return (ssize_t)inlen;
+        return (nghttp2_ssize)inlen;
       }
 
       switch (iframe->frame.hd.type) {
@@ -5997,18 +5460,28 @@
         DEBUGF("recv: DATA\n");
 
         iframe->frame.hd.flags &=
-            (NGHTTP2_FLAG_END_STREAM | NGHTTP2_FLAG_PADDED);
+          (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;
+          return (nghttp2_ssize)inlen;
         }
         if (rv == NGHTTP2_ERR_IGN_PAYLOAD) {
           DEBUGF("recv: DATA not allowed stream_id=%d\n",
                  iframe->frame.hd.stream_id);
+
+          rv = session_update_glitch_ratelim(session);
+          if (rv != 0) {
+            return rv;
+          }
+
+          if (iframe->state == NGHTTP2_IB_IGN_ALL) {
+            return (nghttp2_ssize)inlen;
+          }
+
           iframe->state = NGHTTP2_IB_IGN_DATA;
           break;
         }
@@ -6020,13 +5493,13 @@
         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");
+            session, NGHTTP2_PROTOCOL_ERROR,
+            "DATA: insufficient padding space");
 
           if (nghttp2_is_fatal(rv)) {
             return rv;
           }
-          return (ssize_t)inlen;
+          return (nghttp2_ssize)inlen;
         }
 
         if (rv == 1) {
@@ -6034,6 +5507,20 @@
           break;
         }
 
+        /* Empty DATA frame without END_STREAM flag set is
+           suspicious. */
+        if (iframe->payloadleft == 0 &&
+            (iframe->frame.hd.flags & NGHTTP2_FLAG_END_STREAM) == 0) {
+          rv = session_update_glitch_ratelim(session);
+          if (rv != 0) {
+            return rv;
+          }
+
+          if (iframe->state == NGHTTP2_IB_IGN_ALL) {
+            return (nghttp2_ssize)inlen;
+          }
+        }
+
         iframe->state = NGHTTP2_IB_READ_DATA;
         break;
       }
@@ -6042,18 +5529,18 @@
         DEBUGF("recv: HEADERS\n");
 
         iframe->frame.hd.flags &=
-            (NGHTTP2_FLAG_END_STREAM | NGHTTP2_FLAG_END_HEADERS |
-             NGHTTP2_FLAG_PADDED | NGHTTP2_FLAG_PRIORITY);
+          (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");
+            session, NGHTTP2_PROTOCOL_ERROR,
+            "HEADERS: insufficient padding space");
           if (nghttp2_is_fatal(rv)) {
             return rv;
           }
-          return (ssize_t)inlen;
+          return (nghttp2_ssize)inlen;
         }
 
         if (rv == 1) {
@@ -6096,12 +5583,12 @@
         busy = 1;
 
         if (iframe->state == NGHTTP2_IB_IGN_ALL) {
-          return (ssize_t)inlen;
+          return (nghttp2_ssize)inlen;
         }
 
         if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
-          rv = nghttp2_session_add_rst_stream(
-              session, iframe->frame.hd.stream_id, NGHTTP2_INTERNAL_ERROR);
+          rv = session_handle_invalid_stream2(
+            session, iframe->frame.hd.stream_id, NULL, NGHTTP2_ERR_INTERNAL);
           if (nghttp2_is_fatal(rv)) {
             return rv;
           }
@@ -6110,6 +5597,15 @@
         }
 
         if (rv == NGHTTP2_ERR_IGN_HEADER_BLOCK) {
+          rv = session_update_glitch_ratelim(session);
+          if (rv != 0) {
+            return rv;
+          }
+
+          if (iframe->state == NGHTTP2_IB_IGN_ALL) {
+            return (nghttp2_ssize)inlen;
+          }
+
           iframe->state = NGHTTP2_IB_IGN_HEADER_BLOCK;
           break;
         }
@@ -6130,6 +5626,18 @@
           break;
         }
 
+        /* This is deprecated RFC 7540 priorities mechanism which is
+           very unpopular.  We do not expect it is received so
+           frequently. */
+        rv = session_update_glitch_ratelim(session);
+        if (rv != 0) {
+          return rv;
+        }
+
+        if (iframe->state == NGHTTP2_IB_IGN_ALL) {
+          return (nghttp2_ssize)inlen;
+        }
+
         iframe->state = NGHTTP2_IB_READ_NBYTE;
 
         inbound_frame_set_mark(iframe, NGHTTP2_PRIORITY_SPECLEN);
@@ -6146,7 +5654,7 @@
           DEBUGF("recv: WINDOW_UPDATE\n");
           break;
         }
-#endif /* DEBUGBUILD */
+#endif /* defined(DEBUGBUILD) */
 
         iframe->frame.hd.flags = NGHTTP2_FLAG_NONE;
 
@@ -6188,20 +5696,20 @@
           /* 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->frame.hd.length / NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH + 1;
 
           if (iframe->max_niv - 1 > session->max_settings) {
             rv = nghttp2_session_terminate_session_with_reason(
-                session, NGHTTP2_ENHANCE_YOUR_CALM,
-                "SETTINGS: too many setting entries");
+              session, NGHTTP2_ENHANCE_YOUR_CALM,
+              "SETTINGS: too many setting entries");
             if (nghttp2_is_fatal(rv)) {
               return rv;
             }
-            return (ssize_t)inlen;
+            return (nghttp2_ssize)inlen;
           }
 
           iframe->iv = nghttp2_mem_malloc(mem, sizeof(nghttp2_settings_entry) *
-                                                   iframe->max_niv);
+                                                 iframe->max_niv);
 
           if (!iframe->iv) {
             return NGHTTP2_ERR_NOMEM;
@@ -6209,7 +5717,7 @@
 
           min_header_table_size_entry = &iframe->iv[iframe->max_niv - 1];
           min_header_table_size_entry->settings_id =
-              NGHTTP2_SETTINGS_HEADER_TABLE_SIZE;
+            NGHTTP2_SETTINGS_HEADER_TABLE_SIZE;
           min_header_table_size_entry->value = UINT32_MAX;
 
           inbound_frame_set_mark(iframe, NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH);
@@ -6225,17 +5733,17 @@
         DEBUGF("recv: PUSH_PROMISE\n");
 
         iframe->frame.hd.flags &=
-            (NGHTTP2_FLAG_END_HEADERS | NGHTTP2_FLAG_PADDED);
+          (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");
+            session, NGHTTP2_PROTOCOL_ERROR,
+            "PUSH_PROMISE: insufficient padding space");
           if (nghttp2_is_fatal(rv)) {
             return rv;
           }
-          return (ssize_t)inlen;
+          return (nghttp2_ssize)inlen;
         }
 
         if (rv == 1) {
@@ -6290,20 +5798,29 @@
         /* 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");
+          session, NGHTTP2_PROTOCOL_ERROR, "CONTINUATION: unexpected");
         if (nghttp2_is_fatal(rv)) {
           return rv;
         }
 
-        return (ssize_t)inlen;
+        return (nghttp2_ssize)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. */
+            /* Receiving too frequent unknown frames is suspicious. */
+            rv = session_update_glitch_ratelim(session);
+            if (rv != 0) {
+              return rv;
+            }
 
+            if (iframe->state == NGHTTP2_IB_IGN_ALL) {
+              return (nghttp2_ssize)inlen;
+            }
+
+            /* Silently ignore unknown frame type. */
             busy = 1;
 
             iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
@@ -6321,6 +5838,16 @@
           case NGHTTP2_ALTSVC:
             if ((session->builtin_recv_ext_types & NGHTTP2_TYPEMASK_ALTSVC) ==
                 0) {
+              /* Receiving too frequent unknown frames is suspicious. */
+              rv = session_update_glitch_ratelim(session);
+              if (rv != 0) {
+                return rv;
+              }
+
+              if (iframe->state == NGHTTP2_IB_IGN_ALL) {
+                return (nghttp2_ssize)inlen;
+              }
+
               busy = 1;
               iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
               break;
@@ -6332,6 +5859,17 @@
             iframe->frame.ext.payload = &iframe->ext_frame_payload.altsvc;
 
             if (session->server) {
+              /* Receiving too frequent ALTSVC from client is
+                 suspicious. */
+              rv = session_update_glitch_ratelim(session);
+              if (rv != 0) {
+                return rv;
+              }
+
+              if (iframe->state == NGHTTP2_IB_IGN_ALL) {
+                return (nghttp2_ssize)inlen;
+              }
+
               busy = 1;
               iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
               break;
@@ -6351,6 +5889,16 @@
             break;
           case NGHTTP2_ORIGIN:
             if (!(session->builtin_recv_ext_types & NGHTTP2_TYPEMASK_ORIGIN)) {
+              /* Receiving too frequent unknown frames is suspicious. */
+              rv = session_update_glitch_ratelim(session);
+              if (rv != 0) {
+                return rv;
+              }
+
+              if (iframe->state == NGHTTP2_IB_IGN_ALL) {
+                return (nghttp2_ssize)inlen;
+              }
+
               busy = 1;
               iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
               break;
@@ -6362,6 +5910,17 @@
 
             if (session->server || iframe->frame.hd.stream_id ||
                 (iframe->frame.hd.flags & 0xf0)) {
+              /* Receiving too frequent invalid frames is
+                 suspicious. */
+              rv = session_update_glitch_ratelim(session);
+              if (rv != 0) {
+                return rv;
+              }
+
+              if (iframe->state == NGHTTP2_IB_IGN_ALL) {
+                return (nghttp2_ssize)inlen;
+              }
+
               busy = 1;
               iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
               break;
@@ -6388,6 +5947,16 @@
           case NGHTTP2_PRIORITY_UPDATE:
             if ((session->builtin_recv_ext_types &
                  NGHTTP2_TYPEMASK_PRIORITY_UPDATE) == 0) {
+              /* Receiving too frequent unknown frames is suspicious. */
+              rv = session_update_glitch_ratelim(session);
+              if (rv != 0) {
+                return rv;
+              }
+
+              if (iframe->state == NGHTTP2_IB_IGN_ALL) {
+                return (nghttp2_ssize)inlen;
+              }
+
               busy = 1;
               iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
               break;
@@ -6397,16 +5966,16 @@
 
             iframe->frame.hd.flags = NGHTTP2_FLAG_NONE;
             iframe->frame.ext.payload =
-                &iframe->ext_frame_payload.priority_update;
+              &iframe->ext_frame_payload.priority_update;
 
             if (!session->server) {
               rv = nghttp2_session_terminate_session_with_reason(
-                  session, NGHTTP2_PROTOCOL_ERROR,
-                  "PRIORITY_UPDATE is received from server");
+                session, NGHTTP2_PROTOCOL_ERROR,
+                "PRIORITY_UPDATE is received from server");
               if (nghttp2_is_fatal(rv)) {
                 return rv;
               }
-              return (ssize_t)inlen;
+              return (nghttp2_ssize)inlen;
             }
 
             if (iframe->payloadleft < 4) {
@@ -6415,8 +5984,18 @@
               break;
             }
 
-            if (!session_no_rfc7540_pri_no_fallback(session) ||
-                iframe->payloadleft > sizeof(iframe->raw_sbuf)) {
+            /* Receiving too frequent PRIORITY_UPDATE is
+               suspicious. */
+            rv = session_update_glitch_ratelim(session);
+            if (rv != 0) {
+              return rv;
+            }
+
+            if (iframe->state == NGHTTP2_IB_IGN_ALL) {
+              return (nghttp2_ssize)inlen;
+            }
+
+            if (iframe->payloadleft > sizeof(iframe->raw_sbuf)) {
               busy = 1;
               iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
               break;
@@ -6429,6 +6008,16 @@
 
             break;
           default:
+            /* Receiving too frequent unknown frames is suspicious. */
+            rv = session_update_glitch_ratelim(session);
+            if (rv != 0) {
+              return rv;
+            }
+
+            if (iframe->state == NGHTTP2_IB_IGN_ALL) {
+              return (nghttp2_ssize)inlen;
+            }
+
             busy = 1;
 
             iframe->state = NGHTTP2_IB_IGN_PAYLOAD;
@@ -6464,11 +6053,11 @@
       in += readlen;
       iframe->payloadleft -= readlen;
 
-      DEBUGF("recv: readlen=%zu, payloadleft=%zu, left=%zd\n", 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;
+        return (nghttp2_ssize)(in - first);
       }
 
       switch (iframe->frame.hd.type) {
@@ -6480,11 +6069,11 @@
           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");
+              session, NGHTTP2_PROTOCOL_ERROR, "HEADERS: invalid padding");
             if (nghttp2_is_fatal(rv)) {
               return rv;
             }
-            return (ssize_t)inlen;
+            return (nghttp2_ssize)inlen;
           }
           iframe->frame.headers.padlen = (size_t)padlen;
 
@@ -6511,12 +6100,12 @@
         busy = 1;
 
         if (iframe->state == NGHTTP2_IB_IGN_ALL) {
-          return (ssize_t)inlen;
+          return (nghttp2_ssize)inlen;
         }
 
         if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
-          rv = nghttp2_session_add_rst_stream(
-              session, iframe->frame.hd.stream_id, NGHTTP2_INTERNAL_ERROR);
+          rv = session_handle_invalid_stream2(
+            session, iframe->frame.hd.stream_id, NULL, NGHTTP2_ERR_INTERNAL);
           if (nghttp2_is_fatal(rv)) {
             return rv;
           }
@@ -6525,6 +6114,15 @@
         }
 
         if (rv == NGHTTP2_ERR_IGN_HEADER_BLOCK) {
+          rv = session_update_glitch_ratelim(session);
+          if (rv != 0) {
+            return rv;
+          }
+
+          if (iframe->state == NGHTTP2_IB_IGN_ALL) {
+            return (nghttp2_ssize)inlen;
+          }
+
           iframe->state = NGHTTP2_IB_IGN_HEADER_BLOCK;
           break;
         }
@@ -6533,18 +6131,6 @@
 
         break;
       case NGHTTP2_PRIORITY:
-        if (!session_no_rfc7540_pri_no_fallback(session) &&
-            session->remote_settings.no_rfc7540_priorities != 1) {
-          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;
@@ -6555,7 +6141,7 @@
         }
 
         if (iframe->state == NGHTTP2_IB_IGN_ALL) {
-          return (ssize_t)inlen;
+          return (nghttp2_ssize)inlen;
         }
 
         session_inbound_frame_reset(session);
@@ -6566,14 +6152,13 @@
             (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) {
+                              > 1 + iframe->payloadleft) {
             rv = nghttp2_session_terminate_session_with_reason(
-                session, NGHTTP2_PROTOCOL_ERROR,
-                "PUSH_PROMISE: invalid padding");
+              session, NGHTTP2_PROTOCOL_ERROR, "PUSH_PROMISE: invalid padding");
             if (nghttp2_is_fatal(rv)) {
               return rv;
             }
-            return (ssize_t)inlen;
+            return (nghttp2_ssize)inlen;
           }
 
           iframe->frame.push_promise.padlen = (size_t)padlen;
@@ -6599,13 +6184,13 @@
         busy = 1;
 
         if (iframe->state == NGHTTP2_IB_IGN_ALL) {
-          return (ssize_t)inlen;
+          return (nghttp2_ssize)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);
+          rv = session_handle_invalid_stream2(
+            session, iframe->frame.push_promise.promised_stream_id, NULL,
+            NGHTTP2_ERR_INTERNAL);
           if (nghttp2_is_fatal(rv)) {
             return rv;
           }
@@ -6628,7 +6213,7 @@
         }
 
         if (iframe->state == NGHTTP2_IB_IGN_ALL) {
-          return (ssize_t)inlen;
+          return (nghttp2_ssize)inlen;
         }
 
         session_inbound_frame_reset(session);
@@ -6663,7 +6248,7 @@
         }
 
         if (iframe->state == NGHTTP2_IB_IGN_ALL) {
-          return (ssize_t)inlen;
+          return (nghttp2_ssize)inlen;
         }
 
         session_inbound_frame_reset(session);
@@ -6684,7 +6269,7 @@
 
         if (iframe->frame.hd.length > 2) {
           iframe->raw_lbuf =
-              nghttp2_mem_malloc(mem, iframe->frame.hd.length - 2);
+            nghttp2_mem_malloc(mem, iframe->frame.hd.length - 2);
 
           if (iframe->raw_lbuf == NULL) {
             return NGHTTP2_ERR_NOMEM;
@@ -6721,7 +6306,7 @@
       break;
     case NGHTTP2_IB_READ_HEADER_BLOCK:
     case NGHTTP2_IB_IGN_HEADER_BLOCK: {
-      ssize_t data_readlen;
+      nghttp2_ssize data_readlen;
       size_t trail_padlen;
       int final;
 #ifdef DEBUGBUILD
@@ -6730,7 +6315,7 @@
       } else {
         DEBUGF("recv: [IB_IGN_HEADER_BLOCK]\n");
       }
-#endif /* DEBUGBUILD */
+#endif /* defined(DEBUGBUILD) */
 
       readlen = inbound_frame_payload_readlen(iframe, in, last);
 
@@ -6738,7 +6323,7 @@
              iframe->payloadleft - readlen);
 
       data_readlen = inbound_frame_effective_readlen(
-          iframe, iframe->payloadleft - readlen, readlen);
+        iframe, iframe->payloadleft - readlen, readlen);
 
       if (data_readlen == -1) {
         /* everything is padding */
@@ -6756,23 +6341,23 @@
         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);
+          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;
+          return (nghttp2_ssize)inlen;
         }
 
         if (rv == NGHTTP2_ERR_PAUSE) {
           in += hd_proclen;
           iframe->payloadleft -= hd_proclen;
 
-          return in - first;
+          return (nghttp2_ssize)(in - first);
         }
 
         if (rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
@@ -6783,12 +6368,12 @@
           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);
+          rv = session_handle_invalid_stream2(
+            session,
+            iframe->frame.hd.type == NGHTTP2_PUSH_PROMISE
+              ? iframe->frame.push_promise.promised_stream_id
+              : iframe->frame.hd.stream_id,
+            NULL, NGHTTP2_ERR_INTERNAL);
           if (nghttp2_is_fatal(rv)) {
             return rv;
           }
@@ -6820,7 +6405,6 @@
       }
 
       if ((iframe->frame.hd.flags & NGHTTP2_FLAG_END_HEADERS) == 0) {
-
         inbound_frame_set_mark(iframe, NGHTTP2_FRAME_HDLEN);
 
         iframe->padlen = 0;
@@ -6836,8 +6420,14 @@
           if (nghttp2_is_fatal(rv)) {
             return rv;
           }
+
+          if (iframe->state == NGHTTP2_IB_IGN_ALL) {
+            return (nghttp2_ssize)inlen;
+          }
         }
         session_inbound_frame_reset(session);
+
+        session->num_continuations = 0;
       }
       break;
     }
@@ -6879,7 +6469,7 @@
 
       assert(iframe->state == NGHTTP2_IB_IGN_ALL);
 
-      return (ssize_t)inlen;
+      return (nghttp2_ssize)inlen;
     case NGHTTP2_IB_READ_SETTINGS:
       DEBUGF("recv: [IB_READ_SETTINGS]\n");
 
@@ -6909,7 +6499,7 @@
       }
 
       if (iframe->state == NGHTTP2_IB_IGN_ALL) {
-        return (ssize_t)inlen;
+        return (nghttp2_ssize)inlen;
       }
 
       session_inbound_frame_reset(session);
@@ -6943,7 +6533,7 @@
       }
 
       if (iframe->state == NGHTTP2_IB_IGN_ALL) {
-        return (ssize_t)inlen;
+        return (nghttp2_ssize)inlen;
       }
 
       session_inbound_frame_reset(session);
@@ -6957,13 +6547,17 @@
       } else {
         fprintf(stderr, "recv: [IB_IGN_CONTINUATION]\n");
       }
-#endif /* DEBUGBUILD */
+#endif /* defined(DEBUGBUILD) */
+
+      if (++session->num_continuations > session->max_continuations) {
+        return NGHTTP2_ERR_TOO_MANY_CONTINUATIONS;
+      }
 
       readlen = inbound_frame_buf_read(iframe, in, last);
       in += readlen;
 
       if (nghttp2_buf_mark_avail(&iframe->sbuf)) {
-        return in - first;
+        return (nghttp2_ssize)(in - first);
       }
 
       nghttp2_frame_unpack_frame_hd(&cont_hd, iframe->sbuf.pos);
@@ -6979,20 +6573,20 @@
                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");
+          session, NGHTTP2_PROTOCOL_ERROR,
+          "unexpected non-CONTINUATION frame or stream_id is invalid");
         if (nghttp2_is_fatal(rv)) {
           return rv;
         }
 
-        return (ssize_t)inlen;
+        return (nghttp2_ssize)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));
+        (uint8_t)(iframe->frame.hd.flags |
+                  (cont_hd.flags & NGHTTP2_FLAG_END_HEADERS));
       iframe->frame.hd.length += cont_hd.length;
 
       busy = 1;
@@ -7021,7 +6615,7 @@
              iframe->payloadleft, nghttp2_buf_mark_avail(&iframe->sbuf));
 
       if (nghttp2_buf_mark_avail(&iframe->sbuf)) {
-        return in - first;
+        return (nghttp2_ssize)(in - first);
       }
 
       /* Pad Length field is subject to flow control */
@@ -7031,30 +6625,34 @@
       }
 
       if (iframe->state == NGHTTP2_IB_IGN_ALL) {
-        return (ssize_t)inlen;
+        return (nghttp2_ssize)inlen;
       }
 
       /* Pad Length field is consumed immediately */
       rv =
-          nghttp2_session_consume(session, iframe->frame.hd.stream_id, readlen);
+        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;
+        return (nghttp2_ssize)inlen;
       }
 
       stream = nghttp2_session_get_stream(session, iframe->frame.hd.stream_id);
       if (stream) {
         rv = nghttp2_session_update_recv_stream_window_size(
-            session, stream, readlen,
-            iframe->payloadleft ||
-                (iframe->frame.hd.flags & NGHTTP2_FLAG_END_STREAM) == 0);
+          session, stream, readlen,
+          iframe->payloadleft ||
+            (iframe->frame.hd.flags & NGHTTP2_FLAG_END_STREAM) == 0);
         if (nghttp2_is_fatal(rv)) {
           return rv;
         }
+
+        if (iframe->state == NGHTTP2_IB_IGN_ALL) {
+          return (nghttp2_ssize)inlen;
+        }
       }
 
       busy = 1;
@@ -7062,15 +6660,29 @@
       padlen = inbound_frame_compute_pad(iframe);
       if (padlen < 0) {
         rv = nghttp2_session_terminate_session_with_reason(
-            session, NGHTTP2_PROTOCOL_ERROR, "DATA: invalid padding");
+          session, NGHTTP2_PROTOCOL_ERROR, "DATA: invalid padding");
         if (nghttp2_is_fatal(rv)) {
           return rv;
         }
-        return (ssize_t)inlen;
+        return (nghttp2_ssize)inlen;
       }
 
       iframe->frame.data.padlen = (size_t)padlen;
 
+      /* Empty DATA frame without END_STREAM flag set is
+         suspicious. */
+      if (iframe->payloadleft == 0 &&
+          (iframe->frame.hd.flags & NGHTTP2_FLAG_END_STREAM) == 0) {
+        rv = session_update_glitch_ratelim(session);
+        if (rv != 0) {
+          return rv;
+        }
+
+        if (iframe->state == NGHTTP2_IB_IGN_ALL) {
+          return (nghttp2_ssize)inlen;
+        }
+      }
+
       iframe->state = NGHTTP2_IB_READ_DATA;
 
       break;
@@ -7093,35 +6705,39 @@
              iframe->payloadleft);
 
       if (readlen > 0) {
-        ssize_t data_readlen;
+        nghttp2_ssize data_readlen;
 
-        rv = nghttp2_session_update_recv_connection_window_size(session,
-                                                                readlen);
+        rv =
+          nghttp2_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;
+          return (nghttp2_ssize)inlen;
         }
 
         rv = nghttp2_session_update_recv_stream_window_size(
-            session, stream, readlen,
-            iframe->payloadleft ||
-                (iframe->frame.hd.flags & NGHTTP2_FLAG_END_STREAM) == 0);
+          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 (iframe->state == NGHTTP2_IB_IGN_ALL) {
+          return (nghttp2_ssize)inlen;
+        }
+
+        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;
+        padlen = (nghttp2_ssize)readlen - data_readlen;
 
         if (padlen > 0) {
           /* Padding is considered as "consumed" immediately */
@@ -7133,45 +6749,30 @@
           }
 
           if (iframe->state == NGHTTP2_IB_IGN_ALL) {
-            return (ssize_t)inlen;
+            return (nghttp2_ssize)inlen;
           }
         }
 
-        DEBUGF("recv: data_readlen=%zd\n", data_readlen);
+        DEBUGF("recv: data_readlen=%td\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);
+              rv = nghttp2_session_terminate_session(session,
+                                                     NGHTTP2_PROTOCOL_ERROR);
               if (nghttp2_is_fatal(rv)) {
                 return rv;
               }
-              busy = 1;
-              iframe->state = NGHTTP2_IB_IGN_DATA;
-              break;
+
+              return (nghttp2_ssize)inlen;
             }
           }
           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);
+              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;
+              return (nghttp2_ssize)(in - first);
             }
 
             if (nghttp2_is_fatal(rv)) {
@@ -7190,6 +6791,10 @@
         return rv;
       }
 
+      if (iframe->state == NGHTTP2_IB_IGN_ALL) {
+        return (nghttp2_ssize)inlen;
+      }
+
       session_inbound_frame_reset(session);
 
       break;
@@ -7206,18 +6811,17 @@
       if (readlen > 0) {
         /* Update connection-level flow control window for ignored
            DATA frame too */
-        rv = nghttp2_session_update_recv_connection_window_size(session,
-                                                                readlen);
+        rv =
+          nghttp2_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;
+          return (nghttp2_ssize)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);
 
@@ -7226,7 +6830,7 @@
           }
 
           if (iframe->state == NGHTTP2_IB_IGN_ALL) {
-            return (ssize_t)inlen;
+            return (nghttp2_ssize)inlen;
           }
         }
       }
@@ -7239,7 +6843,7 @@
 
       break;
     case NGHTTP2_IB_IGN_ALL:
-      return (ssize_t)inlen;
+      return (nghttp2_ssize)inlen;
     case NGHTTP2_IB_READ_EXTENSION_PAYLOAD:
       DEBUGF("recv: [IB_READ_EXTENSION_PAYLOAD]\n");
 
@@ -7252,7 +6856,7 @@
 
       if (readlen > 0) {
         rv = session_call_on_extension_chunk_recv_callback(
-            session, in - readlen, readlen);
+          session, in - readlen, readlen);
         if (nghttp2_is_fatal(rv)) {
           return rv;
         }
@@ -7334,7 +6938,7 @@
       }
 
       if (iframe->state == NGHTTP2_IB_IGN_ALL) {
-        return (ssize_t)inlen;
+        return (nghttp2_ssize)inlen;
       }
 
       session_inbound_frame_reset(session);
@@ -7351,16 +6955,17 @@
 
   assert(in == last);
 
-  return in - first;
+  return (nghttp2_ssize)(in - first);
 }
 
 int nghttp2_session_recv(nghttp2_session *session) {
   uint8_t buf[NGHTTP2_INBOUND_BUFFER_LENGTH];
   while (1) {
-    ssize_t readlen;
+    nghttp2_ssize readlen;
     readlen = session_recv(session, buf, sizeof(buf));
     if (readlen > 0) {
-      ssize_t proclen = nghttp2_session_mem_recv(session, buf, (size_t)readlen);
+      nghttp2_ssize proclen =
+        nghttp2_session_mem_recv2(session, buf, (size_t)readlen);
       if (proclen < 0) {
         return (int)proclen;
       }
@@ -7423,9 +7028,7 @@
    */
   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_sched_empty(session)) &&
-          session->remote_window_size > 0) ||
+         (!session_sched_empty(session) && session->remote_window_size > 0) ||
          (nghttp2_outbound_queue_top(&session->ob_syn) &&
           !session_is_outgoing_concurrent_streams_max(session));
 }
@@ -7509,7 +7112,8 @@
 
   /* 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);
+  last_stream_id =
+    nghttp2_min_int32(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);
@@ -7523,6 +7127,9 @@
     nghttp2_mem_free(mem, item);
     return rv;
   }
+
+  session->goaway_flags |= NGHTTP2_GOAWAY_SUBMITTED;
+
   return 0;
 }
 
@@ -7699,8 +7306,8 @@
                               nghttp2_stream *stream) {
   int rv;
   uint32_t data_flags;
-  ssize_t payloadlen;
-  ssize_t padded_payloadlen;
+  nghttp2_ssize payloadlen;
+  nghttp2_ssize padded_payloadlen;
   nghttp2_buf *buf;
   size_t max_payloadlen;
 
@@ -7708,19 +7315,26 @@
 
   buf = &bufs->cur->buf;
 
-  if (session->callbacks.read_length_callback) {
-
-    payloadlen = session->callbacks.read_length_callback(
+  if (session->callbacks.read_length_callback2 ||
+      session->callbacks.read_length_callback) {
+    if (session->callbacks.read_length_callback2) {
+      payloadlen = session->callbacks.read_length_callback2(
         session, frame->hd.type, stream->stream_id, session->remote_window_size,
         stream->remote_window_size, session->remote_settings.max_frame_size,
         session->user_data);
+    } else {
+      payloadlen = (nghttp2_ssize)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);
+    DEBUGF("send: read_length_callback=%td\n", payloadlen);
 
-    payloadlen = nghttp2_session_enforce_flow_control_limits(session, stream,
-                                                             payloadlen);
+    payloadlen =
+      nghttp2_session_enforce_flow_control_limits(session, stream, payloadlen);
 
-    DEBUGF("send: read_length_callback after flow control=%zd\n", payloadlen);
+    DEBUGF("send: read_length_callback after flow control=%td\n", payloadlen);
 
     if (payloadlen <= 0) {
       return NGHTTP2_ERR_CALLBACK_FAILURE;
@@ -7736,9 +7350,9 @@
         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;
+        payloadlen = (nghttp2_ssize)datamax;
 
-        DEBUGF("send: use safe limit payloadlen=%zd", payloadlen);
+        DEBUGF("send: use safe limit payloadlen=%td", payloadlen);
       } else {
         assert(&session->aob.framebufs == bufs);
 
@@ -7752,9 +7366,23 @@
   assert(nghttp2_buf_avail(buf) >= datamax);
 
   data_flags = NGHTTP2_DATA_FLAG_NONE;
-  payloadlen = aux_data->data_prd.read_callback(
+  switch (aux_data->dpw.version) {
+  case NGHTTP2_DATA_PROVIDER_V1:
+    payloadlen = (nghttp2_ssize)aux_data->dpw.data_prd.v1.read_callback(
       session, frame->hd.stream_id, buf->pos, datamax, &data_flags,
-      &aux_data->data_prd.source, session->user_data);
+      &aux_data->dpw.data_prd.source, session->user_data);
+
+    break;
+  case NGHTTP2_DATA_PROVIDER_V2:
+    payloadlen = aux_data->dpw.data_prd.v2.read_callback(
+      session, frame->hd.stream_id, buf->pos, datamax, &data_flags,
+      &aux_data->dpw.data_prd.source, session->user_data);
+
+    break;
+  default:
+    assert(0);
+    abort();
+  }
 
   if (payloadlen == NGHTTP2_ERR_DEFERRED ||
       payloadlen == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE ||
@@ -7799,10 +7427,11 @@
   frame->hd.length = (size_t)payloadlen;
   frame->data.padlen = 0;
 
-  max_payloadlen = nghttp2_min(datamax, frame->hd.length + NGHTTP2_MAX_PADLEN);
+  max_payloadlen =
+    nghttp2_min_size(datamax, frame->hd.length + NGHTTP2_MAX_PADLEN);
 
   padded_payloadlen =
-      session_call_select_padding(session, frame, max_payloadlen);
+    session_call_select_padding(session, frame, max_payloadlen);
 
   if (nghttp2_is_fatal((int)padded_payloadlen)) {
     return (int)padded_payloadlen;
@@ -7812,11 +7441,8 @@
 
   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;
-  }
+  nghttp2_frame_add_pad(bufs, &frame->hd, frame->data.padlen,
+                        aux_data->no_copy);
 
   session_reschedule_stream(session, stream);
 
@@ -7976,7 +7602,7 @@
 
   /* stream->remote_window_size can be negative when
      SETTINGS_INITIAL_WINDOW_SIZE is changed. */
-  return nghttp2_max(0, stream->remote_window_size);
+  return nghttp2_max_int32(0, stream->remote_window_size);
 }
 
 int32_t nghttp2_session_get_remote_window_size(nghttp2_session *session) {
@@ -8042,7 +7668,6 @@
   nghttp2_settings_entry *iv;
   size_t niv;
   int rv;
-  nghttp2_priority_spec pri_spec;
   nghttp2_mem *mem;
 
   mem = &session->mem;
@@ -8079,18 +7704,13 @@
     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);
+    session, 1, NGHTTP2_STREAM_FLAG_NONE, 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;
@@ -8289,14 +7909,16 @@
 nghttp2_stream *nghttp2_session_find_stream(nghttp2_session *session,
                                             int32_t stream_id) {
   if (stream_id == 0) {
-    return &session->root;
+    return &nghttp2_stream_root;
   }
 
   return nghttp2_session_get_stream_raw(session, stream_id);
 }
 
 nghttp2_stream *nghttp2_session_get_root_stream(nghttp2_session *session) {
-  return &session->root;
+  (void)session;
+
+  return &nghttp2_stream_root;
 }
 
 int nghttp2_session_check_server_session(nghttp2_session *session) {
@@ -8304,77 +7926,22 @@
 }
 
 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;
+  nghttp2_session *session, int32_t stream_id,
+  const nghttp2_priority_spec *pri_spec) {
+  (void)session;
+  (void)stream_id;
+  (void)pri_spec;
 
-  if (session->pending_no_rfc7540_priorities == 1) {
-    return 0;
-  }
-
-  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;
+  (void)session;
+  (void)stream_id;
+  (void)pri_spec;
 
-  if (session->pending_no_rfc7540_priorities == 1) {
-    return 0;
-  }
-
-  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;
 }
 
@@ -8393,8 +7960,8 @@
 }
 
 int nghttp2_session_change_extpri_stream_priority(
-    nghttp2_session *session, int32_t stream_id,
-    const nghttp2_extpri *extpri_in, int ignore_client_signal) {
+  nghttp2_session *session, int32_t stream_id, const nghttp2_extpri *extpri_in,
+  int ignore_client_signal) {
   nghttp2_stream *stream;
   nghttp2_extpri extpri = *extpri_in;
 
@@ -8426,3 +7993,30 @@
   return session_update_stream_priority(session, stream,
                                         nghttp2_extpri_to_uint8(&extpri));
 }
+
+int nghttp2_session_get_extpri_stream_priority(nghttp2_session *session,
+                                               nghttp2_extpri *extpri,
+                                               int32_t stream_id) {
+  nghttp2_stream *stream;
+
+  if (!session->server) {
+    return NGHTTP2_ERR_INVALID_STATE;
+  }
+
+  if (session->pending_no_rfc7540_priorities != 1) {
+    return 0;
+  }
+
+  if (stream_id == 0) {
+    return NGHTTP2_ERR_INVALID_ARGUMENT;
+  }
+
+  stream = nghttp2_session_get_stream_raw(session, stream_id);
+  if (!stream) {
+    return NGHTTP2_ERR_INVALID_ARGUMENT;
+  }
+
+  nghttp2_extpri_from_uint8(extpri, stream->extpri);
+
+  return 0;
+}
diff --git a/Utilities/cmnghttp2/lib/nghttp2_session.h b/Utilities/cmnghttp2/lib/nghttp2_session.h
index 34d2d58..edbef80 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_session.h
+++ b/Utilities/cmnghttp2/lib/nghttp2_session.h
@@ -27,7 +27,7 @@
 
 #ifdef HAVE_CONFIG_H
 #  include <config.h>
-#endif /* HAVE_CONFIG_H */
+#endif /* defined(HAVE_CONFIG_H) */
 
 #include <nghttp2/nghttp2.h>
 #include "nghttp2_map.h"
@@ -39,11 +39,14 @@
 #include "nghttp2_buf.h"
 #include "nghttp2_callbacks.h"
 #include "nghttp2_mem.h"
+#include "nghttp2_ratelim.h"
 
 /* The global variable for tests where we want to disable strict
    preface handling. */
 extern int nghttp2_enable_strict_preface;
 
+extern nghttp2_stream nghttp2_stream_root;
+
 /*
  * Option flags.
  */
@@ -52,8 +55,6 @@
   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_SERVER_FALLBACK_RFC7540_PRIORITIES = 1 << 5,
   NGHTTP2_OPTMASK_NO_RFC9113_LEADING_AND_TRAILING_WS_VALIDATION = 1 << 6,
 } nghttp2_optmask;
 
@@ -88,10 +89,6 @@
 /* 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
@@ -105,6 +102,18 @@
 /* The default value of maximum number of concurrent streams. */
 #define NGHTTP2_DEFAULT_MAX_CONCURRENT_STREAMS 0xffffffffu
 
+/* The default values for stream reset rate limiter. */
+#define NGHTTP2_DEFAULT_STREAM_RESET_BURST 1000
+#define NGHTTP2_DEFAULT_STREAM_RESET_RATE 33
+
+/* The default values for glitch rate limiter. */
+#define NGHTTP2_DEFAULT_GLITCH_BURST 1000
+#define NGHTTP2_DEFAULT_GLITCH_RATE 33
+
+/* The default max number of CONTINUATION frames following an incoming
+   HEADER frame. */
+#define NGHTTP2_DEFAULT_MAX_CONTINUATIONS 8
+
 /* Internal state when receiving incoming frame */
 typedef enum {
   /* Receiving frame header */
@@ -178,7 +187,9 @@
   /* Flag means GOAWAY was sent */
   NGHTTP2_GOAWAY_SENT = 0x4,
   /* Flag means GOAWAY was received */
-  NGHTTP2_GOAWAY_RECV = 0x8
+  NGHTTP2_GOAWAY_RECV = 0x8,
+  /* Flag means GOAWAY has been submitted at least once */
+  NGHTTP2_GOAWAY_SUBMITTED = 0x10
 } nghttp2_goaway_flag;
 
 /* nghttp2_inflight_settings stores the SETTINGS entries which local
@@ -194,8 +205,6 @@
 
 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 */
@@ -218,23 +227,14 @@
   /* 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;
+  /* Stream reset rate limiter.  If receiving excessive amount of
+     stream resets, GOAWAY will be sent. */
+  nghttp2_ratelim stream_reset_ratelim;
+  /* Rate limiter for all kinds of glitches. */
+  nghttp2_ratelim glitch_ratelim;
   /* Sequential number across all streams to process streams in
      FIFO. */
   uint64_t stream_seq;
@@ -262,10 +262,9 @@
      |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. */
+  /* The number of idle streams kept in |streams| hash.  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;
@@ -280,6 +279,12 @@
   size_t max_send_header_block_length;
   /* The maximum number of settings accepted per SETTINGS frame. */
   size_t max_settings;
+  /* The maximum number of CONTINUATION frames following an incoming
+     HEADER frame. */
+  size_t max_continuations;
+  /* The number of CONTINUATION frames following an incoming HEADER
+     frame.  This variable is reset when END_HEADERS flag is seen. */
+  size_t num_continuations;
   /* 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,
@@ -342,8 +347,6 @@
   /* Unacked local SETTINGS_NO_RFC7540_PRIORITIES value, which is
      effective before it is acknowledged. */
   uint8_t pending_no_rfc7540_priorities;
-  /* Turn on fallback to RFC 7540 priorities; for server use only. */
-  uint8_t fallback_rfc7540_priorities;
   /* Nonzero if the session is server side. */
   uint8_t server;
   /* Flags indicating GOAWAY is sent and/or received. The flags are
@@ -406,13 +409,22 @@
                              nghttp2_outbound_item *item);
 
 /*
+ * This function wraps around nghttp2_session_add_rst_stream_continue
+ * with continue_without_stream = 1.
+ */
+int nghttp2_session_add_rst_stream(nghttp2_session *session, int32_t stream_id,
+                                   uint32_t error_code);
+
+/*
  * 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.
+ * RST_STREAM for a stream is redundant.  It also returns 0 without
+ * adding the frame if |continue_without_stream| is nonzero, and
+ * stream was already gone.
  *
  * This function returns 0 if it succeeds, or one of the following
  * negative error codes:
@@ -420,8 +432,10 @@
  * NGHTTP2_ERR_NOMEM
  *     Out of memory.
  */
-int nghttp2_session_add_rst_stream(nghttp2_session *session, int32_t stream_id,
-                                   uint32_t error_code);
+int nghttp2_session_add_rst_stream_continue(nghttp2_session *session,
+                                            int32_t stream_id,
+                                            uint32_t error_code,
+                                            int continue_without_stream);
 
 /*
  * Adds PING frame. This is a convenient function built on top of
@@ -507,15 +521,9 @@
  *
  * 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);
 
@@ -524,11 +532,6 @@
  * 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:
  *
@@ -545,63 +548,9 @@
 /*
  * 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);
+void nghttp2_session_destroy_stream(nghttp2_session *session,
+                                    nghttp2_stream *stream);
 
 /*
  * If further receptions and transmissions over the stream |stream_id|
@@ -896,24 +845,6 @@
                                           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.
  *
@@ -961,4 +892,4 @@
                                                    size_t delta_size,
                                                    int send_window_update);
 
-#endif /* NGHTTP2_SESSION_H */
+#endif /* !defined(NGHTTP2_SESSION_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_stream.c b/Utilities/cmnghttp2/lib/nghttp2_stream.c
index b3614a0..0f2d365 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_stream.c
+++ b/Utilities/cmnghttp2/lib/nghttp2_stream.c
@@ -25,45 +25,17 @@
 #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
-   priority 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 remote_initial_window_size,
                          int32_t local_initial_window_size,
-                         void *stream_user_data, nghttp2_mem *mem) {
-  nghttp2_pq_init(&stream->obq, stream_less, mem);
-
+                         void *stream_user_data) {
   stream->stream_id = stream_id;
   stream->flags = flags;
   stream->state = initial_state;
@@ -77,477 +49,62 @@
   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;
 
   stream->extpri = stream->http_extpri = NGHTTP2_EXTPRI_DEFAULT_URGENCY;
 }
 
-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_free(nghttp2_stream *stream) { (void)stream; }
 
 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;
-
+void nghttp2_stream_attach_item(nghttp2_stream *stream,
+                                nghttp2_outbound_item *item) {
   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;
-
-  if (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) {
-    return 0;
-  }
-
-  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) {
+void 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);
-
-  if (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) {
-    return 0;
-  }
-
-  return stream_update_dep_on_detach_item(stream);
 }
 
-int nghttp2_stream_defer_item(nghttp2_stream *stream, uint8_t flags) {
+void 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;
-
-  if (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) {
-    return 0;
-  }
-
-  return stream_update_dep_on_detach_item(stream);
 }
 
-int nghttp2_stream_resume_deferred_item(nghttp2_stream *stream, uint8_t flags) {
+void 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;
-  }
-
-  if (stream->flags & NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES) {
-    return 0;
-  }
-
-  return stream_update_dep_on_attach_item(stream);
 }
 
 int nghttp2_stream_check_deferred_item(nghttp2_stream *stream) {
@@ -573,16 +130,16 @@
 }
 
 int nghttp2_stream_update_remote_initial_window_size(
-    nghttp2_stream *stream, int32_t new_initial_window_size,
-    int32_t old_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) {
+  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);
@@ -593,373 +150,11 @@
   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 == &nghttp2_stream_root) {
+    return NGHTTP2_STREAM_STATE_IDLE;
+  }
+
   if (stream->flags & NGHTTP2_STREAM_FLAG_CLOSED) {
     return NGHTTP2_STREAM_STATE_CLOSED;
   }
@@ -990,27 +185,39 @@
 }
 
 nghttp2_stream *nghttp2_stream_get_parent(nghttp2_stream *stream) {
-  return stream->dep_prev;
+  (void)stream;
+
+  return NULL;
 }
 
 nghttp2_stream *nghttp2_stream_get_next_sibling(nghttp2_stream *stream) {
-  return stream->sib_next;
+  (void)stream;
+
+  return NULL;
 }
 
 nghttp2_stream *nghttp2_stream_get_previous_sibling(nghttp2_stream *stream) {
-  return stream->sib_prev;
+  (void)stream;
+
+  return NULL;
 }
 
 nghttp2_stream *nghttp2_stream_get_first_child(nghttp2_stream *stream) {
-  return stream->dep_next;
+  (void)stream;
+
+  return NULL;
 }
 
 int32_t nghttp2_stream_get_weight(nghttp2_stream *stream) {
-  return stream->weight;
+  (void)stream;
+
+  return NGHTTP2_DEFAULT_WEIGHT;
 }
 
 int32_t nghttp2_stream_get_sum_dependency_weight(nghttp2_stream *stream) {
-  return stream->sum_dep_weight;
+  (void)stream;
+
+  return 0;
 }
 
 int32_t nghttp2_stream_get_stream_id(nghttp2_stream *stream) {
diff --git a/Utilities/cmnghttp2/lib/nghttp2_stream.h b/Utilities/cmnghttp2/lib/nghttp2_stream.h
index 7a8e4c6..603209e 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_stream.h
+++ b/Utilities/cmnghttp2/lib/nghttp2_stream.h
@@ -27,7 +27,7 @@
 
 #ifdef HAVE_CONFIG_H
 #  include <config.h>
-#endif /* HAVE_CONFIG_H */
+#endif /* defined(HAVE_CONFIG_H) */
 
 #include <nghttp2/nghttp2.h>
 #include "nghttp2_outbound_item.h"
@@ -91,9 +91,6 @@
   /* bitwise OR of NGHTTP2_STREAM_FLAG_DEFERRED_FLOW_CONTROL and
      NGHTTP2_STREAM_FLAG_DEFERRED_USER. */
   NGHTTP2_STREAM_FLAG_DEFERRED_ALL = 0x0c,
-  /* Indicates that this stream is not subject to RFC7540
-     priorities scheme. */
-  NGHTTP2_STREAM_FLAG_NO_RFC7540_PRIORITIES = 0x10,
   /* Ignore client RFC 9218 priority signal. */
   NGHTTP2_STREAM_FLAG_IGNORE_CLIENT_PRIORITIES = 0x20,
   /* Indicates that RFC 9113 leading and trailing white spaces
@@ -124,10 +121,9 @@
   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,
+  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,
@@ -147,39 +143,18 @@
 } nghttp2_http_flag;
 
 struct nghttp2_stream {
-  /* Entry for dep_prev->obq */
+  nghttp2_stream_state state;
   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;
+  nghttp2_stream *closed_next;
   /* The arbitrary data provided by user for this stream. */
   void *stream_user_data;
   /* Item to send */
@@ -206,13 +181,8 @@
      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 */
@@ -240,9 +210,9 @@
 
 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 remote_initial_window_size,
                          int32_t local_initial_window_size,
-                         void *stream_user_data, nghttp2_mem *mem);
+                         void *stream_user_data);
 
 void nghttp2_stream_free(nghttp2_stream *stream);
 
@@ -258,14 +228,8 @@
  * 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);
+void nghttp2_stream_defer_item(nghttp2_stream *stream, uint8_t flags);
 
 /*
  * Put back deferred data in this stream to active state.  The |flags|
@@ -274,14 +238,8 @@
  * 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);
+void nghttp2_stream_resume_deferred_item(nghttp2_stream *stream, uint8_t flags);
 
 /*
  * Returns nonzero if item is deferred by whatever reason.
@@ -302,8 +260,8 @@
  * overflow.
  */
 int nghttp2_stream_update_remote_initial_window_size(
-    nghttp2_stream *stream, int32_t new_initial_window_size,
-    int32_t old_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
@@ -314,8 +272,8 @@
  * overflow.
  */
 int nghttp2_stream_update_local_initial_window_size(
-    nghttp2_stream *stream, int32_t new_initial_window_size,
-    int32_t old_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
@@ -325,129 +283,15 @@
 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);
+void 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);
+void 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 */
+#endif /* !defined(NGHTTP2_STREAM_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_submit.c b/Utilities/cmnghttp2/lib/nghttp2_submit.c
index f5554eb..8a90f71 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_submit.c
+++ b/Utilities/cmnghttp2/lib/nghttp2_submit.c
@@ -32,43 +32,13 @@
 #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,
+                                     int32_t stream_id, nghttp2_nv *nva_copy,
+                                     size_t nvlen,
+                                     const nghttp2_data_provider_wrap *dpw,
                                      void *stream_user_data) {
   int rv;
   uint8_t flags_copy;
@@ -87,15 +57,15 @@
 
   nghttp2_outbound_item_init(item);
 
-  if (data_prd != NULL && data_prd->read_callback != NULL) {
-    item->aux_data.headers.data_prd = *data_prd;
+  if (dpw != NULL && dpw->data_prd.read_callback != NULL) {
+    item->aux_data.headers.dpw = *dpw;
   }
 
   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);
+    (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) {
@@ -114,8 +84,8 @@
 
   frame = &item->frame;
 
-  nghttp2_frame_headers_init(&frame->headers, flags_copy, stream_id, hcat,
-                             pri_spec, nva_copy, nvlen);
+  nghttp2_frame_headers_init(&frame->headers, flags_copy, stream_id, hcat, NULL,
+                             nva_copy, nvlen);
 
   rv = nghttp2_session_add_item(session, item);
 
@@ -141,31 +111,22 @@
 
 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,
+                                         const nghttp2_data_provider_wrap *dpw,
                                          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);
+  return submit_headers_shared(session, flags, stream_id, nva_copy, nvlen, dpw,
+                               stream_user_data);
 }
 
 int nghttp2_submit_trailer(nghttp2_session *session, int32_t stream_id,
@@ -175,8 +136,7 @@
   }
 
   return (int)submit_headers_shared_nva(session, NGHTTP2_FLAG_END_STREAM,
-                                        stream_id, NULL, nva, nvlen, NULL,
-                                        NULL);
+                                        stream_id, nva, nvlen, NULL, NULL);
 }
 
 int32_t nghttp2_submit_headers(nghttp2_session *session, uint8_t flags,
@@ -184,7 +144,7 @@
                                const nghttp2_priority_spec *pri_spec,
                                const nghttp2_nv *nva, size_t nvlen,
                                void *stream_user_data) {
-  int rv;
+  (void)pri_spec;
 
   if (stream_id == -1) {
     if (session->server) {
@@ -196,20 +156,8 @@
 
   flags &= NGHTTP2_FLAG_END_STREAM;
 
-  if (pri_spec && !nghttp2_priority_spec_check_default(pri_spec) &&
-      session->remote_settings.no_rfc7540_priorities != 1) {
-    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);
+  return submit_headers_shared_nva(session, flags, stream_id, nva, nvlen, NULL,
+                                   stream_user_data);
 }
 
 int nghttp2_submit_ping(nghttp2_session *session, uint8_t flags,
@@ -221,51 +169,10 @@
 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)session;
   (void)flags;
-
-  mem = &session->mem;
-
-  if (session->remote_settings.no_rfc7540_priorities == 1) {
-    return 0;
-  }
-
-  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;
-  }
+  (void)stream_id;
+  (void)pri_spec;
 
   return 0;
 }
@@ -278,7 +185,8 @@
     return NGHTTP2_ERR_INVALID_ARGUMENT;
   }
 
-  return nghttp2_session_add_rst_stream(session, stream_id, error_code);
+  return nghttp2_session_add_rst_stream_continue(
+    session, stream_id, error_code, /* continue_without_stream = */ 0);
 }
 
 int nghttp2_submit_goaway(nghttp2_session *session, uint8_t flags,
@@ -389,8 +297,8 @@
   }
   if (stream_id == 0) {
     rv = nghttp2_adjust_local_window_size(
-        &session->local_window_size, &session->recv_window_size,
-        &session->recv_reduction, &window_size_increment);
+      &session->local_window_size, &session->recv_window_size,
+      &session->recv_reduction, &window_size_increment);
     if (rv != 0) {
       return rv;
     }
@@ -401,8 +309,8 @@
     }
 
     rv = nghttp2_adjust_local_window_size(
-        &stream->local_window_size, &stream->recv_window_size,
-        &stream->recv_reduction, &window_size_increment);
+      &stream->local_window_size, &stream->recv_window_size,
+      &stream->recv_reduction, &window_size_increment);
     if (rv != 0) {
       return rv;
     }
@@ -411,10 +319,10 @@
   if (window_size_increment > 0) {
     if (stream_id == 0) {
       session->consumed_size =
-          nghttp2_max(0, session->consumed_size - window_size_increment);
+        nghttp2_max_int32(0, session->consumed_size - window_size_increment);
     } else {
       stream->consumed_size =
-          nghttp2_max(0, stream->consumed_size - window_size_increment);
+        nghttp2_max_int32(0, stream->consumed_size - window_size_increment);
     }
 
     return nghttp2_session_add_window_update(session, 0, stream_id,
@@ -444,13 +352,13 @@
 
     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);
+        &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);
+      &session->local_window_size, &session->recv_window_size,
+      &session->recv_reduction, &window_size_increment);
 
     if (rv != 0) {
       return rv;
@@ -477,13 +385,13 @@
 
     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);
+        &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);
+      &stream->local_window_size, &stream->recv_window_size,
+      &stream->recv_reduction, &window_size_increment);
 
     if (rv != 0) {
       return rv;
@@ -579,7 +487,7 @@
   return 0;
 
 fail_item_malloc:
-  free(buf);
+  nghttp2_mem_free(mem, buf);
 
   return rv;
 }
@@ -614,7 +522,7 @@
 
     /* The last nov is added for terminal NULL character. */
     ov_copy =
-        nghttp2_mem_malloc(mem, nov * sizeof(nghttp2_origin_entry) + len + nov);
+      nghttp2_mem_malloc(mem, nov * sizeof(nghttp2_origin_entry) + len + nov);
     if (ov_copy == NULL) {
       return NGHTTP2_ERR_NOMEM;
     }
@@ -662,7 +570,7 @@
   return 0;
 
 fail_item_malloc:
-  free(ov_copy);
+  nghttp2_mem_free(mem, ov_copy);
 
   return rv;
 }
@@ -734,23 +642,34 @@
   return 0;
 
 fail_item_malloc:
-  free(buf);
+  nghttp2_mem_free(mem, buf);
 
   return rv;
 }
 
-static uint8_t set_request_flags(const nghttp2_priority_spec *pri_spec,
-                                 const nghttp2_data_provider *data_prd) {
+static uint8_t set_request_flags(const nghttp2_data_provider_wrap *dpw) {
   uint8_t flags = NGHTTP2_FLAG_NONE;
-  if (data_prd == NULL || data_prd->read_callback == NULL) {
+  if (dpw == NULL || dpw->data_prd.read_callback == NULL) {
     flags |= NGHTTP2_FLAG_END_STREAM;
   }
 
-  if (pri_spec) {
-    flags |= NGHTTP2_FLAG_PRIORITY;
+  return flags;
+}
+
+static int32_t submit_request_shared(nghttp2_session *session,
+                                     const nghttp2_nv *nva, size_t nvlen,
+                                     const nghttp2_data_provider_wrap *dpw,
+                                     void *stream_user_data) {
+  uint8_t flags;
+
+  if (session->server) {
+    return NGHTTP2_ERR_PROTO;
   }
 
-  return flags;
+  flags = set_request_flags(dpw);
+
+  return submit_headers_shared_nva(session, flags, -1, nva, nvlen, dpw,
+                                   stream_user_data);
 }
 
 int32_t nghttp2_submit_request(nghttp2_session *session,
@@ -758,40 +677,38 @@
                                const nghttp2_nv *nva, size_t nvlen,
                                const nghttp2_data_provider *data_prd,
                                void *stream_user_data) {
-  uint8_t flags;
-  int rv;
+  nghttp2_data_provider_wrap dpw;
+  (void)pri_spec;
 
-  if (session->server) {
-    return NGHTTP2_ERR_PROTO;
-  }
-
-  if (pri_spec && !nghttp2_priority_spec_check_default(pri_spec) &&
-      session->remote_settings.no_rfc7540_priorities != 1) {
-    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);
+  return submit_request_shared(session, nva, nvlen,
+                               nghttp2_data_provider_wrap_v1(&dpw, data_prd),
+                               stream_user_data);
 }
 
-static uint8_t set_response_flags(const nghttp2_data_provider *data_prd) {
+int32_t nghttp2_submit_request2(nghttp2_session *session,
+                                const nghttp2_priority_spec *pri_spec,
+                                const nghttp2_nv *nva, size_t nvlen,
+                                const nghttp2_data_provider2 *data_prd,
+                                void *stream_user_data) {
+  nghttp2_data_provider_wrap dpw;
+  (void)pri_spec;
+
+  return submit_request_shared(session, nva, nvlen,
+                               nghttp2_data_provider_wrap_v2(&dpw, data_prd),
+                               stream_user_data);
+}
+
+static uint8_t set_response_flags(const nghttp2_data_provider_wrap *dpw) {
   uint8_t flags = NGHTTP2_FLAG_NONE;
-  if (data_prd == NULL || data_prd->read_callback == NULL) {
+  if (dpw == NULL || dpw->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) {
+static int submit_response_shared(nghttp2_session *session, int32_t stream_id,
+                                  const nghttp2_nv *nva, size_t nvlen,
+                                  const nghttp2_data_provider_wrap *dpw) {
   uint8_t flags;
 
   if (stream_id <= 0) {
@@ -802,14 +719,32 @@
     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);
+  flags = set_response_flags(dpw);
+  return submit_headers_shared_nva(session, flags, stream_id, nva, nvlen, dpw,
+                                   NULL);
 }
 
-int nghttp2_submit_data(nghttp2_session *session, uint8_t flags,
-                        int32_t stream_id,
-                        const nghttp2_data_provider *data_prd) {
+int nghttp2_submit_response(nghttp2_session *session, int32_t stream_id,
+                            const nghttp2_nv *nva, size_t nvlen,
+                            const nghttp2_data_provider *data_prd) {
+  nghttp2_data_provider_wrap dpw;
+
+  return submit_response_shared(session, stream_id, nva, nvlen,
+                                nghttp2_data_provider_wrap_v1(&dpw, data_prd));
+}
+
+int nghttp2_submit_response2(nghttp2_session *session, int32_t stream_id,
+                             const nghttp2_nv *nva, size_t nvlen,
+                             const nghttp2_data_provider2 *data_prd) {
+  nghttp2_data_provider_wrap dpw;
+
+  return submit_response_shared(session, stream_id, nva, nvlen,
+                                nghttp2_data_provider_wrap_v2(&dpw, data_prd));
+}
+
+int nghttp2_submit_data_shared(nghttp2_session *session, uint8_t flags,
+                               int32_t stream_id,
+                               const nghttp2_data_provider_wrap *dpw) {
   int rv;
   nghttp2_outbound_item *item;
   nghttp2_frame *frame;
@@ -832,7 +767,7 @@
 
   frame = &item->frame;
   aux_data = &item->aux_data.data;
-  aux_data->data_prd = *data_prd;
+  aux_data->dpw = *dpw;
   aux_data->eof = 0;
   aux_data->flags = nflags;
 
@@ -848,9 +783,37 @@
   return 0;
 }
 
+int nghttp2_submit_data(nghttp2_session *session, uint8_t flags,
+                        int32_t stream_id,
+                        const nghttp2_data_provider *data_prd) {
+  nghttp2_data_provider_wrap dpw;
+
+  assert(data_prd);
+
+  return nghttp2_submit_data_shared(
+    session, flags, stream_id, nghttp2_data_provider_wrap_v1(&dpw, data_prd));
+}
+
+int nghttp2_submit_data2(nghttp2_session *session, uint8_t flags,
+                         int32_t stream_id,
+                         const nghttp2_data_provider2 *data_prd) {
+  nghttp2_data_provider_wrap dpw;
+
+  assert(data_prd);
+
+  return nghttp2_submit_data_shared(
+    session, flags, stream_id, nghttp2_data_provider_wrap_v2(&dpw, data_prd));
+}
+
 ssize_t nghttp2_pack_settings_payload(uint8_t *buf, size_t buflen,
                                       const nghttp2_settings_entry *iv,
                                       size_t niv) {
+  return (ssize_t)nghttp2_pack_settings_payload2(buf, buflen, iv, niv);
+}
+
+nghttp2_ssize nghttp2_pack_settings_payload2(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;
   }
@@ -859,7 +822,7 @@
     return NGHTTP2_ERR_INSUFF_BUFSIZE;
   }
 
-  return (ssize_t)nghttp2_frame_pack_settings_payload(buf, iv, niv);
+  return (nghttp2_ssize)nghttp2_frame_pack_settings_payload(buf, iv, niv);
 }
 
 int nghttp2_submit_extension(nghttp2_session *session, uint8_t type,
@@ -875,7 +838,8 @@
     return NGHTTP2_ERR_INVALID_ARGUMENT;
   }
 
-  if (!session->callbacks.pack_extension_callback) {
+  if (!session->callbacks.pack_extension_callback2 &&
+      !session->callbacks.pack_extension_callback) {
     return NGHTTP2_ERR_INVALID_STATE;
   }
 
diff --git a/Utilities/cmnghttp2/lib/nghttp2_submit.h b/Utilities/cmnghttp2/lib/nghttp2_submit.h
index 74d702f..decf803 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_submit.h
+++ b/Utilities/cmnghttp2/lib/nghttp2_submit.h
@@ -27,8 +27,14 @@
 
 #ifdef HAVE_CONFIG_H
 #  include <config.h>
-#endif /* HAVE_CONFIG_H */
+#endif /* defined(HAVE_CONFIG_H) */
 
 #include <nghttp2/nghttp2.h>
 
-#endif /* NGHTTP2_SUBMIT_H */
+#include "nghttp2_outbound_item.h"
+
+int nghttp2_submit_data_shared(nghttp2_session *session, uint8_t flags,
+                               int32_t stream_id,
+                               const nghttp2_data_provider_wrap *dpw);
+
+#endif /* !defined(NGHTTP2_SUBMIT_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_time.c b/Utilities/cmnghttp2/lib/nghttp2_time.c
new file mode 100644
index 0000000..18fd7bc
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/nghttp2_time.c
@@ -0,0 +1,62 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2023 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.
+ */
+#include "nghttp2_time.h"
+
+#ifdef HAVE_WINDOWS_H
+#  include <windows.h>
+#endif /* defined(HAVE_WINDOWS_H) */
+
+#include <time.h>
+
+#if !defined(HAVE_GETTICKCOUNT64) || defined(__CYGWIN__)
+static uint64_t time_now_sec(void) {
+  time_t t = time(NULL);
+
+  if (t == -1) {
+    return 0;
+  }
+
+  return (uint64_t)t;
+}
+#endif /* !defined(HAVE_GETTICKCOUNT64) || defined(__CYGWIN__) */
+
+#if defined(HAVE_GETTICKCOUNT64) && !defined(__CYGWIN__)
+uint64_t nghttp2_time_now_sec(void) { return GetTickCount64() / 1000; }
+#elif defined(HAVE_CLOCK_GETTIME) && HAVE_DECL_CLOCK_MONOTONIC
+uint64_t nghttp2_time_now_sec(void) {
+  struct timespec tp;
+  int rv = clock_gettime(CLOCK_MONOTONIC, &tp);
+
+  if (rv == -1) {
+    return time_now_sec();
+  }
+
+  return (uint64_t)tp.tv_sec;
+}
+#else  /* (!defined(HAVE_GETTICKCOUNT64) || !defined(__CYGWIN__)) &&           \
+          (!defined(HAVE_CLOCK_GETTIME) || !HAVE_DECL_CLOCK_MONOTONIC) */
+uint64_t nghttp2_time_now_sec(void) { return time_now_sec(); }
+#endif /* (!defined(HAVE_GETTICKCOUNT64) || !defined(__CYGWIN__)) &&           \
+          (!defined(HAVE_CLOCK_GETTIME) || !HAVE_DECL_CLOCK_MONOTONIC) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_npn.h b/Utilities/cmnghttp2/lib/nghttp2_time.h
similarity index 77%
copy from Utilities/cmnghttp2/lib/nghttp2_npn.h
copy to Utilities/cmnghttp2/lib/nghttp2_time.h
index c6f1c04..a91e62a 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_npn.h
+++ b/Utilities/cmnghttp2/lib/nghttp2_time.h
@@ -1,7 +1,7 @@
 /*
  * nghttp2 - HTTP/2 C Library
  *
- * Copyright (c) 2012 Tatsuhiro Tsujikawa
+ * Copyright (c) 2023 nghttp2 contributors
  *
  * Permission is hereby granted, free of charge, to any person obtaining
  * a copy of this software and associated documentation files (the
@@ -22,13 +22,17 @@
  * 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
+#ifndef NGHTTP2_TIME_H
+#define NGHTTP2_TIME_H
 
 #ifdef HAVE_CONFIG_H
 #  include <config.h>
-#endif /* HAVE_CONFIG_H */
+#endif /* defined(HAVE_CONFIG_H) */
 
 #include <nghttp2/nghttp2.h>
 
-#endif /* NGHTTP2_NPN_H */
+/* nghttp2_time_now_sec returns seconds from implementation-specific
+   timepoint.  If it is unable to get seconds, it returns 0. */
+uint64_t nghttp2_time_now_sec(void);
+
+#endif /* !defined(NGHTTP2_TIME_H) */
diff --git a/Utilities/cmnghttp2/lib/nghttp2_version.c b/Utilities/cmnghttp2/lib/nghttp2_version.c
index 4211f2c..39a49ff 100644
--- a/Utilities/cmnghttp2/lib/nghttp2_version.c
+++ b/Utilities/cmnghttp2/lib/nghttp2_version.c
@@ -24,7 +24,7 @@
  */
 #ifdef HAVE_CONFIG_H
 #  include <config.h>
-#endif /* HAVE_CONFIG_H */
+#endif /* defined(HAVE_CONFIG_H) */
 
 #include <nghttp2/nghttp2.h>
 
diff --git a/Utilities/cmnghttp2/lib/sfparse.c b/Utilities/cmnghttp2/lib/sfparse.c
new file mode 100644
index 0000000..cee089d
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/sfparse.c
@@ -0,0 +1,1787 @@
+/*
+ * sfparse
+ *
+ * Copyright (c) 2023 sfparse contributors
+ * Copyright (c) 2019 nghttp3 contributors
+ * Copyright (c) 2015 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.
+ */
+#include "sfparse.h"
+
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+
+#ifdef __AVX2__
+#  include <immintrin.h>
+#endif /* __AVX2__ */
+
+#define SFPARSE_STATE_DICT 0x08u
+#define SFPARSE_STATE_LIST 0x10u
+#define SFPARSE_STATE_ITEM 0x18u
+
+#define SFPARSE_STATE_INNER_LIST 0x04u
+
+#define SFPARSE_STATE_BEFORE 0x00u
+#define SFPARSE_STATE_BEFORE_PARAMS 0x01u
+#define SFPARSE_STATE_PARAMS 0x02u
+#define SFPARSE_STATE_AFTER 0x03u
+
+#define SFPARSE_STATE_OP_MASK 0x03u
+
+#define SFPARSE_SET_STATE_AFTER(NAME)                                          \
+  (SFPARSE_STATE_##NAME | SFPARSE_STATE_AFTER)
+#define SFPARSE_SET_STATE_BEFORE_PARAMS(NAME)                                  \
+  (SFPARSE_STATE_##NAME | SFPARSE_STATE_BEFORE_PARAMS)
+#define SFPARSE_SET_STATE_INNER_LIST_BEFORE(NAME)                              \
+  (SFPARSE_STATE_##NAME | SFPARSE_STATE_INNER_LIST | SFPARSE_STATE_BEFORE)
+
+#define SFPARSE_STATE_DICT_AFTER SFPARSE_SET_STATE_AFTER(DICT)
+#define SFPARSE_STATE_DICT_BEFORE_PARAMS SFPARSE_SET_STATE_BEFORE_PARAMS(DICT)
+#define SFPARSE_STATE_DICT_INNER_LIST_BEFORE                                   \
+  SFPARSE_SET_STATE_INNER_LIST_BEFORE(DICT)
+
+#define SFPARSE_STATE_LIST_AFTER SFPARSE_SET_STATE_AFTER(LIST)
+#define SFPARSE_STATE_LIST_BEFORE_PARAMS SFPARSE_SET_STATE_BEFORE_PARAMS(LIST)
+#define SFPARSE_STATE_LIST_INNER_LIST_BEFORE                                   \
+  SFPARSE_SET_STATE_INNER_LIST_BEFORE(LIST)
+
+#define SFPARSE_STATE_ITEM_AFTER SFPARSE_SET_STATE_AFTER(ITEM)
+#define SFPARSE_STATE_ITEM_BEFORE_PARAMS SFPARSE_SET_STATE_BEFORE_PARAMS(ITEM)
+#define SFPARSE_STATE_ITEM_INNER_LIST_BEFORE                                   \
+  SFPARSE_SET_STATE_INNER_LIST_BEFORE(ITEM)
+
+#define SFPARSE_STATE_INITIAL 0x00u
+
+#define DIGIT_CASES                                                            \
+  case '0':                                                                    \
+  case '1':                                                                    \
+  case '2':                                                                    \
+  case '3':                                                                    \
+  case '4':                                                                    \
+  case '5':                                                                    \
+  case '6':                                                                    \
+  case '7':                                                                    \
+  case '8':                                                                    \
+  case '9'
+
+#define LCALPHA_CASES                                                          \
+  case 'a':                                                                    \
+  case 'b':                                                                    \
+  case 'c':                                                                    \
+  case 'd':                                                                    \
+  case 'e':                                                                    \
+  case 'f':                                                                    \
+  case 'g':                                                                    \
+  case 'h':                                                                    \
+  case 'i':                                                                    \
+  case 'j':                                                                    \
+  case 'k':                                                                    \
+  case 'l':                                                                    \
+  case 'm':                                                                    \
+  case 'n':                                                                    \
+  case 'o':                                                                    \
+  case 'p':                                                                    \
+  case 'q':                                                                    \
+  case 'r':                                                                    \
+  case 's':                                                                    \
+  case 't':                                                                    \
+  case 'u':                                                                    \
+  case 'v':                                                                    \
+  case 'w':                                                                    \
+  case 'x':                                                                    \
+  case 'y':                                                                    \
+  case 'z'
+
+#define UCALPHA_CASES                                                          \
+  case 'A':                                                                    \
+  case 'B':                                                                    \
+  case 'C':                                                                    \
+  case 'D':                                                                    \
+  case 'E':                                                                    \
+  case 'F':                                                                    \
+  case 'G':                                                                    \
+  case 'H':                                                                    \
+  case 'I':                                                                    \
+  case 'J':                                                                    \
+  case 'K':                                                                    \
+  case 'L':                                                                    \
+  case 'M':                                                                    \
+  case 'N':                                                                    \
+  case 'O':                                                                    \
+  case 'P':                                                                    \
+  case 'Q':                                                                    \
+  case 'R':                                                                    \
+  case 'S':                                                                    \
+  case 'T':                                                                    \
+  case 'U':                                                                    \
+  case 'V':                                                                    \
+  case 'W':                                                                    \
+  case 'X':                                                                    \
+  case 'Y':                                                                    \
+  case 'Z'
+
+#define ALPHA_CASES                                                            \
+  UCALPHA_CASES:                                                               \
+  LCALPHA_CASES
+
+#define TOKEN_CASES                                                            \
+  case '!':                                                                    \
+  case '#':                                                                    \
+  case '$':                                                                    \
+  case '%':                                                                    \
+  case '&':                                                                    \
+  case '\'':                                                                   \
+  case '*':                                                                    \
+  case '+':                                                                    \
+  case '-':                                                                    \
+  case '.':                                                                    \
+  case '/':                                                                    \
+  DIGIT_CASES:                                                                 \
+  case ':':                                                                    \
+  UCALPHA_CASES:                                                               \
+  case '^':                                                                    \
+  case '_':                                                                    \
+  case '`':                                                                    \
+  LCALPHA_CASES:                                                               \
+  case '|':                                                                    \
+  case '~'
+
+#define LCHEXALPHA_CASES                                                       \
+  case 'a':                                                                    \
+  case 'b':                                                                    \
+  case 'c':                                                                    \
+  case 'd':                                                                    \
+  case 'e':                                                                    \
+  case 'f'
+
+#define X00_1F_CASES                                                           \
+  case 0x00:                                                                   \
+  case 0x01:                                                                   \
+  case 0x02:                                                                   \
+  case 0x03:                                                                   \
+  case 0x04:                                                                   \
+  case 0x05:                                                                   \
+  case 0x06:                                                                   \
+  case 0x07:                                                                   \
+  case 0x08:                                                                   \
+  case 0x09:                                                                   \
+  case 0x0a:                                                                   \
+  case 0x0b:                                                                   \
+  case 0x0c:                                                                   \
+  case 0x0d:                                                                   \
+  case 0x0e:                                                                   \
+  case 0x0f:                                                                   \
+  case 0x10:                                                                   \
+  case 0x11:                                                                   \
+  case 0x12:                                                                   \
+  case 0x13:                                                                   \
+  case 0x14:                                                                   \
+  case 0x15:                                                                   \
+  case 0x16:                                                                   \
+  case 0x17:                                                                   \
+  case 0x18:                                                                   \
+  case 0x19:                                                                   \
+  case 0x1a:                                                                   \
+  case 0x1b:                                                                   \
+  case 0x1c:                                                                   \
+  case 0x1d:                                                                   \
+  case 0x1e:                                                                   \
+  case 0x1f
+
+#define X20_21_CASES                                                           \
+  case ' ':                                                                    \
+  case '!'
+
+#define X23_5B_CASES                                                           \
+  case '#':                                                                    \
+  case '$':                                                                    \
+  case '%':                                                                    \
+  case '&':                                                                    \
+  case '\'':                                                                   \
+  case '(':                                                                    \
+  case ')':                                                                    \
+  case '*':                                                                    \
+  case '+':                                                                    \
+  case ',':                                                                    \
+  case '-':                                                                    \
+  case '.':                                                                    \
+  case '/':                                                                    \
+  DIGIT_CASES:                                                                 \
+  case ':':                                                                    \
+  case ';':                                                                    \
+  case '<':                                                                    \
+  case '=':                                                                    \
+  case '>':                                                                    \
+  case '?':                                                                    \
+  case '@':                                                                    \
+  UCALPHA_CASES:                                                               \
+  case '['
+
+#define X5D_7E_CASES                                                           \
+  case ']':                                                                    \
+  case '^':                                                                    \
+  case '_':                                                                    \
+  case '`':                                                                    \
+  LCALPHA_CASES:                                                               \
+  case '{':                                                                    \
+  case '|':                                                                    \
+  case '}':                                                                    \
+  case '~'
+
+#define X7F_FF_CASES                                                           \
+  case 0x7f:                                                                   \
+  case 0x80:                                                                   \
+  case 0x81:                                                                   \
+  case 0x82:                                                                   \
+  case 0x83:                                                                   \
+  case 0x84:                                                                   \
+  case 0x85:                                                                   \
+  case 0x86:                                                                   \
+  case 0x87:                                                                   \
+  case 0x88:                                                                   \
+  case 0x89:                                                                   \
+  case 0x8a:                                                                   \
+  case 0x8b:                                                                   \
+  case 0x8c:                                                                   \
+  case 0x8d:                                                                   \
+  case 0x8e:                                                                   \
+  case 0x8f:                                                                   \
+  case 0x90:                                                                   \
+  case 0x91:                                                                   \
+  case 0x92:                                                                   \
+  case 0x93:                                                                   \
+  case 0x94:                                                                   \
+  case 0x95:                                                                   \
+  case 0x96:                                                                   \
+  case 0x97:                                                                   \
+  case 0x98:                                                                   \
+  case 0x99:                                                                   \
+  case 0x9a:                                                                   \
+  case 0x9b:                                                                   \
+  case 0x9c:                                                                   \
+  case 0x9d:                                                                   \
+  case 0x9e:                                                                   \
+  case 0x9f:                                                                   \
+  case 0xa0:                                                                   \
+  case 0xa1:                                                                   \
+  case 0xa2:                                                                   \
+  case 0xa3:                                                                   \
+  case 0xa4:                                                                   \
+  case 0xa5:                                                                   \
+  case 0xa6:                                                                   \
+  case 0xa7:                                                                   \
+  case 0xa8:                                                                   \
+  case 0xa9:                                                                   \
+  case 0xaa:                                                                   \
+  case 0xab:                                                                   \
+  case 0xac:                                                                   \
+  case 0xad:                                                                   \
+  case 0xae:                                                                   \
+  case 0xaf:                                                                   \
+  case 0xb0:                                                                   \
+  case 0xb1:                                                                   \
+  case 0xb2:                                                                   \
+  case 0xb3:                                                                   \
+  case 0xb4:                                                                   \
+  case 0xb5:                                                                   \
+  case 0xb6:                                                                   \
+  case 0xb7:                                                                   \
+  case 0xb8:                                                                   \
+  case 0xb9:                                                                   \
+  case 0xba:                                                                   \
+  case 0xbb:                                                                   \
+  case 0xbc:                                                                   \
+  case 0xbd:                                                                   \
+  case 0xbe:                                                                   \
+  case 0xbf:                                                                   \
+  case 0xc0:                                                                   \
+  case 0xc1:                                                                   \
+  case 0xc2:                                                                   \
+  case 0xc3:                                                                   \
+  case 0xc4:                                                                   \
+  case 0xc5:                                                                   \
+  case 0xc6:                                                                   \
+  case 0xc7:                                                                   \
+  case 0xc8:                                                                   \
+  case 0xc9:                                                                   \
+  case 0xca:                                                                   \
+  case 0xcb:                                                                   \
+  case 0xcc:                                                                   \
+  case 0xcd:                                                                   \
+  case 0xce:                                                                   \
+  case 0xcf:                                                                   \
+  case 0xd0:                                                                   \
+  case 0xd1:                                                                   \
+  case 0xd2:                                                                   \
+  case 0xd3:                                                                   \
+  case 0xd4:                                                                   \
+  case 0xd5:                                                                   \
+  case 0xd6:                                                                   \
+  case 0xd7:                                                                   \
+  case 0xd8:                                                                   \
+  case 0xd9:                                                                   \
+  case 0xda:                                                                   \
+  case 0xdb:                                                                   \
+  case 0xdc:                                                                   \
+  case 0xdd:                                                                   \
+  case 0xde:                                                                   \
+  case 0xdf:                                                                   \
+  case 0xe0:                                                                   \
+  case 0xe1:                                                                   \
+  case 0xe2:                                                                   \
+  case 0xe3:                                                                   \
+  case 0xe4:                                                                   \
+  case 0xe5:                                                                   \
+  case 0xe6:                                                                   \
+  case 0xe7:                                                                   \
+  case 0xe8:                                                                   \
+  case 0xe9:                                                                   \
+  case 0xea:                                                                   \
+  case 0xeb:                                                                   \
+  case 0xec:                                                                   \
+  case 0xed:                                                                   \
+  case 0xee:                                                                   \
+  case 0xef:                                                                   \
+  case 0xf0:                                                                   \
+  case 0xf1:                                                                   \
+  case 0xf2:                                                                   \
+  case 0xf3:                                                                   \
+  case 0xf4:                                                                   \
+  case 0xf5:                                                                   \
+  case 0xf6:                                                                   \
+  case 0xf7:                                                                   \
+  case 0xf8:                                                                   \
+  case 0xf9:                                                                   \
+  case 0xfa:                                                                   \
+  case 0xfb:                                                                   \
+  case 0xfc:                                                                   \
+  case 0xfd:                                                                   \
+  case 0xfe:                                                                   \
+  case 0xff
+
+static int is_ws(uint8_t c) {
+  switch (c) {
+  case ' ':
+  case '\t':
+    return 1;
+  default:
+    return 0;
+  }
+}
+
+#ifdef __AVX2__
+#  ifdef _MSC_VER
+#    include <intrin.h>
+
+static int ctz(unsigned int v) {
+  unsigned long n;
+
+  /* Assume that v is not 0. */
+  _BitScanForward(&n, v);
+
+  return (int)n;
+}
+#  else /* !_MSC_VER */
+#    define ctz __builtin_ctz
+#  endif /* !_MSC_VER */
+#endif   /* __AVX2__ */
+
+static int parser_eof(sfparse_parser *sfp) { return sfp->pos == sfp->end; }
+
+static void parser_discard_ows(sfparse_parser *sfp) {
+  for (; !parser_eof(sfp) && is_ws(*sfp->pos); ++sfp->pos)
+    ;
+}
+
+static void parser_discard_sp(sfparse_parser *sfp) {
+  for (; !parser_eof(sfp) && *sfp->pos == ' '; ++sfp->pos)
+    ;
+}
+
+static void parser_set_op_state(sfparse_parser *sfp, uint32_t op) {
+  sfp->state &= ~SFPARSE_STATE_OP_MASK;
+  sfp->state |= op;
+}
+
+static void parser_unset_inner_list_state(sfparse_parser *sfp) {
+  sfp->state &= ~SFPARSE_STATE_INNER_LIST;
+}
+
+#ifdef __AVX2__
+static const uint8_t *find_char_key(const uint8_t *first, const uint8_t *last) {
+  const __m256i us = _mm256_set1_epi8('_');
+  const __m256i ds = _mm256_set1_epi8('-');
+  const __m256i dot = _mm256_set1_epi8('.');
+  const __m256i ast = _mm256_set1_epi8('*');
+  const __m256i r0l = _mm256_set1_epi8('0' - 1);
+  const __m256i r0r = _mm256_set1_epi8('9' + 1);
+  const __m256i r1l = _mm256_set1_epi8('a' - 1);
+  const __m256i r1r = _mm256_set1_epi8('z' + 1);
+  __m256i s, x;
+  uint32_t m;
+
+  for (; first != last; first += 32) {
+    s = _mm256_loadu_si256((void *)first);
+
+    x = _mm256_cmpeq_epi8(s, us);
+    x = _mm256_or_si256(_mm256_cmpeq_epi8(s, ds), x);
+    x = _mm256_or_si256(_mm256_cmpeq_epi8(s, dot), x);
+    x = _mm256_or_si256(_mm256_cmpeq_epi8(s, ast), x);
+    x = _mm256_or_si256(
+      _mm256_and_si256(_mm256_cmpgt_epi8(s, r0l), _mm256_cmpgt_epi8(r0r, s)),
+      x);
+    x = _mm256_or_si256(
+      _mm256_and_si256(_mm256_cmpgt_epi8(s, r1l), _mm256_cmpgt_epi8(r1r, s)),
+      x);
+
+    m = ~(uint32_t)_mm256_movemask_epi8(x);
+    if (m) {
+      return first + ctz(m);
+    }
+  }
+
+  return last;
+}
+#endif /* __AVX2__ */
+
+static int parser_key(sfparse_parser *sfp, sfparse_vec *dest) {
+  const uint8_t *base;
+#ifdef __AVX2__
+  const uint8_t *last;
+#endif /* __AVX2__ */
+
+  switch (*sfp->pos) {
+  case '*':
+  LCALPHA_CASES:
+    break;
+  default:
+    return SFPARSE_ERR_PARSE;
+  }
+
+  base = sfp->pos++;
+
+#ifdef __AVX2__
+  if (sfp->end - sfp->pos >= 32) {
+    last = sfp->pos + ((sfp->end - sfp->pos) & ~0x1fu);
+
+    sfp->pos = find_char_key(sfp->pos, last);
+    if (sfp->pos != last) {
+      goto fin;
+    }
+  }
+#endif /* __AVX2__ */
+
+  for (; !parser_eof(sfp); ++sfp->pos) {
+    switch (*sfp->pos) {
+    case '_':
+    case '-':
+    case '.':
+    case '*':
+    DIGIT_CASES:
+    LCALPHA_CASES:
+      continue;
+    }
+
+    break;
+  }
+
+#ifdef __AVX2__
+fin:
+#endif /* __AVX2__ */
+  if (dest) {
+    dest->base = (uint8_t *)base;
+    dest->len = (size_t)(sfp->pos - dest->base);
+  }
+
+  return 0;
+}
+
+static int parser_number(sfparse_parser *sfp, sfparse_value *dest) {
+  int sign = 1;
+  int64_t value = 0;
+  size_t len = 0;
+  size_t fpos = 0;
+
+  if (*sfp->pos == '-') {
+    ++sfp->pos;
+    if (parser_eof(sfp)) {
+      return SFPARSE_ERR_PARSE;
+    }
+
+    sign = -1;
+  }
+
+  assert(!parser_eof(sfp));
+
+  for (; !parser_eof(sfp); ++sfp->pos) {
+    switch (*sfp->pos) {
+    DIGIT_CASES:
+      if (++len > 15) {
+        return SFPARSE_ERR_PARSE;
+      }
+
+      value *= 10;
+      value += *sfp->pos - '0';
+
+      continue;
+    }
+
+    break;
+  }
+
+  if (len == 0) {
+    return SFPARSE_ERR_PARSE;
+  }
+
+  if (parser_eof(sfp) || *sfp->pos != '.') {
+    if (dest) {
+      dest->type = SFPARSE_TYPE_INTEGER;
+      dest->flags = SFPARSE_VALUE_FLAG_NONE;
+      dest->integer = value * sign;
+    }
+
+    return 0;
+  }
+
+  /* decimal */
+
+  if (len > 12) {
+    return SFPARSE_ERR_PARSE;
+  }
+
+  fpos = len;
+
+  ++sfp->pos;
+
+  for (; !parser_eof(sfp); ++sfp->pos) {
+    switch (*sfp->pos) {
+    DIGIT_CASES:
+      if (++len > 15) {
+        return SFPARSE_ERR_PARSE;
+      }
+
+      value *= 10;
+      value += *sfp->pos - '0';
+
+      continue;
+    }
+
+    break;
+  }
+
+  if (fpos == len || len - fpos > 3) {
+    return SFPARSE_ERR_PARSE;
+  }
+
+  if (dest) {
+    dest->type = SFPARSE_TYPE_DECIMAL;
+    dest->flags = SFPARSE_VALUE_FLAG_NONE;
+    dest->decimal.numer = value * sign;
+
+    switch (len - fpos) {
+    case 1:
+      dest->decimal.denom = 10;
+
+      break;
+    case 2:
+      dest->decimal.denom = 100;
+
+      break;
+    case 3:
+      dest->decimal.denom = 1000;
+
+      break;
+    }
+  }
+
+  return 0;
+}
+
+static int parser_date(sfparse_parser *sfp, sfparse_value *dest) {
+  int rv;
+  sfparse_value val;
+
+  /* The first byte has already been validated by the caller. */
+  assert('@' == *sfp->pos);
+
+  ++sfp->pos;
+
+  if (parser_eof(sfp)) {
+    return SFPARSE_ERR_PARSE;
+  }
+
+  rv = parser_number(sfp, &val);
+  if (rv != 0) {
+    return rv;
+  }
+
+  if (val.type != SFPARSE_TYPE_INTEGER) {
+    return SFPARSE_ERR_PARSE;
+  }
+
+  if (dest) {
+    *dest = val;
+    dest->type = SFPARSE_TYPE_DATE;
+  }
+
+  return 0;
+}
+
+#ifdef __AVX2__
+static const uint8_t *find_char_string(const uint8_t *first,
+                                       const uint8_t *last) {
+  const __m256i bs = _mm256_set1_epi8('\\');
+  const __m256i dq = _mm256_set1_epi8('"');
+  const __m256i del = _mm256_set1_epi8(0x7f);
+  const __m256i sp = _mm256_set1_epi8(' ');
+  __m256i s, x;
+  uint32_t m;
+
+  for (; first != last; first += 32) {
+    s = _mm256_loadu_si256((void *)first);
+
+    x = _mm256_cmpgt_epi8(sp, s);
+    x = _mm256_or_si256(_mm256_cmpeq_epi8(s, bs), x);
+    x = _mm256_or_si256(_mm256_cmpeq_epi8(s, dq), x);
+    x = _mm256_or_si256(_mm256_cmpeq_epi8(s, del), x);
+
+    m = (uint32_t)_mm256_movemask_epi8(x);
+    if (m) {
+      return first + ctz(m);
+    }
+  }
+
+  return last;
+}
+#endif /* __AVX2__ */
+
+static int parser_string(sfparse_parser *sfp, sfparse_value *dest) {
+  const uint8_t *base;
+#ifdef __AVX2__
+  const uint8_t *last;
+#endif /* __AVX2__ */
+  uint32_t flags = SFPARSE_VALUE_FLAG_NONE;
+
+  /* The first byte has already been validated by the caller. */
+  assert('"' == *sfp->pos);
+
+  base = ++sfp->pos;
+
+#ifdef __AVX2__
+  for (; sfp->end - sfp->pos >= 32; ++sfp->pos) {
+    last = sfp->pos + ((sfp->end - sfp->pos) & ~0x1fu);
+
+    sfp->pos = find_char_string(sfp->pos, last);
+    if (sfp->pos == last) {
+      break;
+    }
+
+    switch (*sfp->pos) {
+    case '\\':
+      ++sfp->pos;
+      if (parser_eof(sfp)) {
+        return SFPARSE_ERR_PARSE;
+      }
+
+      switch (*sfp->pos) {
+      case '"':
+      case '\\':
+        flags = SFPARSE_VALUE_FLAG_ESCAPED_STRING;
+
+        break;
+      default:
+        return SFPARSE_ERR_PARSE;
+      }
+
+      break;
+    case '"':
+      goto fin;
+    default:
+      return SFPARSE_ERR_PARSE;
+    }
+  }
+#endif /* __AVX2__ */
+
+  for (; !parser_eof(sfp); ++sfp->pos) {
+    switch (*sfp->pos) {
+    X20_21_CASES:
+    X23_5B_CASES:
+    X5D_7E_CASES:
+      break;
+    case '\\':
+      ++sfp->pos;
+      if (parser_eof(sfp)) {
+        return SFPARSE_ERR_PARSE;
+      }
+
+      switch (*sfp->pos) {
+      case '"':
+      case '\\':
+        flags = SFPARSE_VALUE_FLAG_ESCAPED_STRING;
+
+        break;
+      default:
+        return SFPARSE_ERR_PARSE;
+      }
+
+      break;
+    case '"':
+      goto fin;
+    default:
+      return SFPARSE_ERR_PARSE;
+    }
+  }
+
+  return SFPARSE_ERR_PARSE;
+
+fin:
+  if (dest) {
+    dest->type = SFPARSE_TYPE_STRING;
+    dest->flags = flags;
+    dest->vec.len = (size_t)(sfp->pos - base);
+    dest->vec.base = dest->vec.len == 0 ? NULL : (uint8_t *)base;
+  }
+
+  ++sfp->pos;
+
+  return 0;
+}
+
+#ifdef __AVX2__
+static const uint8_t *find_char_token(const uint8_t *first,
+                                      const uint8_t *last) {
+  /* r0: !..:, excluding "(),
+     r1: A..Z
+     r2: ^..~, excluding {} */
+  const __m256i r0l = _mm256_set1_epi8('!' - 1);
+  const __m256i r0r = _mm256_set1_epi8(':' + 1);
+  const __m256i dq = _mm256_set1_epi8('"');
+  const __m256i prl = _mm256_set1_epi8('(');
+  const __m256i prr = _mm256_set1_epi8(')');
+  const __m256i comma = _mm256_set1_epi8(',');
+  const __m256i r1l = _mm256_set1_epi8('A' - 1);
+  const __m256i r1r = _mm256_set1_epi8('Z' + 1);
+  const __m256i r2l = _mm256_set1_epi8('^' - 1);
+  const __m256i r2r = _mm256_set1_epi8('~' + 1);
+  const __m256i cbl = _mm256_set1_epi8('{');
+  const __m256i cbr = _mm256_set1_epi8('}');
+  __m256i s, x;
+  uint32_t m;
+
+  for (; first != last; first += 32) {
+    s = _mm256_loadu_si256((void *)first);
+
+    x = _mm256_andnot_si256(
+      _mm256_cmpeq_epi8(s, comma),
+      _mm256_andnot_si256(
+        _mm256_cmpeq_epi8(s, prr),
+        _mm256_andnot_si256(
+          _mm256_cmpeq_epi8(s, prl),
+          _mm256_andnot_si256(_mm256_cmpeq_epi8(s, dq),
+                              _mm256_and_si256(_mm256_cmpgt_epi8(s, r0l),
+                                               _mm256_cmpgt_epi8(r0r, s))))));
+    x = _mm256_or_si256(
+      _mm256_and_si256(_mm256_cmpgt_epi8(s, r1l), _mm256_cmpgt_epi8(r1r, s)),
+      x);
+    x = _mm256_or_si256(
+      _mm256_andnot_si256(
+        _mm256_cmpeq_epi8(s, cbr),
+        _mm256_andnot_si256(_mm256_cmpeq_epi8(s, cbl),
+                            _mm256_and_si256(_mm256_cmpgt_epi8(s, r2l),
+                                             _mm256_cmpgt_epi8(r2r, s)))),
+      x);
+
+    m = ~(uint32_t)_mm256_movemask_epi8(x);
+    if (m) {
+      return first + ctz(m);
+    }
+  }
+
+  return last;
+}
+#endif /* __AVX2__ */
+
+static int parser_token(sfparse_parser *sfp, sfparse_value *dest) {
+  const uint8_t *base;
+#ifdef __AVX2__
+  const uint8_t *last;
+#endif /* __AVX2__ */
+
+  /* The first byte has already been validated by the caller. */
+  base = sfp->pos++;
+
+#ifdef __AVX2__
+  if (sfp->end - sfp->pos >= 32) {
+    last = sfp->pos + ((sfp->end - sfp->pos) & ~0x1fu);
+
+    sfp->pos = find_char_token(sfp->pos, last);
+    if (sfp->pos != last) {
+      goto fin;
+    }
+  }
+#endif /* __AVX2__ */
+
+  for (; !parser_eof(sfp); ++sfp->pos) {
+    switch (*sfp->pos) {
+    TOKEN_CASES:
+      continue;
+    }
+
+    break;
+  }
+
+#ifdef __AVX2__
+fin:
+#endif /* __AVX2__ */
+  if (dest) {
+    dest->type = SFPARSE_TYPE_TOKEN;
+    dest->flags = SFPARSE_VALUE_FLAG_NONE;
+    dest->vec.base = (uint8_t *)base;
+    dest->vec.len = (size_t)(sfp->pos - base);
+  }
+
+  return 0;
+}
+
+#ifdef __AVX2__
+static const uint8_t *find_char_byteseq(const uint8_t *first,
+                                        const uint8_t *last) {
+  const __m256i pls = _mm256_set1_epi8('+');
+  const __m256i fs = _mm256_set1_epi8('/');
+  const __m256i r0l = _mm256_set1_epi8('0' - 1);
+  const __m256i r0r = _mm256_set1_epi8('9' + 1);
+  const __m256i r1l = _mm256_set1_epi8('A' - 1);
+  const __m256i r1r = _mm256_set1_epi8('Z' + 1);
+  const __m256i r2l = _mm256_set1_epi8('a' - 1);
+  const __m256i r2r = _mm256_set1_epi8('z' + 1);
+  __m256i s, x;
+  uint32_t m;
+
+  for (; first != last; first += 32) {
+    s = _mm256_loadu_si256((void *)first);
+
+    x = _mm256_cmpeq_epi8(s, pls);
+    x = _mm256_or_si256(_mm256_cmpeq_epi8(s, fs), x);
+    x = _mm256_or_si256(
+      _mm256_and_si256(_mm256_cmpgt_epi8(s, r0l), _mm256_cmpgt_epi8(r0r, s)),
+      x);
+    x = _mm256_or_si256(
+      _mm256_and_si256(_mm256_cmpgt_epi8(s, r1l), _mm256_cmpgt_epi8(r1r, s)),
+      x);
+    x = _mm256_or_si256(
+      _mm256_and_si256(_mm256_cmpgt_epi8(s, r2l), _mm256_cmpgt_epi8(r2r, s)),
+      x);
+
+    m = ~(uint32_t)_mm256_movemask_epi8(x);
+    if (m) {
+      return first + ctz(m);
+    }
+  }
+
+  return last;
+}
+#endif /* __AVX2__ */
+
+static int parser_byteseq(sfparse_parser *sfp, sfparse_value *dest) {
+  const uint8_t *base;
+#ifdef __AVX2__
+  const uint8_t *last;
+#endif /* __AVX2__ */
+
+  /* The first byte has already been validated by the caller. */
+  assert(':' == *sfp->pos);
+
+  base = ++sfp->pos;
+
+#ifdef __AVX2__
+  if (sfp->end - sfp->pos >= 32) {
+    last = sfp->pos + ((sfp->end - sfp->pos) & ~0x1fu);
+    sfp->pos = find_char_byteseq(sfp->pos, last);
+  }
+#endif /* __AVX2__ */
+
+  for (; !parser_eof(sfp); ++sfp->pos) {
+    switch (*sfp->pos) {
+    case '+':
+    case '/':
+    DIGIT_CASES:
+    ALPHA_CASES:
+      continue;
+    case '=':
+      switch ((sfp->pos - base) & 0x3) {
+      case 0:
+      case 1:
+        return SFPARSE_ERR_PARSE;
+      case 2:
+        ++sfp->pos;
+
+        if (parser_eof(sfp)) {
+          return SFPARSE_ERR_PARSE;
+        }
+
+        if (*sfp->pos == '=') {
+          ++sfp->pos;
+        }
+
+        break;
+      case 3:
+        ++sfp->pos;
+
+        break;
+      }
+
+      if (parser_eof(sfp) || *sfp->pos != ':') {
+        return SFPARSE_ERR_PARSE;
+      }
+
+      goto fin;
+    case ':':
+      if (((sfp->pos - base) & 0x3) == 1) {
+        return SFPARSE_ERR_PARSE;
+      }
+
+      goto fin;
+    default:
+      return SFPARSE_ERR_PARSE;
+    }
+  }
+
+  return SFPARSE_ERR_PARSE;
+
+fin:
+  if (dest) {
+    dest->type = SFPARSE_TYPE_BYTESEQ;
+    dest->flags = SFPARSE_VALUE_FLAG_NONE;
+    dest->vec.len = (size_t)(sfp->pos - base);
+    dest->vec.base = dest->vec.len == 0 ? NULL : (uint8_t *)base;
+  }
+
+  ++sfp->pos;
+
+  return 0;
+}
+
+static int parser_boolean(sfparse_parser *sfp, sfparse_value *dest) {
+  int b;
+
+  /* The first byte has already been validated by the caller. */
+  assert('?' == *sfp->pos);
+
+  ++sfp->pos;
+
+  if (parser_eof(sfp)) {
+    return SFPARSE_ERR_PARSE;
+  }
+
+  switch (*sfp->pos) {
+  case '0':
+    b = 0;
+
+    break;
+  case '1':
+    b = 1;
+
+    break;
+  default:
+    return SFPARSE_ERR_PARSE;
+  }
+
+  ++sfp->pos;
+
+  if (dest) {
+    dest->type = SFPARSE_TYPE_BOOLEAN;
+    dest->flags = SFPARSE_VALUE_FLAG_NONE;
+    dest->boolean = b;
+  }
+
+  return 0;
+}
+
+static int pctdecode(uint8_t *pc, const uint8_t **ppos) {
+  uint8_t c, b = **ppos;
+
+  switch (b) {
+  DIGIT_CASES:
+    c = (uint8_t)((b - '0') << 4);
+
+    break;
+  LCHEXALPHA_CASES:
+    c = (uint8_t)((b - 'a' + 10) << 4);
+
+    break;
+  default:
+    return -1;
+  }
+
+  b = *++*ppos;
+
+  switch (b) {
+  DIGIT_CASES:
+    c |= (uint8_t)(b - '0');
+
+    break;
+  LCHEXALPHA_CASES:
+    c |= (uint8_t)(b - 'a' + 10);
+
+    break;
+  default:
+    return -1;
+  }
+
+  *pc = c;
+  ++*ppos;
+
+  return 0;
+}
+
+/* Start of utf8 dfa */
+/* Copyright (c) 2008-2010 Bjoern Hoehrmann <bjoern@hoehrmann.de>
+ * See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details.
+ *
+ * Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>
+ *
+ * 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.
+ */
+#define UTF8_ACCEPT 0
+#define UTF8_REJECT 12
+
+/* clang-format off */
+static const uint8_t utf8d[] = {
+  /*
+   * The first part of the table maps bytes to character classes that
+   * to reduce the size of the transition table and create bitmasks.
+   */
+   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+   1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,  9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
+   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+   8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8,
+
+   /*
+    * The second part is a transition table that maps a combination
+    * of a state of the automaton and a character class to a state.
+    */
+   0,12,24,36,60,96,84,12,12,12,48,72, 12,12,12,12,12,12,12,12,12,12,12,12,
+  12, 0,12,12,12,12,12, 0,12, 0,12,12, 12,24,12,12,12,12,12,24,12,24,12,12,
+  12,12,12,12,12,12,12,24,12,12,12,12, 12,24,12,12,12,12,12,12,12,24,12,12,
+  12,12,12,12,12,12,12,36,12,36,12,12, 12,36,12,12,12,12,12,36,12,36,12,12,
+  12,36,12,12,12,12,12,12,12,12,12,12,
+};
+/* clang-format on */
+
+static void utf8_decode(uint32_t *state, uint8_t byte) {
+  *state = utf8d[256 + *state + utf8d[byte]];
+}
+
+/* End of utf8 dfa */
+
+static int parser_dispstring(sfparse_parser *sfp, sfparse_value *dest) {
+  const uint8_t *base;
+  uint8_t c;
+  uint32_t utf8state = UTF8_ACCEPT;
+
+  assert('%' == *sfp->pos);
+
+  ++sfp->pos;
+
+  if (parser_eof(sfp) || *sfp->pos != '"') {
+    return SFPARSE_ERR_PARSE;
+  }
+
+  base = ++sfp->pos;
+
+  for (; !parser_eof(sfp);) {
+    switch (*sfp->pos) {
+    X00_1F_CASES:
+    X7F_FF_CASES:
+      return SFPARSE_ERR_PARSE;
+    case '%':
+      ++sfp->pos;
+
+      if (sfp->pos + 2 > sfp->end) {
+        return SFPARSE_ERR_PARSE;
+      }
+
+      if (pctdecode(&c, &sfp->pos) != 0) {
+        return SFPARSE_ERR_PARSE;
+      }
+
+      utf8_decode(&utf8state, c);
+      if (utf8state == UTF8_REJECT) {
+        return SFPARSE_ERR_PARSE;
+      }
+
+      break;
+    case '"':
+      if (utf8state != UTF8_ACCEPT) {
+        return SFPARSE_ERR_PARSE;
+      }
+
+      if (dest) {
+        dest->type = SFPARSE_TYPE_DISPSTRING;
+        dest->flags = SFPARSE_VALUE_FLAG_NONE;
+        dest->vec.len = (size_t)(sfp->pos - base);
+        dest->vec.base = dest->vec.len == 0 ? NULL : (uint8_t *)base;
+      }
+
+      ++sfp->pos;
+
+      return 0;
+    default:
+      if (utf8state != UTF8_ACCEPT) {
+        return SFPARSE_ERR_PARSE;
+      }
+
+      ++sfp->pos;
+    }
+  }
+
+  return SFPARSE_ERR_PARSE;
+}
+
+static int parser_bare_item(sfparse_parser *sfp, sfparse_value *dest) {
+  switch (*sfp->pos) {
+  case '"':
+    return parser_string(sfp, dest);
+  case '-':
+  DIGIT_CASES:
+    return parser_number(sfp, dest);
+  case '@':
+    return parser_date(sfp, dest);
+  case ':':
+    return parser_byteseq(sfp, dest);
+  case '?':
+    return parser_boolean(sfp, dest);
+  case '*':
+  ALPHA_CASES:
+    return parser_token(sfp, dest);
+  case '%':
+    return parser_dispstring(sfp, dest);
+  default:
+    return SFPARSE_ERR_PARSE;
+  }
+}
+
+static int parser_skip_inner_list(sfparse_parser *sfp);
+
+int sfparse_parser_param(sfparse_parser *sfp, sfparse_vec *dest_key,
+                         sfparse_value *dest_value) {
+  int rv;
+
+  switch (sfp->state & SFPARSE_STATE_OP_MASK) {
+  case SFPARSE_STATE_BEFORE:
+    rv = parser_skip_inner_list(sfp);
+    if (rv != 0) {
+      return rv;
+    }
+
+    /* fall through */
+  case SFPARSE_STATE_BEFORE_PARAMS:
+    parser_set_op_state(sfp, SFPARSE_STATE_PARAMS);
+
+    break;
+  case SFPARSE_STATE_PARAMS:
+    break;
+  default:
+    assert(0);
+    abort();
+  }
+
+  if (parser_eof(sfp) || *sfp->pos != ';') {
+    parser_set_op_state(sfp, SFPARSE_STATE_AFTER);
+
+    return SFPARSE_ERR_EOF;
+  }
+
+  ++sfp->pos;
+
+  parser_discard_sp(sfp);
+  if (parser_eof(sfp)) {
+    return SFPARSE_ERR_PARSE;
+  }
+
+  rv = parser_key(sfp, dest_key);
+  if (rv != 0) {
+    return rv;
+  }
+
+  if (parser_eof(sfp) || *sfp->pos != '=') {
+    if (dest_value) {
+      dest_value->type = SFPARSE_TYPE_BOOLEAN;
+      dest_value->flags = SFPARSE_VALUE_FLAG_NONE;
+      dest_value->boolean = 1;
+    }
+
+    return 0;
+  }
+
+  ++sfp->pos;
+
+  if (parser_eof(sfp)) {
+    return SFPARSE_ERR_PARSE;
+  }
+
+  return parser_bare_item(sfp, dest_value);
+}
+
+static int parser_skip_params(sfparse_parser *sfp) {
+  int rv;
+
+  for (;;) {
+    rv = sfparse_parser_param(sfp, NULL, NULL);
+    switch (rv) {
+    case 0:
+      break;
+    case SFPARSE_ERR_EOF:
+      return 0;
+    case SFPARSE_ERR_PARSE:
+      return rv;
+    default:
+      assert(0);
+      abort();
+    }
+  }
+}
+
+int sfparse_parser_inner_list(sfparse_parser *sfp, sfparse_value *dest) {
+  int rv;
+
+  switch (sfp->state & SFPARSE_STATE_OP_MASK) {
+  case SFPARSE_STATE_BEFORE:
+    parser_discard_sp(sfp);
+    if (parser_eof(sfp)) {
+      return SFPARSE_ERR_PARSE;
+    }
+
+    break;
+  case SFPARSE_STATE_BEFORE_PARAMS:
+    rv = parser_skip_params(sfp);
+    if (rv != 0) {
+      return rv;
+    }
+
+    /* Technically, we are entering SFPARSE_STATE_AFTER, but we will set
+       another state without reading the state. */
+    /* parser_set_op_state(sfp, SFPARSE_STATE_AFTER); */
+
+    /* fall through */
+  case SFPARSE_STATE_AFTER:
+    if (parser_eof(sfp)) {
+      return SFPARSE_ERR_PARSE;
+    }
+
+    switch (*sfp->pos) {
+    case ' ':
+      parser_discard_sp(sfp);
+      if (parser_eof(sfp)) {
+        return SFPARSE_ERR_PARSE;
+      }
+
+      break;
+    case ')':
+      break;
+    default:
+      return SFPARSE_ERR_PARSE;
+    }
+
+    break;
+  default:
+    assert(0);
+    abort();
+  }
+
+  if (*sfp->pos == ')') {
+    ++sfp->pos;
+
+    parser_unset_inner_list_state(sfp);
+    parser_set_op_state(sfp, SFPARSE_STATE_BEFORE_PARAMS);
+
+    return SFPARSE_ERR_EOF;
+  }
+
+  rv = parser_bare_item(sfp, dest);
+  if (rv != 0) {
+    return rv;
+  }
+
+  parser_set_op_state(sfp, SFPARSE_STATE_BEFORE_PARAMS);
+
+  return 0;
+}
+
+static int parser_skip_inner_list(sfparse_parser *sfp) {
+  int rv;
+
+  for (;;) {
+    rv = sfparse_parser_inner_list(sfp, NULL);
+    switch (rv) {
+    case 0:
+      break;
+    case SFPARSE_ERR_EOF:
+      return 0;
+    case SFPARSE_ERR_PARSE:
+      return rv;
+    default:
+      assert(0);
+      abort();
+    }
+  }
+}
+
+static int parser_next_key_or_item(sfparse_parser *sfp) {
+  parser_discard_ows(sfp);
+
+  if (parser_eof(sfp)) {
+    return SFPARSE_ERR_EOF;
+  }
+
+  if (*sfp->pos != ',') {
+    return SFPARSE_ERR_PARSE;
+  }
+
+  ++sfp->pos;
+
+  parser_discard_ows(sfp);
+  if (parser_eof(sfp)) {
+    return SFPARSE_ERR_PARSE;
+  }
+
+  return 0;
+}
+
+static int parser_dict_value(sfparse_parser *sfp, sfparse_value *dest) {
+  int rv;
+
+  if (parser_eof(sfp) || *(sfp->pos) != '=') {
+    /* Boolean true */
+    if (dest) {
+      dest->type = SFPARSE_TYPE_BOOLEAN;
+      dest->flags = SFPARSE_VALUE_FLAG_NONE;
+      dest->boolean = 1;
+    }
+
+    sfp->state = SFPARSE_STATE_DICT_BEFORE_PARAMS;
+
+    return 0;
+  }
+
+  ++sfp->pos;
+
+  if (parser_eof(sfp)) {
+    return SFPARSE_ERR_PARSE;
+  }
+
+  if (*sfp->pos == '(') {
+    if (dest) {
+      dest->type = SFPARSE_TYPE_INNER_LIST;
+      dest->flags = SFPARSE_VALUE_FLAG_NONE;
+    }
+
+    ++sfp->pos;
+
+    sfp->state = SFPARSE_STATE_DICT_INNER_LIST_BEFORE;
+
+    return 0;
+  }
+
+  rv = parser_bare_item(sfp, dest);
+  if (rv != 0) {
+    return rv;
+  }
+
+  sfp->state = SFPARSE_STATE_DICT_BEFORE_PARAMS;
+
+  return 0;
+}
+
+int sfparse_parser_dict(sfparse_parser *sfp, sfparse_vec *dest_key,
+                        sfparse_value *dest_value) {
+  int rv;
+
+  switch (sfp->state) {
+  case SFPARSE_STATE_DICT_INNER_LIST_BEFORE:
+    rv = parser_skip_inner_list(sfp);
+    if (rv != 0) {
+      return rv;
+    }
+
+    /* fall through */
+  case SFPARSE_STATE_DICT_BEFORE_PARAMS:
+    rv = parser_skip_params(sfp);
+    if (rv != 0) {
+      return rv;
+    }
+
+    /* fall through */
+  case SFPARSE_STATE_DICT_AFTER:
+    rv = parser_next_key_or_item(sfp);
+    if (rv != 0) {
+      return rv;
+    }
+
+    break;
+  case SFPARSE_STATE_INITIAL:
+    parser_discard_sp(sfp);
+
+    if (parser_eof(sfp)) {
+      return SFPARSE_ERR_EOF;
+    }
+
+    break;
+  default:
+    assert(0);
+    abort();
+  }
+
+  rv = parser_key(sfp, dest_key);
+  if (rv != 0) {
+    return rv;
+  }
+
+  return parser_dict_value(sfp, dest_value);
+}
+
+int sfparse_parser_list(sfparse_parser *sfp, sfparse_value *dest) {
+  int rv;
+
+  switch (sfp->state) {
+  case SFPARSE_STATE_LIST_INNER_LIST_BEFORE:
+    rv = parser_skip_inner_list(sfp);
+    if (rv != 0) {
+      return rv;
+    }
+
+    /* fall through */
+  case SFPARSE_STATE_LIST_BEFORE_PARAMS:
+    rv = parser_skip_params(sfp);
+    if (rv != 0) {
+      return rv;
+    }
+
+    /* fall through */
+  case SFPARSE_STATE_LIST_AFTER:
+    rv = parser_next_key_or_item(sfp);
+    if (rv != 0) {
+      return rv;
+    }
+
+    break;
+  case SFPARSE_STATE_INITIAL:
+    parser_discard_sp(sfp);
+
+    if (parser_eof(sfp)) {
+      return SFPARSE_ERR_EOF;
+    }
+
+    break;
+  default:
+    assert(0);
+    abort();
+  }
+
+  if (*sfp->pos == '(') {
+    if (dest) {
+      dest->type = SFPARSE_TYPE_INNER_LIST;
+      dest->flags = SFPARSE_VALUE_FLAG_NONE;
+    }
+
+    ++sfp->pos;
+
+    sfp->state = SFPARSE_STATE_LIST_INNER_LIST_BEFORE;
+
+    return 0;
+  }
+
+  rv = parser_bare_item(sfp, dest);
+  if (rv != 0) {
+    return rv;
+  }
+
+  sfp->state = SFPARSE_STATE_LIST_BEFORE_PARAMS;
+
+  return 0;
+}
+
+int sfparse_parser_item(sfparse_parser *sfp, sfparse_value *dest) {
+  int rv;
+
+  switch (sfp->state) {
+  case SFPARSE_STATE_INITIAL:
+    parser_discard_sp(sfp);
+
+    if (parser_eof(sfp)) {
+      return SFPARSE_ERR_PARSE;
+    }
+
+    break;
+  case SFPARSE_STATE_ITEM_INNER_LIST_BEFORE:
+    rv = parser_skip_inner_list(sfp);
+    if (rv != 0) {
+      return rv;
+    }
+
+    /* fall through */
+  case SFPARSE_STATE_ITEM_BEFORE_PARAMS:
+    rv = parser_skip_params(sfp);
+    if (rv != 0) {
+      return rv;
+    }
+
+    /* fall through */
+  case SFPARSE_STATE_ITEM_AFTER:
+    parser_discard_sp(sfp);
+
+    if (!parser_eof(sfp)) {
+      return SFPARSE_ERR_PARSE;
+    }
+
+    return SFPARSE_ERR_EOF;
+  default:
+    assert(0);
+    abort();
+  }
+
+  if (*sfp->pos == '(') {
+    if (dest) {
+      dest->type = SFPARSE_TYPE_INNER_LIST;
+      dest->flags = SFPARSE_VALUE_FLAG_NONE;
+    }
+
+    ++sfp->pos;
+
+    sfp->state = SFPARSE_STATE_ITEM_INNER_LIST_BEFORE;
+
+    return 0;
+  }
+
+  rv = parser_bare_item(sfp, dest);
+  if (rv != 0) {
+    return rv;
+  }
+
+  sfp->state = SFPARSE_STATE_ITEM_BEFORE_PARAMS;
+
+  return 0;
+}
+
+void sfparse_parser_init(sfparse_parser *sfp, const uint8_t *data,
+                         size_t datalen) {
+  if (datalen == 0) {
+    sfp->pos = sfp->end = NULL;
+  } else {
+    sfp->pos = data;
+    sfp->end = data + datalen;
+  }
+
+  sfp->state = SFPARSE_STATE_INITIAL;
+}
+
+void sfparse_unescape(sfparse_vec *dest, const sfparse_vec *src) {
+  const uint8_t *p, *q;
+  uint8_t *o;
+  size_t len, slen;
+
+  if (src->len == 0) {
+    dest->len = 0;
+
+    return;
+  }
+
+  o = dest->base;
+  p = src->base;
+  len = src->len;
+
+  for (;;) {
+    q = memchr(p, '\\', len);
+    if (q == NULL) {
+      memcpy(o, p, len);
+      o += len;
+
+      dest->len = (size_t)(o - dest->base);
+
+      return;
+    }
+
+    slen = (size_t)(q - p);
+    memcpy(o, p, slen);
+    o += slen;
+
+    p = q + 1;
+    *o++ = *p++;
+    len -= slen + 2;
+  }
+}
+
+void sfparse_base64decode(sfparse_vec *dest, const sfparse_vec *src) {
+  static const int index_tbl[] = {
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+    -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60,
+    61, -1, -1, -1, -1, -1, -1, -1, 0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10,
+    11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1,
+    -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
+    43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+    -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+    -1, -1, -1, -1, -1, -1, -1, -1, -1};
+  uint8_t *o;
+  const uint8_t *p, *end;
+  uint32_t n;
+  size_t i, left;
+  int idx;
+
+  if (src->len == 0) {
+    dest->len = 0;
+
+    return;
+  }
+
+  o = dest->base;
+  p = src->base;
+  left = src->len & 0x3;
+  if (left == 0 && src->base[src->len - 1] == '=') {
+    left = 4;
+  }
+  end = src->base + src->len - left;
+
+  for (; p != end;) {
+    n = 0;
+
+    for (i = 1; i <= 4; ++i, ++p) {
+      idx = index_tbl[*p];
+
+      assert(idx != -1);
+
+      n += (uint32_t)(idx << (24 - i * 6));
+    }
+
+    *o++ = (uint8_t)(n >> 16);
+    *o++ = (n >> 8) & 0xffu;
+    *o++ = n & 0xffu;
+  }
+
+  switch (left) {
+  case 0:
+    goto fin;
+  case 1:
+    assert(0);
+    abort();
+  case 3:
+    if (src->base[src->len - 1] == '=') {
+      left = 2;
+    }
+
+    break;
+  case 4:
+    assert('=' == src->base[src->len - 1]);
+
+    if (src->base[src->len - 2] == '=') {
+      left = 2;
+    } else {
+      left = 3;
+    }
+
+    break;
+  }
+
+  switch (left) {
+  case 2:
+    *o = (uint8_t)(index_tbl[*p++] << 2);
+    *o++ |= (uint8_t)(index_tbl[*p++] >> 4);
+
+    break;
+  case 3:
+    n = (uint32_t)(index_tbl[*p++] << 10);
+    n += (uint32_t)(index_tbl[*p++] << 4);
+    n += (uint32_t)(index_tbl[*p++] >> 2);
+    *o++ = (n >> 8) & 0xffu;
+    *o++ = n & 0xffu;
+
+    break;
+  }
+
+fin:
+  dest->len = (size_t)(o - dest->base);
+}
+
+void sfparse_pctdecode(sfparse_vec *dest, const sfparse_vec *src) {
+  const uint8_t *p, *q;
+  uint8_t *o;
+  size_t len, slen;
+
+  if (src->len == 0) {
+    dest->len = 0;
+
+    return;
+  }
+
+  o = dest->base;
+  p = src->base;
+  len = src->len;
+
+  for (;;) {
+    q = memchr(p, '%', len);
+    if (q == NULL) {
+      memcpy(o, p, len);
+      o += len;
+
+      dest->len = (size_t)(o - dest->base);
+
+      return;
+    }
+
+    slen = (size_t)(q - p);
+    memcpy(o, p, slen);
+    o += slen;
+
+    p = q + 1;
+
+    pctdecode(o++, &p);
+
+    len -= slen + 3;
+  }
+}
diff --git a/Utilities/cmnghttp2/lib/sfparse.h b/Utilities/cmnghttp2/lib/sfparse.h
new file mode 100644
index 0000000..9341221
--- /dev/null
+++ b/Utilities/cmnghttp2/lib/sfparse.h
@@ -0,0 +1,442 @@
+/*
+ * sfparse
+ *
+ * Copyright (c) 2023 sfparse contributors
+ * Copyright (c) 2019 nghttp3 contributors
+ * Copyright (c) 2015 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.
+ */
+#ifndef SFPARSE_H
+#define SFPARSE_H
+
+/* Define WIN32 when build target is Win32 API (borrowed from
+   libcurl) */
+#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
+#  define WIN32
+#endif /* (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) */
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* defined(__cplusplus) */
+
+#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 <stddef.h>
+
+/**
+ * @enum
+ *
+ * :type:`sfparse_type` defines value type.
+ */
+typedef enum sfparse_type {
+  /**
+   * :enum:`SFPARSE_TYPE_BOOLEAN` indicates boolean type.
+   */
+  SFPARSE_TYPE_BOOLEAN,
+  /**
+   * :enum:`SFPARSE_TYPE_INTEGER` indicates integer type.
+   */
+  SFPARSE_TYPE_INTEGER,
+  /**
+   * :enum:`SFPARSE_TYPE_DECIMAL` indicates decimal type.
+   */
+  SFPARSE_TYPE_DECIMAL,
+  /**
+   * :enum:`SFPARSE_TYPE_STRING` indicates string type.
+   */
+  SFPARSE_TYPE_STRING,
+  /**
+   * :enum:`SFPARSE_TYPE_TOKEN` indicates token type.
+   */
+  SFPARSE_TYPE_TOKEN,
+  /**
+   * :enum:`SFPARSE_TYPE_BYTESEQ` indicates byte sequence type.
+   */
+  SFPARSE_TYPE_BYTESEQ,
+  /**
+   * :enum:`SFPARSE_TYPE_INNER_LIST` indicates inner list type.
+   */
+  SFPARSE_TYPE_INNER_LIST,
+  /**
+   * :enum:`SFPARSE_TYPE_DATE` indicates date type.
+   */
+  SFPARSE_TYPE_DATE,
+  /**
+   * :enum:`SFPARSE_TYPE_DISPSTRING` indicates display string type.
+   */
+  SFPARSE_TYPE_DISPSTRING
+} sfparse_type;
+
+/**
+ * @macro
+ *
+ * :macro:`SFPARSE_ERR_PARSE` indicates fatal parse error has
+ * occurred, and it is not possible to continue the processing.
+ */
+#define SFPARSE_ERR_PARSE -1
+
+/**
+ * @macro
+ *
+ * :macro:`SFPARSE_ERR_EOF` indicates that there is nothing left to
+ * read.  The context of this error varies depending on the function
+ * that returns this error code.
+ */
+#define SFPARSE_ERR_EOF -2
+
+/**
+ * @struct
+ *
+ * :type:`sfparse_vec` stores sequence of bytes.
+ */
+typedef struct sfparse_vec {
+  /**
+   * :member:`base` points to the beginning of the sequence of bytes.
+   */
+  uint8_t *base;
+  /**
+   * :member:`len` is the number of bytes contained in this sequence.
+   */
+  size_t len;
+} sfparse_vec;
+
+/**
+ * @macro
+ *
+ * :macro:`SFPARSE_VALUE_FLAG_NONE` indicates no flag set.
+ */
+#define SFPARSE_VALUE_FLAG_NONE 0x0u
+
+/**
+ * @macro
+ *
+ * :macro:`SFPARSE_VALUE_FLAG_ESCAPED_STRING` indicates that a string
+ * contains escaped character(s).
+ */
+#define SFPARSE_VALUE_FLAG_ESCAPED_STRING 0x1u
+
+/**
+ * @struct
+ *
+ * :type:`sfparse_decimal` contains decimal value.
+ */
+typedef struct sfparse_decimal {
+  /**
+   * :member:`numer` contains numerator of the decimal value.
+   */
+  int64_t numer;
+  /**
+   * :member:`denom` contains denominator of the decimal value.
+   */
+  int64_t denom;
+} sfparse_decimal;
+
+/**
+ * @struct
+ *
+ * :type:`sfparse_value` stores a Structured Field item.  For Inner
+ * List, only type is set to
+ * :enum:`sfparse_type.SFPARSE_TYPE_INNER_LIST`.  In order to read the
+ * items contained in an inner list, call `sfparse_parser_inner_list`.
+ */
+typedef struct sfparse_value {
+  /**
+   * :member:`type` is the type of the value contained in this
+   * particular object.
+   */
+  sfparse_type type;
+  /**
+   * :member:`flags` is bitwise OR of one or more of
+   * :macro:`SFPARSE_VALUE_FLAG_* <SFPARSE_VALUE_FLAG_NONE>`.
+   */
+  uint32_t flags;
+  /**
+   * @anonunion_start
+   *
+   * @sfparse_value_value
+   */
+  union {
+    /**
+     * :member:`boolean` contains boolean value if :member:`type` ==
+     * :enum:`sfparse_type.SFPARSE_TYPE_BOOLEAN`.  1 indicates true,
+     * and 0 indicates false.
+     */
+    int boolean;
+    /**
+     * :member:`integer` contains integer value if :member:`type` is
+     * either :enum:`sfparse_type.SFPARSE_TYPE_INTEGER` or
+     * :enum:`sfparse_type.SFPARSE_TYPE_DATE`.
+     */
+    int64_t integer;
+    /**
+     * :member:`decimal` contains decimal value if :member:`type` ==
+     * :enum:`sfparse_type.SFPARSE_TYPE_DECIMAL`.
+     */
+    sfparse_decimal decimal;
+    /**
+     * :member:`vec` contains sequence of bytes if :member:`type` is
+     * either :enum:`sfparse_type.SFPARSE_TYPE_STRING`,
+     * :enum:`sfparse_type.SFPARSE_TYPE_TOKEN`,
+     * :enum:`sfparse_type.SFPARSE_TYPE_BYTESEQ`, or
+     * :enum:`sfparse_type.SFPARSE_TYPE_DISPSTRING`.
+     *
+     * For :enum:`sfparse_type.SFPARSE_TYPE_STRING`, this field
+     * contains one or more escaped characters if :member:`flags` has
+     * :macro:`SFPARSE_VALUE_FLAG_ESCAPED_STRING` set.  To unescape
+     * the string, use `sfparse_unescape`.
+     *
+     * For :enum:`sfparse_type.SFPARSE_TYPE_BYTESEQ`, this field
+     * contains base64 encoded string.  To decode this byte string,
+     * use `sfparse_base64decode`.
+     *
+     * For :enum:`sfparse_type.SFPARSE_TYPE_DISPSTRING`, this field
+     * may contain percent-encoded UTF-8 byte sequences.  To decode
+     * it, use `sfparse_pctdecode`.
+     *
+     * If :member:`vec.len <sfparse_vec.len>` == 0, :member:`vec.base
+     * <sfparse_vec.base>` is guaranteed to be NULL.
+     */
+    sfparse_vec vec;
+    /**
+     * @anonunion_end
+     */
+  };
+} sfparse_value;
+
+/**
+ * @struct
+ *
+ * :type:`sfparse_parser` is the Structured Field Values parser.  Use
+ * `sfparse_parser_init` to initialize it.
+ */
+typedef struct sfparse_parser {
+  /* all fields are private */
+  const uint8_t *pos;
+  const uint8_t *end;
+  uint32_t state;
+} sfparse_parser;
+
+/**
+ * @function
+ *
+ * `sfparse_parser_init` initializes |sfp| with the given data encoded
+ * in Structured Field Values pointed by |data| of length |datalen|.
+ */
+void sfparse_parser_init(sfparse_parser *sfp, const uint8_t *data,
+                         size_t datalen);
+
+/**
+ * @function
+ *
+ * `sfparse_parser_param` reads a parameter.  If this function returns
+ * 0, it stores parameter key and value in |dest_key| and |dest_value|
+ * respectively, if they are not NULL.
+ *
+ * This function does no effort to find duplicated keys.  Same key may
+ * be reported more than once.
+ *
+ * Caller should keep calling this function until it returns negative
+ * error code.  If it returns :macro:`SFPARSE_ERR_EOF`, all parameters
+ * have read, and caller can continue to read rest of the values.  If
+ * it returns :macro:`SFPARSE_ERR_PARSE`, it encountered fatal error
+ * while parsing field value.
+ */
+int sfparse_parser_param(sfparse_parser *sfp, sfparse_vec *dest_key,
+                         sfparse_value *dest_value);
+
+/**
+ * @function
+ *
+ * `sfparse_parser_dict` reads the next dictionary key and value pair.
+ * If this function returns 0, it stores the key and value in
+ * |dest_key| and |dest_value| respectively, if they are not NULL.
+ *
+ * Caller can optionally read parameters attached to the pair by
+ * calling `sfparse_parser_param`.
+ *
+ * This function does no effort to find duplicated keys.  Same key may
+ * be reported more than once.
+ *
+ * Caller should keep calling this function until it returns negative
+ * error code.  If it returns :macro:`SFPARSE_ERR_EOF`, all key and
+ * value pairs have been read, and there is nothing left to read.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :macro:`SFPARSE_ERR_EOF`
+ *     All values in the dictionary have read.
+ * :macro:`SFPARSE_ERR_PARSE`
+ *     It encountered fatal error while parsing field value.
+ */
+int sfparse_parser_dict(sfparse_parser *sfp, sfparse_vec *dest_key,
+                        sfparse_value *dest_value);
+
+/**
+ * @function
+ *
+ * `sfparse_parser_list` reads the next list item.  If this function
+ * returns 0, it stores the item in |dest| if it is not NULL.
+ *
+ * Caller can optionally read parameters attached to the item by
+ * calling `sfparse_parser_param`.
+ *
+ * Caller should keep calling this function until it returns negative
+ * error code.  If it returns :macro:`SFPARSE_ERR_EOF`, all values in
+ * the list have been read, and there is nothing left to read.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :macro:`SFPARSE_ERR_EOF`
+ *     All values in the list have read.
+ * :macro:`SFPARSE_ERR_PARSE`
+ *     It encountered fatal error while parsing field value.
+ */
+int sfparse_parser_list(sfparse_parser *sfp, sfparse_value *dest);
+
+/**
+ * @function
+ *
+ * `sfparse_parser_item` reads a single item.  If this function
+ * returns 0, it stores the item in |dest| if it is not NULL.
+ *
+ * This function is only used for the field value that consists of a
+ * single item.
+ *
+ * Caller can optionally read parameters attached to the item by
+ * calling `sfparse_parser_param`.
+ *
+ * Caller should call this function again to make sure that there is
+ * nothing left to read.  If this 2nd function call returns
+ * :macro:`SFPARSE_ERR_EOF`, all data have been processed
+ * successfully.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :macro:`SFPARSE_ERR_EOF`
+ *     There is nothing left to read.
+ * :macro:`SFPARSE_ERR_PARSE`
+ *     It encountered fatal error while parsing field value.
+ */
+int sfparse_parser_item(sfparse_parser *sfp, sfparse_value *dest);
+
+/**
+ * @function
+ *
+ * `sfparse_parser_inner_list` reads the next inner list item.  If
+ * this function returns 0, it stores the item in |dest| if it is not
+ * NULL.
+ *
+ * Caller can optionally read parameters attached to the item by
+ * calling `sfparse_parser_param`.
+ *
+ * Caller should keep calling this function until it returns negative
+ * error code.  If it returns :macro:`SFPARSE_ERR_EOF`, all values in
+ * this inner list have been read, and caller can optionally read
+ * parameters attached to this inner list by calling
+ * `sfparse_parser_param`.  Then caller can continue to read rest of
+ * the values.
+ *
+ * This function returns 0 if it succeeds, or one of the following
+ * negative error codes:
+ *
+ * :macro:`SFPARSE_ERR_EOF`
+ *     All values in the inner list have read.
+ * :macro:`SFPARSE_ERR_PARSE`
+ *     It encountered fatal error while parsing field value.
+ */
+int sfparse_parser_inner_list(sfparse_parser *sfp, sfparse_value *dest);
+
+/**
+ * @function
+ *
+ * `sfparse_unescape` copies |src| to |dest| by removing escapes
+ * (``\``).  |src| should be the pointer to
+ * :member:`sfparse_value.vec` of type
+ * :enum:`sfparse_type.SFPARSE_TYPE_STRING` produced by either
+ * `sfparse_parser_dict`, `sfparse_parser_list`,
+ * `sfparse_parser_inner_list`, `sfparse_parser_item`, or
+ * `sfparse_parser_param`, otherwise the behavior is undefined.
+ *
+ * :member:`dest->base <sfparse_vec.base>` must point to the buffer
+ * that has sufficient space to store the unescaped string.  The
+ * memory areas pointed by :member:`dest->base <sfparse_vec.base>` and
+ * :member:`src->base <sfparse_vec.base>` must not overlap.
+ *
+ * This function sets the length of unescaped string to
+ * :member:`dest->len <sfparse_vec.len>`.
+ */
+void sfparse_unescape(sfparse_vec *dest, const sfparse_vec *src);
+
+/**
+ * @function
+ *
+ * `sfparse_base64decode` decodes Base64 encoded string |src| and
+ * writes the result into |dest|.  |src| should be the pointer to
+ * :member:`sfparse_value.vec` of type
+ * :enum:`sfparse_type.SFPARSE_TYPE_BYTESEQ` produced by either
+ * `sfparse_parser_dict`, `sfparse_parser_list`,
+ * `sfparse_parser_inner_list`, `sfparse_parser_item`, or
+ * `sfparse_parser_param`, otherwise the behavior is undefined.
+ *
+ * :member:`dest->base <sfparse_vec.base>` must point to the buffer
+ * that has sufficient space to store the decoded byte string.
+ *
+ * This function sets the length of decoded byte string to
+ * :member:`dest->len <sfparse_vec.len>`.
+ */
+void sfparse_base64decode(sfparse_vec *dest, const sfparse_vec *src);
+
+/**
+ * @function
+ *
+ * `sfparse_pctdecode` decodes percent-encoded string |src| and writes
+ * the result into |dest|.  |src| should be the pointer to
+ * :member:`sfparse_value.vec` of type
+ * :enum:`sfparse_type.SFPARSE_TYPE_DISPSTRING` produced by either
+ * `sfparse_parser_dict`, `sfparse_parser_list`,
+ * `sfparse_parser_inner_list`, `sfparse_parser_item`, or
+ * `sfparse_parser_param`, otherwise the behavior is undefined.
+ *
+ * :member:`dest->base <sfparse_vec.base>` must point to the buffer
+ * that has sufficient space to store the decoded byte string.  The
+ * memory areas pointed by :member:`dest->base <sfparse_vec.base>` and
+ * :member:`src->base <sfparse_vec.base>` must not overlap.
+ *
+ * This function sets the length of decoded byte string to
+ * :member:`dest->len <sfparse_vec.len>`.
+ */
+void sfparse_pctdecode(sfparse_vec *dest, const sfparse_vec *src);
+
+#ifdef __cplusplus
+}
+#endif /* defined(__cplusplus) */
+
+#endif /* !defined(SFPARSE_H) */