Merge tag jbr-release-17.0.11b1207.24

JBR-7018 Rebase JBR17 on top of OpenJDK 17.0.11
JBR-6456 Sudden keyboard death on Linux using iBus.
JDK-8324241 Always record evol_method deps to avoid excessive method flushing
JBR-7020 SIGSEGV at [AGXMetalG15X_B0+0x782f54] -[AGXG15XFamilyRenderContext setFragmentBytes:length:atIndex:]+0x3c
JBR-6723 JetBrainsClient crash Java: Java2D Queue Flusher EXC_BAD_ACCESS (SIGABRT)
JBR-6911 IDE crashes (EXC_BAD_ACCESS) after disconnecting the secondary display if a markdown file is opened (macOS Sonoma 14.4.1)
JBR-5500 Freeze in Component.updateCursorImmediately
JBR-6171 Random freezes when code suggestions opens on New UI
JBR-6593 Freezes in JawsAnnouncer
JBR-6620 java/awt/GraphicsDevice/CheckDisplayModes.java: Display modes are different after test execution
JBR-6737 Cannot switch projects from Window menu after minimizing them on Linux
JBR-6742 Record resident set size in JVM fatal error log
JBR-6769 Make it possible to get info whether IDE is running in a virtual env
JBR-6771 BoxLayout throws mysterious NPEs due to previous exceptions
JBR-6847 Improve locking performance on Windows
JBR-6927 IDE is frozen right after waking from sleep with disconnected HDMI

Change-Id: Ic9bc8e1a9c3230aad93365119537d75750d0d999
diff --git a/.github/scripts/gen-test-results.sh b/.github/scripts/gen-test-results.sh
index 73edb8b..9e85eef 100644
--- a/.github/scripts/gen-test-results.sh
+++ b/.github/scripts/gen-test-results.sh
@@ -1,6 +1,6 @@
 #!/bin/bash
 #
-# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -44,8 +44,8 @@
   base_path="$(echo "$test" | tr '#' '_')"
   report_file="$report_dir/$base_path.jtr"
   hs_err_files=$(ls $report_dir/$base_path/hs_err*.log 2> /dev/null || true)
+  replay_files=$(ls $report_dir/$base_path/replay*.log 2> /dev/null || true)
   echo "####  <a id="$anchor">$test"
-
   echo '<details><summary>View test results</summary>'
   echo ''
   echo '```'
@@ -73,6 +73,20 @@
     echo ''
   fi
 
+  if [[ "$replay_files" != "" ]]; then
+    echo '<details><summary>View HotSpot replay file</summary>'
+    echo ''
+    for replay in $replay_files; do
+      echo '```'
+      echo "$replay:"
+      echo ''
+      cat "$replay"
+      echo '```'
+    done
+
+    echo '</details>'
+    echo ''
+  fi
 done >> $GITHUB_STEP_SUMMARY
 
 # With many failures, the summary can easily exceed 1024 kB, the limit set by Github
diff --git a/.github/scripts/gen-test-summary.sh b/.github/scripts/gen-test-summary.sh
index d016cb3..a612bed 100644
--- a/.github/scripts/gen-test-summary.sh
+++ b/.github/scripts/gen-test-summary.sh
@@ -42,6 +42,7 @@
 
 if [[ "$failures" = "" && "$errors" = "" ]]; then
   # We know something went wrong, but not what
+  echo 'failure=true' >> $GITHUB_OUTPUT
   echo 'error-message=Unspecified test suite failure. Please see log for job for details.' >> $GITHUB_OUTPUT
   exit 0
 fi
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 3febb11..5d91e05 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -60,7 +60,10 @@
           - 'jdk/tier1 part 3'
           - 'langtools/tier1'
           - 'hs/tier1 common'
-          - 'hs/tier1 compiler'
+          - 'hs/tier1 compiler part 1'
+          - 'hs/tier1 compiler part 2'
+          - 'hs/tier1 compiler part 3'
+          - 'hs/tier1 compiler not-xcomp'
           - 'hs/tier1 gc'
           - 'hs/tier1 runtime'
           - 'hs/tier1 serviceability'
@@ -83,8 +86,20 @@
             test-suite: 'test/hotspot/jtreg/:tier1_common'
             debug-suffix: -debug
 
-          - test-name: 'hs/tier1 compiler'
-            test-suite: 'test/hotspot/jtreg/:tier1_compiler'
+          - test-name: 'hs/tier1 compiler part 1'
+            test-suite: 'test/hotspot/jtreg/:tier1_compiler_1'
+            debug-suffix: -debug
+
+          - test-name: 'hs/tier1 compiler part 2'
+            test-suite: 'test/hotspot/jtreg/:tier1_compiler_2'
+            debug-suffix: -debug
+
+          - test-name: 'hs/tier1 compiler part 3'
+            test-suite: 'test/hotspot/jtreg/:tier1_compiler_3'
+            debug-suffix: -debug
+
+          - test-name: 'hs/tier1 compiler not-xcomp'
+            test-suite: 'test/hotspot/jtreg/:tier1_compiler_not_xcomp'
             debug-suffix: -debug
 
           - test-name: 'hs/tier1 gc'
diff --git a/.jcheck/conf b/.jcheck/conf
index a2d6545..71f8e5b 100644
--- a/.jcheck/conf
+++ b/.jcheck/conf
@@ -1,7 +1,7 @@
 [general]
 project=jdk-updates
 jbs=JDK
-version=17.0.10
+version=17.0.11
 
 [checks]
 error=author,committer,reviewers,merge,issues,executable,symlink,message,hg-tag,whitespace,problemlists
diff --git a/build.txt b/build.txt
index 35aed57..a68fdfc 100644
--- a/build.txt
+++ b/build.txt
@@ -1 +1 @@
-jbr-release-17.0.10b1207.12
+jbr-release-17.0.11b1207.24
diff --git a/doc/building.html b/doc/building.html
index 536a0d5..c18c1e8 100644
--- a/doc/building.html
+++ b/doc/building.html
@@ -175,22 +175,22 @@
 <table>
 <thead>
 <tr class="header">
-<th style="text-align: left;">Operating system</th>
-<th style="text-align: left;">Vendor/version used</th>
+<th>Operating system</th>
+<th>Vendor/version used</th>
 </tr>
 </thead>
 <tbody>
 <tr class="odd">
-<td style="text-align: left;">Linux</td>
-<td style="text-align: left;">Oracle Enterprise Linux 6.4 / 7.6</td>
+<td>Linux</td>
+<td>Oracle Enterprise Linux 6.4 / 7.6</td>
 </tr>
 <tr class="even">
-<td style="text-align: left;">macOS</td>
-<td style="text-align: left;">Mac OS X 10.13 (High Sierra)</td>
+<td>macOS</td>
+<td>Mac OS X 10.13 (High Sierra)</td>
 </tr>
 <tr class="odd">
-<td style="text-align: left;">Windows</td>
-<td style="text-align: left;">Windows Server 2012 R2</td>
+<td>Windows</td>
+<td>Windows Server 2012 R2</td>
 </tr>
 </tbody>
 </table>
@@ -545,27 +545,27 @@
 <table>
 <thead>
 <tr class="header">
-<th style="text-align: left;">Supported devkit targets</th>
+<th>Supported devkit targets</th>
 </tr>
 </thead>
 <tbody>
 <tr class="odd">
-<td style="text-align: left;">x86_64-linux-gnu</td>
+<td>x86_64-linux-gnu</td>
 </tr>
 <tr class="even">
-<td style="text-align: left;">aarch64-linux-gnu</td>
+<td>aarch64-linux-gnu</td>
 </tr>
 <tr class="odd">
-<td style="text-align: left;">arm-linux-gnueabihf</td>
+<td>arm-linux-gnueabihf</td>
 </tr>
 <tr class="even">
-<td style="text-align: left;">ppc64-linux-gnu</td>
+<td>ppc64-linux-gnu</td>
 </tr>
 <tr class="odd">
-<td style="text-align: left;">ppc64le-linux-gnu</td>
+<td>ppc64le-linux-gnu</td>
 </tr>
 <tr class="even">
-<td style="text-align: left;">s390x-linux-gnu</td>
+<td>s390x-linux-gnu</td>
 </tr>
 </tbody>
 </table>
@@ -679,103 +679,103 @@
 <table>
 <thead>
 <tr class="header">
-<th style="text-align: left;">Target</th>
-<th style="text-align: left;">Debian tree</th>
-<th style="text-align: left;">Debian arch</th>
-<th style="text-align: left;"><code>--openjdk-target=...</code></th>
+<th>Target</th>
+<th>Debian tree</th>
+<th>Debian arch</th>
+<th><code>--openjdk-target=...</code></th>
 <th><code>--with-jvm-variants=...</code></th>
 </tr>
 </thead>
 <tbody>
 <tr class="odd">
-<td style="text-align: left;">x86</td>
-<td style="text-align: left;">buster</td>
-<td style="text-align: left;">i386</td>
-<td style="text-align: left;">i386-linux-gnu</td>
+<td>x86</td>
+<td>buster</td>
+<td>i386</td>
+<td>i386-linux-gnu</td>
 <td>(all)</td>
 </tr>
 <tr class="even">
-<td style="text-align: left;">arm</td>
-<td style="text-align: left;">buster</td>
-<td style="text-align: left;">armhf</td>
-<td style="text-align: left;">arm-linux-gnueabihf</td>
+<td>arm</td>
+<td>buster</td>
+<td>armhf</td>
+<td>arm-linux-gnueabihf</td>
 <td>(all)</td>
 </tr>
 <tr class="odd">
-<td style="text-align: left;">aarch64</td>
-<td style="text-align: left;">buster</td>
-<td style="text-align: left;">arm64</td>
-<td style="text-align: left;">aarch64-linux-gnu</td>
+<td>aarch64</td>
+<td>buster</td>
+<td>arm64</td>
+<td>aarch64-linux-gnu</td>
 <td>(all)</td>
 </tr>
 <tr class="even">
-<td style="text-align: left;">ppc64le</td>
-<td style="text-align: left;">buster</td>
-<td style="text-align: left;">ppc64el</td>
-<td style="text-align: left;">powerpc64le-linux-gnu</td>
+<td>ppc64le</td>
+<td>buster</td>
+<td>ppc64el</td>
+<td>powerpc64le-linux-gnu</td>
 <td>(all)</td>
 </tr>
 <tr class="odd">
-<td style="text-align: left;">s390x</td>
-<td style="text-align: left;">buster</td>
-<td style="text-align: left;">s390x</td>
-<td style="text-align: left;">s390x-linux-gnu</td>
+<td>s390x</td>
+<td>buster</td>
+<td>s390x</td>
+<td>s390x-linux-gnu</td>
 <td>(all)</td>
 </tr>
 <tr class="even">
-<td style="text-align: left;">mipsle</td>
-<td style="text-align: left;">buster</td>
-<td style="text-align: left;">mipsel</td>
-<td style="text-align: left;">mipsel-linux-gnu</td>
+<td>mipsle</td>
+<td>buster</td>
+<td>mipsel</td>
+<td>mipsel-linux-gnu</td>
 <td>zero</td>
 </tr>
 <tr class="odd">
-<td style="text-align: left;">mips64le</td>
-<td style="text-align: left;">buster</td>
-<td style="text-align: left;">mips64el</td>
-<td style="text-align: left;">mips64el-linux-gnueabi64</td>
+<td>mips64le</td>
+<td>buster</td>
+<td>mips64el</td>
+<td>mips64el-linux-gnueabi64</td>
 <td>zero</td>
 </tr>
 <tr class="even">
-<td style="text-align: left;">armel</td>
-<td style="text-align: left;">buster</td>
-<td style="text-align: left;">arm</td>
-<td style="text-align: left;">arm-linux-gnueabi</td>
+<td>armel</td>
+<td>buster</td>
+<td>arm</td>
+<td>arm-linux-gnueabi</td>
 <td>zero</td>
 </tr>
 <tr class="odd">
-<td style="text-align: left;">ppc</td>
-<td style="text-align: left;">sid</td>
-<td style="text-align: left;">powerpc</td>
-<td style="text-align: left;">powerpc-linux-gnu</td>
+<td>ppc</td>
+<td>sid</td>
+<td>powerpc</td>
+<td>powerpc-linux-gnu</td>
 <td>zero</td>
 </tr>
 <tr class="even">
-<td style="text-align: left;">ppc64be</td>
-<td style="text-align: left;">sid</td>
-<td style="text-align: left;">ppc64</td>
-<td style="text-align: left;">powerpc64-linux-gnu</td>
+<td>ppc64be</td>
+<td>sid</td>
+<td>ppc64</td>
+<td>powerpc64-linux-gnu</td>
 <td>(all)</td>
 </tr>
 <tr class="odd">
-<td style="text-align: left;">m68k</td>
-<td style="text-align: left;">sid</td>
-<td style="text-align: left;">m68k</td>
-<td style="text-align: left;">m68k-linux-gnu</td>
+<td>m68k</td>
+<td>sid</td>
+<td>m68k</td>
+<td>m68k-linux-gnu</td>
 <td>zero</td>
 </tr>
 <tr class="even">
-<td style="text-align: left;">alpha</td>
-<td style="text-align: left;">sid</td>
-<td style="text-align: left;">alpha</td>
-<td style="text-align: left;">alpha-linux-gnu</td>
+<td>alpha</td>
+<td>sid</td>
+<td>alpha</td>
+<td>alpha-linux-gnu</td>
 <td>zero</td>
 </tr>
 <tr class="odd">
-<td style="text-align: left;">sh4</td>
-<td style="text-align: left;">sid</td>
-<td style="text-align: left;">sh4</td>
-<td style="text-align: left;">sh4-linux-gnu</td>
+<td>sh4</td>
+<td>sid</td>
+<td>sh4</td>
+<td>sh4-linux-gnu</td>
 <td>zero</td>
 </tr>
 </tbody>
diff --git a/doc/building.md b/doc/building.md
index 03549dd..307072f 100644
--- a/doc/building.md
+++ b/doc/building.md
@@ -154,11 +154,11 @@
 information is always subject to change, but this table is up to date at the
 time of writing.
 
- Operating system   Vendor/version used
- -----------------  -------------------------------------------------------
- Linux              Oracle Enterprise Linux 6.4 / 7.6
- macOS              Mac OS X 10.13 (High Sierra)
- Windows            Windows Server 2012 R2
+| Operating system  | Vendor/version used                |
+| ----------------- | ---------------------------------- |
+| Linux             | Oracle Enterprise Linux 6.4 / 7.6  |
+| macOS             | Mac OS X 10.13 (High Sierra)       |
+| Windows           | Windows Server 2012 R2             |
 
 The double version numbers for Linux are due to the hybrid model
 used at Oracle, where header files and external libraries from an older version
@@ -957,14 +957,14 @@
 targets are given, a native toolchain for the current platform will be
 created. Currently, at least the following targets are known to work:
 
- Supported devkit targets
- -------------------------
- x86_64-linux-gnu
- aarch64-linux-gnu
- arm-linux-gnueabihf
- ppc64-linux-gnu
- ppc64le-linux-gnu
- s390x-linux-gnu
+| Supported devkit targets |
+| ------------------------ |
+| x86_64-linux-gnu         |
+| aarch64-linux-gnu        |
+| arm-linux-gnueabihf      |
+| ppc64-linux-gnu          |
+| ppc64le-linux-gnu        |
+| s390x-linux-gnu          |
 
 `BASE_OS` must be one of "OEL6" for Oracle Enterprise Linux 6 or
 "Fedora" (if not specified "OEL6" will be the default). If the base OS
@@ -1184,21 +1184,21 @@
 
 Architectures that are known to successfully cross-compile like this are:
 
-  Target        Debian tree  Debian arch   `--openjdk-target=...`   `--with-jvm-variants=...`
-  ------------  ------------ ------------- ------------------------ --------------
-  x86           buster       i386          i386-linux-gnu           (all)
-  arm           buster       armhf         arm-linux-gnueabihf      (all)
-  aarch64       buster       arm64         aarch64-linux-gnu        (all)
-  ppc64le       buster       ppc64el       powerpc64le-linux-gnu    (all)
-  s390x         buster       s390x         s390x-linux-gnu          (all)
-  mipsle        buster       mipsel        mipsel-linux-gnu         zero
-  mips64le      buster       mips64el      mips64el-linux-gnueabi64 zero
-  armel         buster       arm           arm-linux-gnueabi        zero
-  ppc           sid          powerpc       powerpc-linux-gnu        zero
-  ppc64be       sid          ppc64         powerpc64-linux-gnu      (all)
-  m68k          sid          m68k          m68k-linux-gnu           zero
-  alpha         sid          alpha         alpha-linux-gnu          zero
-  sh4           sid          sh4           sh4-linux-gnu            zero
+| Target       | Debian tree  | Debian arch   | `--openjdk-target=...`   | `--with-jvm-variants=...` |
+| ------------ | ------------ | ------------- | ------------------------ | ------------------------- |
+| x86          | buster       | i386          | i386-linux-gnu           | (all)                     |
+| arm          | buster       | armhf         | arm-linux-gnueabihf      | (all)                     |
+| aarch64      | buster       | arm64         | aarch64-linux-gnu        | (all)                     |
+| ppc64le      | buster       | ppc64el       | powerpc64le-linux-gnu    | (all)                     |
+| s390x        | buster       | s390x         | s390x-linux-gnu          | (all)                     |
+| mipsle       | buster       | mipsel        | mipsel-linux-gnu         | zero                      |
+| mips64le     | buster       | mips64el      | mips64el-linux-gnueabi64 | zero                      |
+| armel        | buster       | arm           | arm-linux-gnueabi        | zero                      |
+| ppc          | sid          | powerpc       | powerpc-linux-gnu        | zero                      |
+| ppc64be      | sid          | ppc64         | powerpc64-linux-gnu      | (all)                     |
+| m68k         | sid          | m68k          | m68k-linux-gnu           | zero                      |
+| alpha        | sid          | alpha         | alpha-linux-gnu          | zero                      |
+| sh4          | sid          | sh4           | sh4-linux-gnu            | zero                      |
 
 ### Building for ARM/aarch64
 
diff --git a/make/RunTests.gmk b/make/RunTests.gmk
index 6e762cb..50984d8 100644
--- a/make/RunTests.gmk
+++ b/make/RunTests.gmk
@@ -785,8 +785,10 @@
   $1_JTREG_BASIC_OPTIONS += -e:JDK8_HOME=$$(BOOT_JDK)
   # If running on Windows, propagate the _NT_SYMBOL_PATH to enable
   # symbol lookup in hserr files
+  # The minidumps are disabled by default on client Windows, so enable them
   ifeq ($$(call isTargetOs, windows), true)
     $1_JTREG_BASIC_OPTIONS += -e:_NT_SYMBOL_PATH
+    $1_JTREG_BASIC_OPTIONS += -vmoption:-XX:+CreateCoredumpOnCrash
   endif
 
   $1_JTREG_BASIC_OPTIONS += \
@@ -855,7 +857,7 @@
 	$$(RM) -r $$($1_TEST_RESULTS_DIR)
 
   $1_COMMAND_LINE := \
-      $$(JAVA) $$($1_JTREG_LAUNCHER_OPTIONS) \
+      $$(JTREG_JAVA) $$($1_JTREG_LAUNCHER_OPTIONS) \
           -Dprogram=jtreg -jar $$(JT_HOME)/lib/jtreg.jar \
           $$($1_JTREG_BASIC_OPTIONS) \
           -testjdk:$$(JDK_UNDER_TEST) \
diff --git a/make/RunTestsPrebuilt.gmk b/make/RunTestsPrebuilt.gmk
index b3afaa7..7c1c55b 100644
--- a/make/RunTestsPrebuilt.gmk
+++ b/make/RunTestsPrebuilt.gmk
@@ -122,6 +122,7 @@
 $(eval $(call SetupVariable,JDK_IMAGE_DIR,$(OUTPUTDIR)/images/jdk))
 $(eval $(call SetupVariable,TEST_IMAGE_DIR,$(OUTPUTDIR)/images/test))
 $(eval $(call SetupVariable,SYMBOLS_IMAGE_DIR,$(OUTPUTDIR)/images/symbols,NO_CHECK))
+$(eval $(call SetupVariable,JTREG_JDK,$(BOOT_JDK)))
 
 # Provide default values for tools that we need
 $(eval $(call SetupVariable,MAKE,make,NO_CHECK))
@@ -255,6 +256,7 @@
     TOPDIR := $(TOPDIR), \
     OUTPUTDIR := $(OUTPUTDIR), \
     BOOT_JDK := $(BOOT_JDK), \
+    JTREG_JDK := $(JTREG_JDK), \
     JT_HOME := $(JT_HOME), \
     JDK_IMAGE_DIR := $(JDK_IMAGE_DIR), \
     JCOV_IMAGE_DIR := $(JCOV_IMAGE_DIR), \
diff --git a/make/RunTestsPrebuiltSpec.gmk b/make/RunTestsPrebuiltSpec.gmk
index f423fea..44c89523 100644
--- a/make/RunTestsPrebuiltSpec.gmk
+++ b/make/RunTestsPrebuiltSpec.gmk
@@ -124,6 +124,8 @@
 JLINK := $(FIXPATH) $(JLINK_CMD)
 JMOD := $(FIXPATH) $(JMOD_CMD)
 
+JTREG_JAVA := $(FIXPATH) $(JTREG_JDK)/bin/java $(JAVA_FLAGS_BIG) $(JAVA_FLAGS)
+
 BUILD_JAVA := $(JDK_IMAGE_DIR)/bin/JAVA
 ################################################################################
 # Some common tools. Assume most common name and no path.
diff --git a/make/autoconf/flags-cflags.m4 b/make/autoconf/flags-cflags.m4
index 7a57b93..ad5377b 100644
--- a/make/autoconf/flags-cflags.m4
+++ b/make/autoconf/flags-cflags.m4
@@ -171,6 +171,8 @@
       if test "x$TOOLCHAIN_VERSION" = x2017; then
         # VS2017 incorrectly triggers this warning for constexpr
         DISABLED_WARNINGS+=" 4307"
+        # VS2017 incorrectly triggers this warning for static cast (test_atomic.cpp)
+        DISABLED_WARNINGS+=" 4309"
       fi
       ;;
 
diff --git a/make/autoconf/lib-tests.m4 b/make/autoconf/lib-tests.m4
index 43ed2aa..69ea97dd 100644
--- a/make/autoconf/lib-tests.m4
+++ b/make/autoconf/lib-tests.m4
@@ -233,12 +233,47 @@
   UTIL_FIXUP_PATH(JT_HOME)
   AC_SUBST(JT_HOME)
 
+  # Specify a JDK for running jtreg. Defaults to the BOOT_JDK.
+  AC_ARG_WITH(jtreg-jdk, [AS_HELP_STRING([--with-jdk],
+    [path to JDK for running jtreg @<:@BOOT_JDK@:>@])])
+
+  AC_MSG_CHECKING([for jtreg jdk])
+  if test "x${with_jtreg_jdk}" != x; then
+    if test "x${with_jtreg_jdk}" = xno; then
+      AC_MSG_RESULT([no, jtreg jdk not specified])
+    elif test "x${with_jtreg_jdk}" = xyes; then
+      AC_MSG_RESULT([not specified])
+      AC_MSG_ERROR([--with-jtreg-jdk needs a value])
+    else
+      JTREG_JDK="${with_jtreg_jdk}"
+      AC_MSG_RESULT([$JTREG_JDK])
+      UTIL_FIXUP_PATH(JTREG_JDK)
+      if test ! -f "$JTREG_JDK/bin/java"; then
+        AC_MSG_ERROR([Could not find jtreg java at $JTREG_JDK/bin/java])
+      fi
+    fi
+  else
+    JTREG_JDK="${BOOT_JDK}"
+    AC_MSG_RESULT([no, using BOOT_JDK])
+  fi
+
+  UTIL_FIXUP_PATH(JTREG_JDK)
+  AC_SUBST([JTREG_JDK])
+  # For use in the configure script
+  JTREG_JAVA="$FIXPATH $JTREG_JDK/bin/java"
+
   # Verify jtreg version
   if test "x$JT_HOME" != x; then
+    AC_MSG_CHECKING([jtreg jar existence])
+    if test ! -f "$JT_HOME/lib/jtreg.jar"; then
+      AC_MSG_ERROR([Could not find jtreg jar at $JT_HOME/lib/jtreg.jar])
+    fi
+
     AC_MSG_CHECKING([jtreg version number])
     # jtreg -version looks like this: "jtreg 6.1+1-19"
     # Extract actual version part ("6.1" in this case)
-    jtreg_version_full=`$JAVA -jar $JT_HOME/lib/jtreg.jar -version | $HEAD -n 1 | $CUT -d ' ' -f 2`
+    jtreg_version_full=$($JTREG_JAVA -jar $JT_HOME/lib/jtreg.jar -version | $HEAD -n 1 | $CUT -d ' ' -f 2)
+
     jtreg_version=${jtreg_version_full/%+*}
     AC_MSG_RESULT([$jtreg_version])
 
diff --git a/make/autoconf/spec.gmk.in b/make/autoconf/spec.gmk.in
index 360625d..7b33cb2 100644
--- a/make/autoconf/spec.gmk.in
+++ b/make/autoconf/spec.gmk.in
@@ -676,6 +676,9 @@
 JLINK = $(JLINK_CMD)
 JMOD = $(JMOD_CMD) $(JAVA_TOOL_FLAGS_SMALL)
 
+JTREG_JDK := @JTREG_JDK@
+JTREG_JAVA = @FIXPATH@ $(JTREG_JDK)/bin/java $(JAVA_FLAGS_BIG) $(JAVA_FLAGS)
+
 BUILD_JAVA_FLAGS := @BOOTCYCLE_JVM_ARGS_BIG@
 BUILD_JAVA=@FIXPATH@ $(BUILD_JDK)/bin/java $(BUILD_JAVA_FLAGS)
 BUILD_JAVAC=@FIXPATH@ $(BUILD_JDK)/bin/javac
diff --git a/make/autoconf/toolchain.m4 b/make/autoconf/toolchain.m4
index e77476d..8105ce9 100644
--- a/make/autoconf/toolchain.m4
+++ b/make/autoconf/toolchain.m4
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -369,6 +369,10 @@
   # This is necessary since AC_PROG_CC defaults CFLAGS to "-g -O2"
   CFLAGS="$ORG_CFLAGS"
   CXXFLAGS="$ORG_CXXFLAGS"
+
+  # filter out some unwanted additions autoconf may add to CXX; we saw this on macOS with autoconf 2.72
+  UTIL_GET_NON_MATCHING_VALUES(cxx_filtered, $CXX, -std=c++11 -std=gnu++11)
+  CXX="$cxx_filtered"
 ])
 
 # Check if a compiler is of the toolchain type we expect, and save the version
diff --git a/make/autoconf/util.m4 b/make/autoconf/util.m4
index 30abe29..08d681c 100644
--- a/make/autoconf/util.m4
+++ b/make/autoconf/util.m4
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -199,7 +199,7 @@
   if test -z "$legal_values"; then
     $1="$2"
   else
-    result=`$GREP -Fvx "$legal_values" <<< "$values_to_check" | $GREP -v '^$'`
+    result=`$GREP -Fvx -- "$legal_values" <<< "$values_to_check" | $GREP -v '^$'`
     $1=${result//$'\n'/ }
   fi
 ])
@@ -226,7 +226,7 @@
   if test -z "$illegal_values"; then
     $1=""
   else
-    result=`$GREP -Fx "$illegal_values" <<< "$values_to_check" | $GREP -v '^$'`
+    result=`$GREP -Fx -- "$illegal_values" <<< "$values_to_check" | $GREP -v '^$'`
     $1=${result//$'\n'/ }
   fi
 ])
diff --git a/make/conf/version-numbers.conf b/make/conf/version-numbers.conf
index 9433c11..d71569c 100644
--- a/make/conf/version-numbers.conf
+++ b/make/conf/version-numbers.conf
@@ -28,12 +28,12 @@
 
 DEFAULT_VERSION_FEATURE=17
 DEFAULT_VERSION_INTERIM=0
-DEFAULT_VERSION_UPDATE=10
+DEFAULT_VERSION_UPDATE=11
 DEFAULT_VERSION_PATCH=0
 DEFAULT_VERSION_EXTRA1=0
 DEFAULT_VERSION_EXTRA2=0
 DEFAULT_VERSION_EXTRA3=0
-DEFAULT_VERSION_DATE=2024-01-16
+DEFAULT_VERSION_DATE=2024-04-16
 DEFAULT_VERSION_CLASSFILE_MAJOR=61  # "`$EXPR $DEFAULT_VERSION_FEATURE + 44`"
 DEFAULT_VERSION_CLASSFILE_MINOR=0
 DEFAULT_VERSION_DOCS_API_SINCE=11
diff --git a/make/data/cacerts/certainlyroote1 b/make/data/cacerts/certainlyroote1
new file mode 100644
index 0000000..3f0d0fa
--- /dev/null
+++ b/make/data/cacerts/certainlyroote1
@@ -0,0 +1,20 @@
+Owner: CN=Certainly Root E1, O=Certainly, C=US
+Issuer: CN=Certainly Root E1, O=Certainly, C=US
+Serial number: 62533b1470333275cf98d9ab9bfccf8
+Valid from: Thu Apr 01 00:00:00 GMT 2021 until: Sun Apr 01 00:00:00 GMT 2046
+Signature algorithm name: SHA384withECDSA
+Subject Public Key Algorithm: 384-bit EC (secp384r1) key
+Version: 3
+-----BEGIN CERTIFICATE-----
+MIIB9zCCAX2gAwIBAgIQBiUzsUcDMydc+Y2aub/M+DAKBggqhkjOPQQDAzA9MQsw
+CQYDVQQGEwJVUzESMBAGA1UEChMJQ2VydGFpbmx5MRowGAYDVQQDExFDZXJ0YWlu
+bHkgUm9vdCBFMTAeFw0yMTA0MDEwMDAwMDBaFw00NjA0MDEwMDAwMDBaMD0xCzAJ
+BgNVBAYTAlVTMRIwEAYDVQQKEwlDZXJ0YWlubHkxGjAYBgNVBAMTEUNlcnRhaW5s
+eSBSb290IEUxMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE3m/4fxzf7flHh4axpMCK
++IKXgOqPyEpeKn2IaKcBYhSRJHpcnqMXfYqGITQYUBsQ3tA3SybHGWCA6TS9YBk2
+QNYphwk8kXr2vBMj3VlOBF7PyAIcGFPBMdjaIOlEjeR2o0IwQDAOBgNVHQ8BAf8E
+BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU8ygYy2R17ikq6+2uI1g4
+hevIIgcwCgYIKoZIzj0EAwMDaAAwZQIxALGOWiDDshliTd6wT99u0nCK8Z9+aozm
+ut6Dacpps6kFtZaSF4fC0urQe87YQVt8rgIwRt7qy12a7DLCZRawTDBcMPPaTnOG
+BtjOiQRINzf43TNRnXCve1XYAS59BWQOhriR
+-----END CERTIFICATE-----
diff --git a/make/data/cacerts/certainlyrootr1 b/make/data/cacerts/certainlyrootr1
new file mode 100644
index 0000000..dbb99fa
--- /dev/null
+++ b/make/data/cacerts/certainlyrootr1
@@ -0,0 +1,38 @@
+Owner: CN=Certainly Root R1, O=Certainly, C=US
+Issuer: CN=Certainly Root R1, O=Certainly, C=US
+Serial number: 8e0ff94b907168653354f4d44439b7e0
+Valid from: Thu Apr 01 00:00:00 GMT 2021 until: Sun Apr 01 00:00:00 GMT 2046
+Signature algorithm name: SHA256withRSA
+Subject Public Key Algorithm: 4096-bit RSA key
+Version: 3
+-----BEGIN CERTIFICATE-----
+MIIFRzCCAy+gAwIBAgIRAI4P+UuQcWhlM1T01EQ5t+AwDQYJKoZIhvcNAQELBQAw
+PTELMAkGA1UEBhMCVVMxEjAQBgNVBAoTCUNlcnRhaW5seTEaMBgGA1UEAxMRQ2Vy
+dGFpbmx5IFJvb3QgUjEwHhcNMjEwNDAxMDAwMDAwWhcNNDYwNDAxMDAwMDAwWjA9
+MQswCQYDVQQGEwJVUzESMBAGA1UEChMJQ2VydGFpbmx5MRowGAYDVQQDExFDZXJ0
+YWlubHkgUm9vdCBSMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANA2
+1B/q3avk0bbm+yLA3RMNansiExyXPGhjZjKcA7WNpIGD2ngwEc/csiu+kr+O5MQT
+vqRoTNoCaBZ0vrLdBORrKt03H2As2/X3oXyVtwxwhi7xOu9S98zTm/mLvg7fMbed
+aFySpvXl8wo0tf97ouSHocavFwDvA5HtqRxOcT3Si2yJ9HiG5mpJoM610rCrm/b0
+1C7jcvk2xusVtyWMOvwlDbMicyF0yEqWYZL1LwsYpfSt4u5BvQF5+paMjRcCMLT5
+r3gajLQ2EBAHBXDQ9DGQilHFhiZ5shGIXsXwClTNSaa/ApzSRKft43jvRl5tcdF5
+cBxGX1HpyTfcX35pe0HfNEXgO4T0oYoKNp43zGJS4YkNKPl6I7ENPT2a/Z2B7yyQ
+wHtETrtJ4A5KVpK8y7XdeReJkd5hiXSSqOMyhb5OhaRLWcsrxXiOcVTQAjeZjOVJ
+6uBUcqQRBi8LjMFbvrWhsFNunLhgkR9Za/kt9JQKl7XsxXYDVBtlUrpMklZRNaBA
+2CnbrlJ2Oy0wQJuK0EJWtLeIAaSHO1OWzaMWj/Nmqhexx2DgwUMFDO6bW2BvBlyH
+Wyf5QBGenDPBt+U1VwV/J84XIIwc/PH72jEpSe31C4SnT8H2TsIonPru4K8H+zMR
+eiFPCyEQtkA6qyI6BJyLm4SGcprSp6XEtHWRqSsjAgMBAAGjQjBAMA4GA1UdDwEB
+/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTgqj8ljZ9EXME66C6u
+d0yEPmcM9DANBgkqhkiG9w0BAQsFAAOCAgEAuVevuBLaV4OPaAszHQNTVfSVcOQr
+PbA56/qJYv331hgELyE03fFo8NWWWt7CgKPBjcZq91l3rhVkz1t5BXdm6ozTaw3d
+8VkswTOlMIAVRQdFGjEitpIAq5lNOo93r6kiyi9jyhXWx8bwPWz8HA2YEGGeEaIi
+1wrykXprOQ4vMMM2SZ/g6Q8CRFA3lFV96p/2O7qUpUzpvD5RtOjKkjZUbVwlKNrd
+rRT90+7iIgXr0PK3aBLXWopBGsaSpVo7Y0VPv+E6dyIvXL9G+VoDhRNCX8reU9di
+taY1BMJH/5n9hN9czulegChB8n3nHpDYT3Y+gjwN/KUD+nsa2UUeYNrEjvn8K8l7
+lcUq/6qJ34IxD3L/DCfXCh5WAFAeDJDBlrXYFIW7pw0WwfgHJBu6haEaBQmAupVj
+yTrsJZ9/nbqkRxWbRHDxakvWOF5D8xh+UG7pWijmZeZ3Gzr9Hb4DJqPb1OG7fpYn
+Kx3upPvaJVQTA945xsMfTZDsjxtK0hzthZU4UHlG1sGQUDGpXJpuHfUzVounmdLy
+yCwzk5Iwx06MZTMQZBf9JBeW0Y3COmor6xOLRPIh80oat3df1+2IpHLlOR+Vnb5n
+wXARPbv0+Em34yaXOp/SX3z7wJl8OSngex2/DaeP0ik0biQVy96QXr8axGbqwua6
+OV+KmalBWQewLK8=
+-----END CERTIFICATE-----
diff --git a/make/data/charsetmapping/MS950_HKSCS.map b/make/data/charsetmapping/MS950_HKSCS.map
new file mode 100644
index 0000000..77e2f01
--- /dev/null
+++ b/make/data/charsetmapping/MS950_HKSCS.map
@@ -0,0 +1,5019 @@
+#
+#  http://www.ogcio.gov.hk/ccli/eng/hskcs/mapping_table_2008.html
+#
+#  commnent out following entries
+#
+#  88A3  <00EA,0304>
+#  88A5  <00EA,030C>
+#  8862  <00CA,0304>
+#  8864  <00CA,030C>
+#
+8740         43F0
+8741         4C32
+8742         4603
+8743         45A6
+8744         4578
+8745        27267
+8746         4D77
+8747         45B3
+8748        27CB1
+8749         4CE2
+874A        27CC5
+874B         3B95
+874C         4736
+874D         4744
+874E         4C47
+874F         4C40
+8750        242BF
+8751        23617
+8752        27352
+8753        26E8B
+8754        270D2
+8755         4C57
+8756        2A351
+8757         474F
+8758         45DA
+8759         4C85
+875A        27C6C
+875B         4D07
+875C         4AA4
+875D         46A1
+875E        26B23
+875F         7225
+8760        25A54
+8761        21A63
+8762        23E06
+8763        23F61
+8764         664D
+8765         56FB
+8767         7D95
+8768         591D
+8769        28BB9
+876A         3DF4
+876B         9734
+876C        27BEF
+876D         5BDB
+876E        21D5E
+876F         5AA4
+8770         3625
+8771        29EB0
+8772         5AD1
+8773         5BB7
+8774         5CFC
+8775         676E
+8776         8593
+8777        29945
+8778         7461
+8779         749D
+877A         3875
+877B        21D53
+877C        2369E
+877D        26021
+877E         3EEC
+87A1        258DE
+87A2         3AF5
+87A3         7AFC
+87A4         9F97
+87A5        24161
+87A6        2890D
+87A7        231EA
+87A8        20A8A
+87A9        2325E
+87AA         430A
+87AB         8484
+87AC         9F96
+87AD         942F
+87AE         4930
+87AF         8613
+87B0         5896
+87B1         974A
+87B2         9218
+87B3         79D0
+87B4         7A32
+87B5         6660
+87B6         6A29
+87B7         889D
+87B8         744C
+87B9         7BC5
+87BA         6782
+87BB         7A2C
+87BC         524F
+87BD         9046
+87BE         34E6
+87BF         73C4
+87C0        25DB9
+87C1         74C6
+87C2         9FC7
+87C3         57B3
+87C4         492F
+87C5         544C
+87C6         4131
+87C7        2368E
+87C8         5818
+87C9         7A72
+87CA        27B65
+87CB         8B8F
+87CC         46AE
+87CD        26E88
+87CE         4181
+87CF        25D99
+87D0         7BAE
+87D1        224BC
+87D2         9FC8
+87D3        224C1
+87D4        224C9
+87D5        224CC
+87D6         9FC9
+87D7         8504
+87D8        235BB
+87D9         40B4
+87DA         9FCA
+87DB         44E1
+87DC        2ADFF
+87DD         62C1
+87DE         706E
+87DF         9FCB
+8840         31C0
+8841         31C1
+8842         31C2
+8843         31C3
+8844         31C4
+8845        2010C
+8846         31C5
+8847        200D1
+8848        200CD
+8849         31C6
+884A         31C7
+884B        200CB
+884C        21FE8
+884D         31C8
+884E        200CA
+884F         31C9
+8850         31CA
+8851         31CB
+8852         31CC
+8853        2010E
+8854         31CD
+8855         31CE
+8856         0100
+8857         00C1
+8858         01CD
+8859         00C0
+885A         0112
+885B         00C9
+885C         011A
+885D         00C8
+885E         014C
+885F         00D3
+8860         01D1
+8861         00D2
+#8862  <00CA,0304>
+8863         1EBE
+#8864  <00CA,030C>
+8865         1EC0
+8866         00CA
+8867         0101
+8868         00E1
+8869         01CE
+886A         00E0
+886B         0251
+886C         0113
+886D         00E9
+886E         011B
+886F         00E8
+8870         012B
+8871         00ED
+8872         01D0
+8873         00EC
+8874         014D
+8875         00F3
+8876         01D2
+8877         00F2
+8878         016B
+8879         00FA
+887A         01D4
+887B         00F9
+887C         01D6
+887D         01D8
+887E         01DA
+88A1         01DC
+88A2         00FC
+#88A3  <00EA,0304>
+88A4         1EBF
+#88A5  <00EA,030C>
+88A6         1EC1
+88A7         00EA
+88A8         0261
+88A9         23DA
+88AA         23DB
+8940        2A3A9
+8941        21145
+8943         650A
+8946         4E3D
+8947         6EDD
+8948         9D4E
+8949         91DF
+894C        27735
+894D         6491
+894E         4F1A
+894F         4F28
+8950         4FA8
+8951         5156
+8952         5174
+8953         519C
+8954         51E4
+8955         52A1
+8956         52A8
+8957         533B
+8958         534E
+8959         53D1
+895A         53D8
+895B         56E2
+895C         58F0
+895D         5904
+895E         5907
+895F         5932
+8960         5934
+8961         5B66
+8962         5B9E
+8963         5B9F
+8964         5C9A
+8965         5E86
+8966         603B
+8967         6589
+8968         67FE
+8969         6804
+896A         6865
+896B         6D4E
+896C         70BC
+896D         7535
+896E         7EA4
+896F         7EAC
+8970         7EBA
+8971         7EC7
+8972         7ECF
+8973         7EDF
+8974         7F06
+8975         7F37
+8976         827A
+8977         82CF
+8978         836F
+8979         89C6
+897A         8BBE
+897B         8BE2
+897C         8F66
+897D         8F67
+897E         8F6E
+89A1         7411
+89A2         7CFC
+89A3         7DCD
+89A4         6946
+89A5         7AC9
+89A6         5227
+89AB         918C
+89AC         78B8
+89AD         915E
+89AE         80BC
+89B0         8D0B
+89B1         80F6
+89B2        209E7
+89B5         809F
+89B6         9EC7
+89B7         4CCD
+89B8         9DC9
+89B9         9E0C
+89BA         4C3E
+89BB        29DF6
+89BC        2700E
+89BD         9E0A
+89BE        2A133
+89BF         35C1
+89C1         6E9A
+89C2         823E
+89C3         7519
+89C5         4911
+89C6         9A6C
+89C7         9A8F
+89C8         9F99
+89C9         7987
+89CA        2846C
+89CB        21DCA
+89CC        205D0
+89CD        22AE6
+89CE         4E24
+89CF         4E81
+89D0         4E80
+89D1         4E87
+89D2         4EBF
+89D3         4EEB
+89D4         4F37
+89D5         344C
+89D6         4FBD
+89D7         3E48
+89D8         5003
+89D9         5088
+89DA         347D
+89DB         3493
+89DC         34A5
+89DD         5186
+89DE         5905
+89DF         51DB
+89E0         51FC
+89E1         5205
+89E2         4E89
+89E3         5279
+89E4         5290
+89E5         5327
+89E6         35C7
+89E7         53A9
+89E8         3551
+89E9         53B0
+89EA         3553
+89EB         53C2
+89EC         5423
+89ED         356D
+89EE         3572
+89EF         3681
+89F0         5493
+89F1         54A3
+89F2         54B4
+89F3         54B9
+89F4         54D0
+89F5         54EF
+89F6         5518
+89F7         5523
+89F8         5528
+89F9         3598
+89FA         553F
+89FB         35A5
+89FC         35BF
+89FD         55D7
+89FE         35C5
+8A40        27D84
+8A41         5525
+8A43        20C42
+8A44        20D15
+8A45        2512B
+8A46         5590
+8A47        22CC6
+8A48         39EC
+8A49        20341
+8A4A         8E46
+8A4B        24DB8
+8A4C        294E5
+8A4D         4053
+8A4E        280BE
+8A4F         777A
+8A50        22C38
+8A51         3A34
+8A52         47D5
+8A53        2815D
+8A54        269F2
+8A55        24DEA
+8A56         64DD
+8A57        20D7C
+8A58        20FB4
+8A59        20CD5
+8A5A        210F4
+8A5B         648D
+8A5C         8E7E
+8A5D        20E96
+8A5E        20C0B
+8A5F        20F64
+8A60        22CA9
+8A61        28256
+8A62        244D3
+8A64        20D46
+8A65        29A4D
+8A66        280E9
+8A67         47F4
+8A68        24EA7
+8A69        22CC2
+8A6A         9AB2
+8A6B         3A67
+8A6C        295F4
+8A6D         3FED
+8A6E         3506
+8A6F        252C7
+8A70        297D4
+8A71        278C8
+8A72        22D44
+8A73         9D6E
+8A74         9815
+8A76         43D9
+8A77        260A5
+8A78         64B4
+8A79         54E3
+8A7A        22D4C
+8A7B        22BCA
+8A7C        21077
+8A7D         39FB
+8A7E        2106F
+8AA1        266DA
+8AA2        26716
+8AA3        279A0
+8AA4         64EA
+8AA5        25052
+8AA6        20C43
+8AA7         8E68
+8AA8        221A1
+8AA9        28B4C
+8AAA        20731
+8AAC         480B
+8AAD        201A9
+8AAE         3FFA
+8AAF         5873
+8AB0        22D8D
+8AB2        245C8
+8AB3        204FC
+8AB4        26097
+8AB5        20F4C
+8AB6        20D96
+8AB7         5579
+8AB8         40BB
+8AB9         43BA
+8ABB         4AB4
+8ABC        22A66
+8ABD        2109D
+8ABE         81AA
+8ABF         98F5
+8AC0        20D9C
+8AC1         6379
+8AC2         39FE
+8AC3        22775
+8AC4         8DC0
+8AC5         56A1
+8AC6         647C
+8AC7         3E43
+8AC9        2A601
+8ACA        20E09
+8ACB        22ACF
+8ACC        22CC9
+8ACE        210C8
+8ACF        239C2
+8AD0         3992
+8AD1         3A06
+8AD2        2829B
+8AD3         3578
+8AD4        25E49
+8AD5        220C7
+8AD6         5652
+8AD7        20F31
+8AD8        22CB2
+8AD9        29720
+8ADA         34BC
+8ADB         6C3D
+8ADC        24E3B
+8ADF        27574
+8AE0        22E8B
+8AE1        22208
+8AE2        2A65B
+8AE3        28CCD
+8AE4        20E7A
+8AE5        20C34
+8AE6        2681C
+8AE7         7F93
+8AE8        210CF
+8AE9        22803
+8AEA        22939
+8AEB         35FB
+8AEC        251E3
+8AED        20E8C
+8AEE        20F8D
+8AEF        20EAA
+8AF0         3F93
+8AF1        20F30
+8AF2        20D47
+8AF3        2114F
+8AF4        20E4C
+8AF6        20EAB
+8AF7        20BA9
+8AF8        20D48
+8AF9        210C0
+8AFA        2113D
+8AFB         3FF9
+8AFC        22696
+8AFD         6432
+8AFE        20FAD
+8B40        233F4
+8B41        27639
+8B42        22BCE
+8B43        20D7E
+8B44        20D7F
+8B45        22C51
+8B46        22C55
+8B47         3A18
+8B48        20E98
+8B49        210C7
+8B4A        20F2E
+8B4B        2A632
+8B4C        26B50
+8B4D        28CD2
+8B4E        28D99
+8B4F        28CCA
+8B50         95AA
+8B51         54CC
+8B52         82C4
+8B53         55B9
+8B55        29EC3
+8B56         9C26
+8B57         9AB6
+8B58        2775E
+8B59        22DEE
+8B5A         7140
+8B5B         816D
+8B5C         80EC
+8B5D         5C1C
+8B5E        26572
+8B5F         8134
+8B60         3797
+8B61         535F
+8B62        280BD
+8B63         91B6
+8B64        20EFA
+8B65        20E0F
+8B66        20E77
+8B67        20EFB
+8B68         35DD
+8B69        24DEB
+8B6A         3609
+8B6B        20CD6
+8B6C         56AF
+8B6D        227B5
+8B6E        210C9
+8B6F        20E10
+8B70        20E78
+8B71        21078
+8B72        21148
+8B73        28207
+8B74        21455
+8B75        20E79
+8B76        24E50
+8B77        22DA4
+8B78         5A54
+8B79        2101D
+8B7A        2101E
+8B7B        210F5
+8B7C        210F6
+8B7D         579C
+8B7E        20E11
+8BA1        27694
+8BA2        282CD
+8BA3        20FB5
+8BA4        20E7B
+8BA5        2517E
+8BA6         3703
+8BA7        20FB6
+8BA8        21180
+8BA9        252D8
+8BAA        2A2BD
+8BAB        249DA
+8BAC        2183A
+8BAD        24177
+8BAE        2827C
+8BAF         5899
+8BB0         5268
+8BB1         361A
+8BB2        2573D
+8BB3         7BB2
+8BB4         5B68
+8BB5         4800
+8BB6         4B2C
+8BB7         9F27
+8BB8         49E7
+8BB9         9C1F
+8BBA         9B8D
+8BBB        25B74
+8BBC        2313D
+8BBD         55FB
+8BBE         35F2
+8BBF         5689
+8BC0         4E28
+8BC1         5902
+8BC2        21BC1
+8BC3        2F878
+8BC4         9751
+8BC5        20086
+8BC6         4E5B
+8BC7         4EBB
+8BC8         353E
+8BC9         5C23
+8BCA         5F51
+8BCB         5FC4
+8BCC         38FA
+8BCD         624C
+8BCE         6535
+8BCF         6B7A
+8BD0         6C35
+8BD1         6C3A
+8BD2         706C
+8BD3         722B
+8BD4         4E2C
+8BD5         72AD
+8BD6        248E9
+8BD7         7F52
+8BD8         793B
+8BD9         7CF9
+8BDA         7F53
+8BDB        2626A
+8BDC         34C1
+8BDE        2634B
+8BDF         8002
+8BE0         8080
+8BE1        26612
+8BE2        26951
+8BE3         535D
+8BE4         8864
+8BE5         89C1
+8BE6        278B2
+8BE7         8BA0
+8BE8         8D1D
+8BE9         9485
+8BEA         9578
+8BEB         957F
+8BEC         95E8
+8BED        28E0F
+8BEE         97E6
+8BEF         9875
+8BF0         98CE
+8BF1         98DE
+8BF2         9963
+8BF3        29810
+8BF4         9C7C
+8BF5         9E1F
+8BF6         9EC4
+8BF7         6B6F
+8BF8         F907
+8BF9         4E37
+8BFA        20087
+8BFB         961D
+8BFC         6237
+8BFD         94A2
+8C40         503B
+8C41         6DFE
+8C42        29C73
+8C43         9FA6
+8C44         3DC9
+8C45         888F
+8C46        2414E
+8C47         7077
+8C48         5CF5
+8C49         4B20
+8C4A        251CD
+8C4B         3559
+8C4C        25D30
+8C4D         6122
+8C4E        28A32
+8C4F         8FA7
+8C50         91F6
+8C51         7191
+8C52         6719
+8C53         73BA
+8C54        23281
+8C55        2A107
+8C56         3C8B
+8C57        21980
+8C58         4B10
+8C59         78E4
+8C5A         7402
+8C5B         51AE
+8C5C        2870F
+8C5D         4009
+8C5E         6A63
+8C5F        2A2BA
+8C60         4223
+8C61         860F
+8C62        20A6F
+8C63         7A2A
+8C64        29947
+8C65        28AEA
+8C66         9755
+8C67         704D
+8C68         5324
+8C69        2207E
+8C6A         93F4
+8C6B         76D9
+8C6C        289E3
+8C6D         9FA7
+8C6E         77DD
+8C6F         4EA3
+8C70         4FF0
+8C71         50BC
+8C72         4E2F
+8C73         4F17
+8C74         9FA8
+8C75         5434
+8C76         7D8B
+8C77         5892
+8C78         58D0
+8C79        21DB6
+8C7A         5E92
+8C7B         5E99
+8C7C         5FC2
+8C7D        22712
+8C7E         658B
+8CA1        233F9
+8CA2         6919
+8CA3         6A43
+8CA4        23C63
+8CA5         6CFF
+8CA7         7200
+8CA8        24505
+8CA9         738C
+8CAA         3EDB
+8CAB        24A13
+8CAC         5B15
+8CAD         74B9
+8CAE         8B83
+8CAF        25CA4
+8CB0        25695
+8CB1         7A93
+8CB2         7BEC
+8CB3         7CC3
+8CB4         7E6C
+8CB5         82F8
+8CB6         8597
+8CB7         9FA9
+8CB8         8890
+8CB9         9FAA
+8CBA         8EB9
+8CBB         9FAB
+8CBC         8FCF
+8CBD         855F
+8CBE         99E0
+8CBF         9221
+8CC0         9FAC
+8CC1        28DB9
+8CC2        2143F
+8CC3         4071
+8CC4         42A2
+8CC5         5A1A
+8CC9         9868
+8CCA         676B
+8CCB         4276
+8CCC         573D
+8CCE         85D6
+8CCF        2497B
+8CD0         82BF
+8CD1        2710D
+8CD2         4C81
+8CD3        26D74
+8CD4         5D7B
+8CD5        26B15
+8CD6        26FBE
+8CD7         9FAD
+8CD8         9FAE
+8CD9         5B96
+8CDA         9FAF
+8CDB         66E7
+8CDC         7E5B
+8CDD         6E57
+8CDE         79CA
+8CDF         3D88
+8CE0         44C3
+8CE1        23256
+8CE2        22796
+8CE3         439A
+8CE4         4536
+8CE6         5CD5
+8CE7        23B1A
+8CE8         8AF9
+8CE9         5C78
+8CEA         3D12
+8CEB        23551
+8CEC         5D78
+8CED         9FB2
+8CEE         7157
+8CEF         4558
+8CF0        240EC
+8CF1        21E23
+8CF2         4C77
+8CF3         3978
+8CF4         344A
+8CF5        201A4
+8CF6        26C41
+8CF7         8ACC
+8CF8         4FB4
+8CF9        20239
+8CFA         59BF
+8CFB         816C
+8CFC         9856
+8CFD        298FA
+8CFE         5F3B
+8D40        20B9F
+8D42        221C1
+8D43        2896D
+8D44         4102
+8D45         46BB
+8D46        29079
+8D47         3F07
+8D48         9FB3
+8D49        2A1B5
+8D4A         40F8
+8D4B         37D6
+8D4C         46F7
+8D4D        26C46
+8D4E         417C
+8D4F        286B2
+8D50        273FF
+8D51         456D
+8D52         38D4
+8D53        2549A
+8D54         4561
+8D55         451B
+8D56         4D89
+8D57         4C7B
+8D58         4D76
+8D59         45EA
+8D5A         3FC8
+8D5B        24B0F
+8D5C         3661
+8D5D         44DE
+8D5E         44BD
+8D5F         41ED
+8D60         5D3E
+8D61         5D48
+8D62         5D56
+8D63         3DFC
+8D64         380F
+8D65         5DA4
+8D66         5DB9
+8D67         3820
+8D68         3838
+8D69         5E42
+8D6A         5EBD
+8D6B         5F25
+8D6C         5F83
+8D6D         3908
+8D6E         3914
+8D6F         393F
+8D70         394D
+8D71         60D7
+8D72         613D
+8D73         5CE5
+8D74         3989
+8D75         61B7
+8D76         61B9
+8D77         61CF
+8D78         39B8
+8D79         622C
+8D7A         6290
+8D7B         62E5
+8D7C         6318
+8D7D         39F8
+8D7E         56B1
+8DA1         3A03
+8DA2         63E2
+8DA3         63FB
+8DA4         6407
+8DA5         645A
+8DA6         3A4B
+8DA7         64C0
+8DA8         5D15
+8DA9         5621
+8DAA         9F9F
+8DAB         3A97
+8DAC         6586
+8DAD         3ABD
+8DAE         65FF
+8DAF         6653
+8DB0         3AF2
+8DB1         6692
+8DB2         3B22
+8DB3         6716
+8DB4         3B42
+8DB5         67A4
+8DB6         6800
+8DB7         3B58
+8DB8         684A
+8DB9         6884
+8DBA         3B72
+8DBB         3B71
+8DBC         3B7B
+8DBD         6909
+8DBE         6943
+8DBF         725C
+8DC0         6964
+8DC1         699F
+8DC2         6985
+8DC3         3BBC
+8DC4         69D6
+8DC5         3BDD
+8DC6         6A65
+8DC7         6A74
+8DC8         6A71
+8DC9         6A82
+8DCA         3BEC
+8DCB         6A99
+8DCC         3BF2
+8DCD         6AAB
+8DCE         6AB5
+8DCF         6AD4
+8DD0         6AF6
+8DD1         6B81
+8DD2         6BC1
+8DD3         6BEA
+8DD4         6C75
+8DD5         6CAA
+8DD6         3CCB
+8DD7         6D02
+8DD8         6D06
+8DD9         6D26
+8DDA         6D81
+8DDB         3CEF
+8DDC         6DA4
+8DDD         6DB1
+8DDE         6E15
+8DDF         6E18
+8DE0         6E29
+8DE1         6E86
+8DE2        289C0
+8DE3         6EBB
+8DE4         6EE2
+8DE5         6EDA
+8DE6         9F7F
+8DE7         6EE8
+8DE8         6EE9
+8DE9         6F24
+8DEA         6F34
+8DEB         3D46
+8DEC        23F41
+8DED         6F81
+8DEE         6FBE
+8DEF         3D6A
+8DF0         3D75
+8DF1         71B7
+8DF2         5C99
+8DF3         3D8A
+8DF4         702C
+8DF5         3D91
+8DF6         7050
+8DF7         7054
+8DF8         706F
+8DF9         707F
+8DFA         7089
+8DFB        20325
+8DFC         43C1
+8DFD         35F1
+8DFE        20ED8
+8E40        23ED7
+8E41         57BE
+8E42        26ED3
+8E43         713E
+8E44        257E0
+8E45         364E
+8E46         69A2
+8E47        28BE9
+8E48         5B74
+8E49         7A49
+8E4A        258E1
+8E4B        294D9
+8E4C         7A65
+8E4D         7A7D
+8E4E        259AC
+8E4F         7ABB
+8E50         7AB0
+8E51         7AC2
+8E52         7AC3
+8E53         71D1
+8E54        2648D
+8E55         41CA
+8E56         7ADA
+8E57         7ADD
+8E58         7AEA
+8E59         41EF
+8E5A         54B2
+8E5B        25C01
+8E5C         7B0B
+8E5D         7B55
+8E5E         7B29
+8E5F        2530E
+8E60        25CFE
+8E61         7BA2
+8E62         7B6F
+8E63         839C
+8E64        25BB4
+8E65        26C7F
+8E66         7BD0
+8E67         8421
+8E68         7B92
+8E6A        25D20
+8E6B         3DAD
+8E6C        25C65
+8E6D         8492
+8E6E         7BFA
+8E70         7C35
+8E71        25CC1
+8E72         7C44
+8E73         7C83
+8E74        24882
+8E75         7CA6
+8E76         667D
+8E77        24578
+8E78         7CC9
+8E79         7CC7
+8E7A         7CE6
+8E7B         7C74
+8E7C         7CF3
+8E7D         7CF5
+8EA1         7E67
+8EA2         451D
+8EA3        26E44
+8EA4         7D5D
+8EA5        26ED6
+8EA6         748D
+8EA7         7D89
+8EA8         7DAB
+8EA9         7135
+8EAA         7DB3
+8EAC        24057
+8EAD        26029
+8EAE         7DE4
+8EAF         3D13
+8EB0         7DF5
+8EB1        217F9
+8EB2         7DE5
+8EB3        2836D
+8EB5        26121
+8EB6        2615A
+8EB7         7E6E
+8EB8         7E92
+8EB9         432B
+8EBA         946C
+8EBB         7E27
+8EBC         7F40
+8EBD         7F41
+8EBE         7F47
+8EBF         7936
+8EC0        262D0
+8EC1         99E1
+8EC2         7F97
+8EC3        26351
+8EC4         7FA3
+8EC5        21661
+8EC6        20068
+8EC7         455C
+8EC8        23766
+8EC9         4503
+8ECA        2833A
+8ECB         7FFA
+8ECC        26489
+8ECE         8008
+8ECF         801D
+8ED1         802F
+8ED2        2A087
+8ED3        26CC3
+8ED4         803B
+8ED5         803C
+8ED6         8061
+8ED7        22714
+8ED8         4989
+8ED9        26626
+8EDA        23DE3
+8EDB        266E8
+8EDC         6725
+8EDD         80A7
+8EDE        28A48
+8EDF         8107
+8EE0         811A
+8EE1         58B0
+8EE2        226F6
+8EE3         6C7F
+8EE4        26498
+8EE5        24FB8
+8EE6         64E7
+8EE7        2148A
+8EE8         8218
+8EE9        2185E
+8EEA         6A53
+8EEB        24A65
+8EEC        24A95
+8EED         447A
+8EEE         8229
+8EEF        20B0D
+8EF0        26A52
+8EF1        23D7E
+8EF2         4FF9
+8EF3        214FD
+8EF4         84E2
+8EF5         8362
+8EF6        26B0A
+8EF7        249A7
+8EF8        23530
+8EF9        21773
+8EFA        23DF8
+8EFB         82AA
+8EFC         691B
+8EFD        2F994
+8EFE         41DB
+8F40         854B
+8F41         82D0
+8F42         831A
+8F43        20E16
+8F44        217B4
+8F45         36C1
+8F46        2317D
+8F47        2355A
+8F48         827B
+8F49         82E2
+8F4A         8318
+8F4B        23E8B
+8F4C        26DA3
+8F4D        26B05
+8F4E        26B97
+8F4F        235CE
+8F50         3DBF
+8F51         831D
+8F52         55EC
+8F53         8385
+8F54         450B
+8F55        26DA5
+8F56         83AC
+8F58         83D3
+8F59         347E
+8F5A        26ED4
+8F5B         6A57
+8F5C         855A
+8F5D         3496
+8F5E        26E42
+8F5F        22EEF
+8F60         8458
+8F61        25BE4
+8F62         8471
+8F63         3DD3
+8F64         44E4
+8F65         6AA7
+8F66         844A
+8F67        23CB5
+8F68         7958
+8F6A        26B96
+8F6B        26E77
+8F6C        26E43
+8F6D         84DE
+8F6F         8391
+8F70         44A0
+8F71         8493
+8F72         84E4
+8F73        25C91
+8F74         4240
+8F75        25CC0
+8F76         4543
+8F77         8534
+8F78         5AF2
+8F79        26E99
+8F7A         4527
+8F7B         8573
+8F7C         4516
+8F7D         67BF
+8F7E         8616
+8FA1        28625
+8FA2        2863B
+8FA3         85C1
+8FA4        27088
+8FA5         8602
+8FA6        21582
+8FA7        270CD
+8FA8        2F9B2
+8FA9         456A
+8FAA         8628
+8FAB         3648
+8FAC        218A2
+8FAD         53F7
+8FAE        2739A
+8FAF         867E
+8FB0         8771
+8FB1        2A0F8
+8FB2         87EE
+8FB3        22C27
+8FB4         87B1
+8FB5         87DA
+8FB6         880F
+8FB7         5661
+8FB8         866C
+8FB9         6856
+8FBA         460F
+8FBB         8845
+8FBC         8846
+8FBD        275E0
+8FBE        23DB9
+8FBF        275E4
+8FC0         885E
+8FC1         889C
+8FC2         465B
+8FC3         88B4
+8FC4         88B5
+8FC5         63C1
+8FC6         88C5
+8FC7         7777
+8FC8        2770F
+8FC9         8987
+8FCA         898A
+8FCD         89A7
+8FCE         89BC
+8FCF        28A25
+8FD0         89E7
+8FD1        27924
+8FD2        27ABD
+8FD3         8A9C
+8FD4         7793
+8FD5         91FE
+8FD6         8A90
+8FD7        27A59
+8FD8         7AE9
+8FD9        27B3A
+8FDA        23F8F
+8FDB         4713
+8FDC        27B38
+8FDD         717C
+8FDE         8B0C
+8FDF         8B1F
+8FE0        25430
+8FE1        25565
+8FE2         8B3F
+8FE3         8B4C
+8FE4         8B4D
+8FE5         8AA9
+8FE6        24A7A
+8FE7         8B90
+8FE8         8B9B
+8FE9         8AAF
+8FEA        216DF
+8FEB         4615
+8FEC         884F
+8FED         8C9B
+8FEE        27D54
+8FEF        27D8F
+8FF0        2F9D4
+8FF1         3725
+8FF2        27D53
+8FF3         8CD6
+8FF4        27D98
+8FF5        27DBD
+8FF6         8D12
+8FF7         8D03
+8FF8        21910
+8FF9         8CDB
+8FFA         705C
+8FFB         8D11
+8FFC        24CC9
+8FFD         3ED0
+9040         8DA9
+9041        28002
+9042        21014
+9043        2498A
+9044         3B7C
+9045        281BC
+9046        2710C
+9047         7AE7
+9048         8EAD
+9049         8EB6
+904A         8EC3
+904B         92D4
+904C         8F19
+904D         8F2D
+904E        28365
+904F        28412
+9050         8FA5
+9051         9303
+9052        2A29F
+9053        20A50
+9054         8FB3
+9055         492A
+9056        289DE
+9057        2853D
+9058        23DBB
+9059         5EF8
+905A        23262
+905B         8FF9
+905C        2A014
+905D        286BC
+905E        28501
+905F        22325
+9060         3980
+9061        26ED7
+9062         9037
+9063        2853C
+9064        27ABE
+9065         9061
+9066        2856C
+9067        2860B
+9068         90A8
+9069        28713
+906A         90C4
+906B        286E6
+906C         90AE
+906E         9167
+906F         3AF0
+9070         91A9
+9071         91C4
+9072         7CAC
+9073        28933
+9074        21E89
+9075         920E
+9076         6C9F
+9077         9241
+9078         9262
+9079        255B9
+907B        28AC6
+907C        23C9B
+907D        28B0C
+907E        255DB
+90A1        20D31
+90A2         932C
+90A3         936B
+90A4        28AE1
+90A5        28BEB
+90A6         708F
+90A7         5AC3
+90A8        28AE2
+90A9        28AE5
+90AA         4965
+90AB         9244
+90AC        28BEC
+90AD        28C39
+90AE        28BFF
+90AF         9373
+90B0         945B
+90B1         8EBC
+90B2         9585
+90B3         95A6
+90B4         9426
+90B5         95A0
+90B6         6FF6
+90B7         42B9
+90B8        2267A
+90B9        286D8
+90BA        2127C
+90BB        23E2E
+90BC         49DF
+90BD         6C1C
+90BE         967B
+90BF         9696
+90C0         416C
+90C1         96A3
+90C2        26ED5
+90C3         61DA
+90C4         96B6
+90C5         78F5
+90C6        28AE0
+90C7         96BD
+90C8         53CC
+90C9         49A1
+90CA        26CB8
+90CB        20274
+90CC        26410
+90CD        290AF
+90CE        290E5
+90CF        24AD1
+90D0        21915
+90D1        2330A
+90D2         9731
+90D3         8642
+90D4         9736
+90D5         4A0F
+90D6         453D
+90D7         4585
+90D8        24AE9
+90D9         7075
+90DA         5B41
+90DB         971B
+90DD        291D5
+90DE         9757
+90DF         5B4A
+90E0        291EB
+90E1         975F
+90E2         9425
+90E3         50D0
+90E4        230B7
+90E5        230BC
+90E6         9789
+90E7         979F
+90E8         97B1
+90E9         97BE
+90EA         97C0
+90EB         97D2
+90EC         97E0
+90ED        2546C
+90EE         97EE
+90EF         741C
+90F0        29433
+90F2         97F5
+90F3        2941D
+90F4        2797A
+90F5         4AD1
+90F6         9834
+90F7         9833
+90F8         984B
+90F9         9866
+90FA         3B0E
+90FB        27175
+90FC         3D51
+90FD        20630
+90FE        2415C
+9140        25706
+9141         98CA
+9142         98B7
+9143         98C8
+9144         98C7
+9145         4AFF
+9146        26D27
+9147        216D3
+9148         55B0
+9149         98E1
+914A         98E6
+914B         98EC
+914C         9378
+914D         9939
+914E        24A29
+914F         4B72
+9150        29857
+9151        29905
+9152         99F5
+9153         9A0C
+9154         9A3B
+9155         9A10
+9156         9A58
+9157        25725
+9158         36C4
+9159        290B1
+915A        29BD5
+915B         9AE0
+915C         9AE2
+915D        29B05
+915E         9AF4
+915F         4C0E
+9160         9B14
+9161         9B2D
+9162        28600
+9163         5034
+9164         9B34
+9165        269A8
+9166         38C3
+9167        2307D
+9168         9B50
+9169         9B40
+916A        29D3E
+916B         5A45
+916C        21863
+916D         9B8E
+916E        2424B
+916F         9C02
+9170         9BFF
+9171         9C0C
+9172        29E68
+9173         9DD4
+9174        29FB7
+9175        2A192
+9176        2A1AB
+9177        2A0E1
+9178        2A123
+9179        2A1DF
+917A         9D7E
+917B         9D83
+917C        2A134
+917D         9E0E
+917E         6888
+91A1         9DC4
+91A2        2215B
+91A3        2A193
+91A4        2A220
+91A5        2193B
+91A6        2A233
+91A7         9D39
+91A8        2A0B9
+91A9        2A2B4
+91AA         9E90
+91AB         9E95
+91AC         9E9E
+91AD         9EA2
+91AE         4D34
+91AF         9EAA
+91B0         9EAF
+91B1        24364
+91B2         9EC1
+91B3         3B60
+91B4         39E5
+91B5         3D1D
+91B6         4F32
+91B7         37BE
+91B8        28C2B
+91B9         9F02
+91BA         9F08
+91BB         4B96
+91BC         9424
+91BD        26DA2
+91BE         9F17
+91C0         9F39
+91C1         569F
+91C2         568A
+91C3         9F45
+91C4         99B8
+91C5        2908B
+91C6         97F2
+91C7         847F
+91C8         9F62
+91C9         9F69
+91CA         7ADC
+91CB         9F8E
+91CC         7216
+91CD         4BBE
+91CE        24975
+91CF        249BB
+91D0         7177
+91D1        249F8
+91D2        24348
+91D3        24A51
+91D4         739E
+91D5        28BDA
+91D6        218FA
+91D7         799F
+91D8        2897E
+91D9        28E36
+91DA         9369
+91DB         93F3
+91DC        28A44
+91DD         92EC
+91DE         9381
+91DF         93CB
+91E0        2896C
+91E1        244B9
+91E2         7217
+91E3         3EEB
+91E4         7772
+91E5         7A43
+91E6         70D0
+91E7        24473
+91E8        243F8
+91E9         717E
+91EA        217EF
+91EB         70A3
+91EC        218BE
+91ED        23599
+91EE         3EC7
+91EF        21885
+91F0        2542F
+91F1        217F8
+91F2         3722
+91F3        216FB
+91F4        21839
+91F5         36E1
+91F6        21774
+91F7        218D1
+91F8        25F4B
+91F9         3723
+91FA        216C0
+91FB         575B
+91FC        24A25
+91FD        213FE
+91FE        212A8
+9240        213C6
+9241        214B6
+9242         8503
+9243        236A6
+9245         8455
+9246        24994
+9247        27165
+9248        23E31
+9249        2555C
+924A        23EFB
+924B        27052
+924C         44F4
+924D        236EE
+924E        2999D
+924F        26F26
+9250         67F9
+9251         3733
+9252         3C15
+9253         3DE7
+9254         586C
+9255        21922
+9256         6810
+9257         4057
+9258        2373F
+9259        240E1
+925A        2408B
+925B        2410F
+925C        26C21
+925D         54CB
+925E         569E
+925F        266B1
+9260         5692
+9261        20FDF
+9262        20BA8
+9263        20E0D
+9264         93C6
+9265        28B13
+9266         939C
+9267         4EF8
+9268         512B
+9269         3819
+926A        24436
+926B         4EBC
+926C        20465
+926D        2037F
+926E         4F4B
+926F         4F8A
+9270        25651
+9271         5A68
+9272        201AB
+9273        203CB
+9274         3999
+9275        2030A
+9276        20414
+9277         3435
+9278         4F29
+9279        202C0
+927A        28EB3
+927B        20275
+927C         8ADA
+927D        2020C
+927E         4E98
+92A1         50CD
+92A2         510D
+92A3         4FA2
+92A4         4F03
+92A5        24A0E
+92A6        23E8A
+92A7         4F42
+92A8         502E
+92A9         506C
+92AA         5081
+92AB         4FCC
+92AC         4FE5
+92AD         5058
+92AE         50FC
+92B3         6E76
+92B4        23595
+92B5        23E39
+92B6        23EBF
+92B7         6D72
+92B8        21884
+92B9        23E89
+92BA         51A8
+92BB         51C3
+92BC        205E0
+92BD         44DD
+92BE        204A3
+92BF        20492
+92C0        20491
+92C1         8D7A
+92C2        28A9C
+92C3        2070E
+92C4         5259
+92C5         52A4
+92C6        20873
+92C7         52E1
+92C9         467A
+92CA         718C
+92CB        2438C
+92CC        20C20
+92CD        249AC
+92CE        210E4
+92CF         69D1
+92D0        20E1D
+92D2         3EDE
+92D3         7499
+92D4         7414
+92D5         7456
+92D6         7398
+92D7         4B8E
+92D8        24ABC
+92D9        2408D
+92DA         53D0
+92DB         3584
+92DC         720F
+92DD        240C9
+92DE         55B4
+92DF        20345
+92E0         54CD
+92E1        20BC6
+92E2         571D
+92E3         925D
+92E4         96F4
+92E5         9366
+92E6         57DD
+92E7         578D
+92E8         577F
+92E9         363E
+92EA         58CB
+92EB         5A99
+92EC        28A46
+92ED        216FA
+92EE        2176F
+92EF        21710
+92F0         5A2C
+92F1         59B8
+92F2         928F
+92F3         5A7E
+92F4         5ACF
+92F5         5A12
+92F6        25946
+92F7        219F3
+92F8        21861
+92F9        24295
+92FA         36F5
+92FB         6D05
+92FC         7443
+92FD         5A21
+92FE        25E83
+9340         5A81
+9341        28BD7
+9342        20413
+9343         93E0
+9344         748C
+9345        21303
+9346         7105
+9347         4972
+9348         9408
+9349        289FB
+934A         93BD
+934B         37A0
+934C         5C1E
+934D         5C9E
+934E         5E5E
+934F         5E48
+9350        21996
+9351        2197C
+9352        23AEE
+9353         5ECD
+9354         5B4F
+9355        21903
+9356        21904
+9357         3701
+9358        218A0
+9359         36DD
+935A        216FE
+935B         36D3
+935C         812A
+935D        28A47
+935E        21DBA
+935F        23472
+9360        289A8
+9361         5F0C
+9362         5F0E
+9363        21927
+9364        217AB
+9365         5A6B
+9366        2173B
+9367         5B44
+9368         8614
+9369        275FD
+936A         8860
+936B         607E
+936C        22860
+936D        2262B
+936E         5FDB
+936F         3EB8
+9370        225AF
+9371        225BE
+9372        29088
+9373        26F73
+9374         61C0
+9375        2003E
+9376        20046
+9377        2261B
+9378         6199
+9379         6198
+937A         6075
+937B        22C9B
+937C        22D07
+937D        246D4
+937E        2914D
+93A1         6471
+93A2        24665
+93A3        22B6A
+93A4         3A29
+93A5        22B22
+93A6        23450
+93A7        298EA
+93A8        22E78
+93A9         6337
+93AA        2A45B
+93AB         64B6
+93AC         6331
+93AD         63D1
+93AE        249E3
+93AF        22D67
+93B0         62A4
+93B1        22CA1
+93B2         643B
+93B3         656B
+93B4         6972
+93B5         3BF4
+93B6        2308E
+93B7        232AD
+93B8        24989
+93B9        232AB
+93BA         550D
+93BB        232E0
+93BC        218D9
+93BD        2943F
+93BE         66CE
+93BF        23289
+93C0        231B3
+93C1         3AE0
+93C2         4190
+93C3        25584
+93C4        28B22
+93C5        2558F
+93C6        216FC
+93C7        2555B
+93C8        25425
+93C9         78EE
+93CA        23103
+93CB        2182A
+93CC        23234
+93CD         3464
+93CE        2320F
+93CF        23182
+93D0        242C9
+93D1         668E
+93D2        26D24
+93D3         666B
+93D4         4B93
+93D5         6630
+93D6        27870
+93D7        21DEB
+93D8         6663
+93D9        232D2
+93DA        232E1
+93DB         661E
+93DC        25872
+93DD         38D1
+93DE        2383A
+93DF        237BC
+93E0         3B99
+93E1        237A2
+93E2        233FE
+93E3         74D0
+93E4         3B96
+93E5         678F
+93E6        2462A
+93E7         68B6
+93E8         681E
+93E9         3BC4
+93EA         6ABE
+93EB         3863
+93EC        237D5
+93ED        24487
+93EE         6A33
+93EF         6A52
+93F0         6AC9
+93F1         6B05
+93F2        21912
+93F3         6511
+93F4         6898
+93F5         6A4C
+93F6         3BD7
+93F7         6A7A
+93F8         6B57
+93F9        23FC0
+93FA        23C9A
+93FB         93A0
+93FC         92F2
+93FD        28BEA
+93FE        28ACB
+9440         9289
+9441        2801E
+9442        289DC
+9443         9467
+9444         6DA5
+9445         6F0B
+9446        249EC
+9448        23F7F
+9449         3D8F
+944A         6E04
+944B        2403C
+944C         5A3D
+944D         6E0A
+944E         5847
+944F         6D24
+9450         7842
+9451         713B
+9452        2431A
+9453        24276
+9454         70F1
+9455         7250
+9456         7287
+9457         7294
+9458        2478F
+9459        24725
+945A         5179
+945B        24AA4
+945C        205EB
+945D         747A
+945E        23EF8
+945F        2365F
+9460        24A4A
+9461        24917
+9462        25FE1
+9463         3F06
+9464         3EB1
+9465        24ADF
+9466        28C23
+9467        23F35
+9468         60A7
+9469         3EF3
+946A         74CC
+946B         743C
+946C         9387
+946D         7437
+946E         449F
+946F        26DEA
+9470         4551
+9471         7583
+9472         3F63
+9473        24CD9
+9474        24D06
+9475         3F58
+9476         7555
+9477         7673
+9478        2A5C6
+9479         3B19
+947A         7468
+947B        28ACC
+947C        249AB
+947D        2498E
+947E         3AFB
+94A1         3DCD
+94A2        24A4E
+94A3         3EFF
+94A4        249C5
+94A5        248F3
+94A6         91FA
+94A7         5732
+94A8         9342
+94A9        28AE3
+94AA        21864
+94AB         50DF
+94AC        25221
+94AD        251E7
+94AE         7778
+94AF        23232
+94B0         770E
+94B1         770F
+94B2         777B
+94B3        24697
+94B4        23781
+94B5         3A5E
+94B6        248F0
+94B7         7438
+94B8         749B
+94B9         3EBF
+94BA        24ABA
+94BB        24AC7
+94BC         40C8
+94BD        24A96
+94BE        261AE
+94BF         9307
+94C0        25581
+94C1         781E
+94C2         788D
+94C3         7888
+94C4         78D2
+94C5         73D0
+94C6         7959
+94C7        27741
+94C8        256E3
+94C9         410E
+94CB         8496
+94CC         79A5
+94CD         6A2D
+94CE        23EFA
+94CF         7A3A
+94D0         79F4
+94D1         416E
+94D2        216E6
+94D3         4132
+94D4         9235
+94D5         79F1
+94D6        20D4C
+94D7        2498C
+94D8        20299
+94D9        23DBA
+94DA        2176E
+94DB         3597
+94DC         556B
+94DD         3570
+94DE         36AA
+94DF        201D4
+94E0        20C0D
+94E1         7AE2
+94E2         5A59
+94E3        226F5
+94E4        25AAF
+94E5        25A9C
+94E6         5A0D
+94E7        2025B
+94E8         78F0
+94E9         5A2A
+94EA        25BC6
+94EB         7AFE
+94EC         41F9
+94ED         7C5D
+94EE         7C6D
+94EF         4211
+94F0        25BB3
+94F1        25EBC
+94F2        25EA6
+94F3         7CCD
+94F4        249F9
+94F5        217B0
+94F6         7C8E
+94F7         7C7C
+94F8         7CAE
+94F9         6AB2
+94FA         7DDC
+94FB         7E07
+94FC         7DD3
+94FD         7F4E
+94FE        26261
+9540        2615C
+9541        27B48
+9542         7D97
+9543        25E82
+9544         426A
+9545        26B75
+9546        20916
+9547         67D6
+9548        2004E
+9549        235CF
+954A         57C4
+954B        26412
+954C        263F8
+954D        24962
+954E         7FDD
+954F         7B27
+9550        2082C
+9551        25AE9
+9552        25D43
+9553         7B0C
+9554        25E0E
+9555         99E6
+9556         8645
+9557         9A63
+9558         6A1C
+9559        2343F
+955A         39E2
+955B        249F7
+955C        265AD
+955D         9A1F
+955E        265A0
+955F         8480
+9560        27127
+9561        26CD1
+9562         44EA
+9563         8137
+9564         4402
+9565         80C6
+9566         8109
+9567         8142
+9568        267B4
+9569         98C3
+956A        26A42
+956B         8262
+956C         8265
+956D        26A51
+956E         8453
+956F        26DA7
+9570         8610
+9571        2721B
+9572         5A86
+9573         417F
+9574        21840
+9575         5B2B
+9576        218A1
+9577         5AE4
+9578        218D8
+9579         86A0
+957A        2F9BC
+957B        23D8F
+957C         882D
+957D        27422
+957E         5A02
+95A1         886E
+95A2         4F45
+95A3         8887
+95A4         88BF
+95A5         88E6
+95A6         8965
+95A7         894D
+95A8        25683
+95A9         8954
+95AA        27785
+95AB        27784
+95AC        28BF5
+95AD        28BD9
+95AE        28B9C
+95AF        289F9
+95B0         3EAD
+95B1         84A3
+95B2         46F5
+95B3         46CF
+95B4         37F2
+95B5         8A3D
+95B6         8A1C
+95B7        29448
+95B8         5F4D
+95B9         922B
+95BA        24284
+95BB         65D4
+95BC         7129
+95BD         70C4
+95BE        21845
+95BF         9D6D
+95C0         8C9F
+95C1         8CE9
+95C2        27DDC
+95C3         599A
+95C4         77C3
+95C5         59F0
+95C6         436E
+95C7         36D4
+95C8         8E2A
+95C9         8EA7
+95CA        24C09
+95CB         8F30
+95CC         8F4A
+95CD         42F4
+95CE         6C58
+95CF         6FBB
+95D0        22321
+95D1         489B
+95D2         6F79
+95D3         6E8B
+95D4        217DA
+95D5         9BE9
+95D6         36B5
+95D7        2492F
+95D8         90BB
+95DA         5571
+95DB         4906
+95DC         91BB
+95DD         9404
+95DE        28A4B
+95DF         4062
+95E0        28AFC
+95E1         9427
+95E2        28C1D
+95E3        28C3B
+95E4         84E5
+95E5         8A2B
+95E6         9599
+95E7         95A7
+95E8         9597
+95E9         9596
+95EA        28D34
+95EB         7445
+95EC         3EC2
+95ED        248FF
+95EE        24A42
+95EF        243EA
+95F0         3EE7
+95F1        23225
+95F2         968F
+95F3        28EE7
+95F4        28E66
+95F5        28E65
+95F6         3ECC
+95F7        249ED
+95F8        24A78
+95F9        23FEE
+95FA         7412
+95FB         746B
+95FC         3EFC
+95FD         9741
+95FE        290B0
+9640         6847
+9641         4A1D
+9642        29093
+9643        257DF
+9645         9368
+9646        28989
+9647        28C26
+9648        28B2F
+9649        263BE
+964A         92BA
+964B         5B11
+964C         8B69
+964D         493C
+964E         73F9
+964F        2421B
+9650         979B
+9651         9771
+9652         9938
+9653        20F26
+9654         5DC1
+9655        28BC5
+9656        24AB2
+9657         981F
+9658        294DA
+9659         92F6
+965A        295D7
+965B         91E5
+965C         44C0
+965D        28B50
+965E        24A67
+965F        28B64
+9660         98DC
+9661        28A45
+9662         3F00
+9663         922A
+9664         4925
+9665         8414
+9666         993B
+9667         994D
+9668        27B06
+9669         3DFD
+966A         999B
+966B         4B6F
+966C         99AA
+966D         9A5C
+966E        28B65
+966F        258C8
+9670         6A8F
+9671         9A21
+9672         5AFE
+9673         9A2F
+9674        298F1
+9675         4B90
+9676        29948
+9677         99BC
+9678         4BBD
+9679         4B97
+967A         937D
+967B         5872
+967C        21302
+967D         5822
+967E        249B8
+96A1        214E8
+96A2         7844
+96A3        2271F
+96A4        23DB8
+96A5         68C5
+96A6         3D7D
+96A7         9458
+96A8         3927
+96A9         6150
+96AA        22781
+96AB        2296B
+96AC         6107
+96AD         9C4F
+96AE         9C53
+96AF         9C7B
+96B0         9C35
+96B1         9C10
+96B2         9B7F
+96B3         9BCF
+96B4        29E2D
+96B5         9B9F
+96B6        2A1F5
+96B7        2A0FE
+96B8         9D21
+96B9         4CAE
+96BA        24104
+96BB         9E18
+96BC         4CB0
+96BD         9D0C
+96BE        2A1B4
+96BF        2A0ED
+96C0        2A0F3
+96C1        2992F
+96C2         9DA5
+96C3         84BD
+96C4        26E12
+96C5        26FDF
+96C6        26B82
+96C7         85FC
+96C8         4533
+96C9        26DA4
+96CA        26E84
+96CB        26DF0
+96CC         8420
+96CD         85EE
+96CE        26E00
+96CF        237D7
+96D0        26064
+96D1         79E2
+96D2        2359C
+96D3        23640
+96D4         492D
+96D5        249DE
+96D6         3D62
+96D7         93DB
+96D8         92BE
+96D9         9348
+96DA        202BF
+96DB         78B9
+96DC         9277
+96DD         944D
+96DE         4FE4
+96DF         3440
+96E0         9064
+96E1        2555D
+96E2         783D
+96E3         7854
+96E4         78B6
+96E5         784B
+96E6        21757
+96E7        231C9
+96E8        24941
+96E9         369A
+96EA         4F72
+96EB         6FDA
+96EC         6FD9
+96EE         701E
+96EF         5414
+96F0        241B5
+96F1         57BB
+96F2         58F3
+96F3         578A
+96F4         9D16
+96F5         57D7
+96F6         7134
+96F7         34AF
+96F8        241AC
+96F9         71EB
+96FA        26C40
+96FB        24F97
+96FD        217B5
+96FE        28A49
+9740         610C
+9741         5ACE
+9742         5A0B
+9743         42BC
+9744        24488
+9745         372C
+9746         4B7B
+9747        289FC
+9748         93BB
+9749         93B8
+974A        218D6
+974B        20F1D
+974C         8472
+974D        26CC0
+974E        21413
+974F        242FA
+9750        22C26
+9751        243C1
+9752         5994
+9753        23DB7
+9754        26741
+9755         7DA8
+9756        2615B
+9757        260A4
+9758        249B9
+9759        2498B
+975A        289FA
+975B         92E5
+975C         73E2
+975D         3EE9
+975E         74B4
+975F        28B63
+9760        2189F
+9761         3EE1
+9762        24AB3
+9763         6AD8
+9764         73F3
+9765         73FB
+9766         3ED6
+9767        24A3E
+9768        24A94
+9769        217D9
+976A        24A66
+976B        203A7
+976C        21424
+976D        249E5
+976E         7448
+976F        24916
+9770         70A5
+9771        24976
+9772         9284
+9773         73E6
+9774         935F
+9775        204FE
+9776         9331
+9777        28ACE
+9778        28A16
+9779         9386
+977A        28BE7
+977B        255D5
+977C         4935
+977D        28A82
+977E         716B
+97A1        24943
+97A2        20CFF
+97A3         56A4
+97A4        2061A
+97A5        20BEB
+97A6        20CB8
+97A7         5502
+97A8         79C4
+97A9        217FA
+97AA         7DFE
+97AB        216C2
+97AC        24A50
+97AD        21852
+97AE         452E
+97AF         9401
+97B0         370A
+97B1        28AC0
+97B2        249AD
+97B3         59B0
+97B4        218BF
+97B5        21883
+97B6        27484
+97B7         5AA1
+97B8         36E2
+97B9        23D5B
+97BA         36B0
+97BB         925F
+97BC         5A79
+97BD        28A81
+97BE        21862
+97BF         9374
+97C0         3CCD
+97C1        20AB4
+97C2         4A96
+97C3         398A
+97C4         50F4
+97C5         3D69
+97C6         3D4C
+97C7        2139C
+97C8         7175
+97C9         42FB
+97CA        28218
+97CB         6E0F
+97CC        290E4
+97CD         44EB
+97CE         6D57
+97CF        27E4F
+97D0         7067
+97D1         6CAF
+97D2         3CD6
+97D3        23FED
+97D4        23E2D
+97D5         6E02
+97D6         6F0C
+97D7         3D6F
+97D8        203F5
+97D9         7551
+97DA         36BC
+97DB         34C8
+97DC         4680
+97DD         3EDA
+97DE         4871
+97DF         59C4
+97E0         926E
+97E1         493E
+97E2         8F41
+97E3        28C1C
+97E4        26BC0
+97E5         5812
+97E6         57C8
+97E7         36D6
+97E8        21452
+97E9         70FE
+97EA        24362
+97EB        24A71
+97EC        22FE3
+97ED        212B0
+97EE        223BD
+97EF         68B9
+97F0         6967
+97F1        21398
+97F2        234E5
+97F3        27BF4
+97F4        236DF
+97F5        28A83
+97F6        237D6
+97F7        233FA
+97F8        24C9F
+97F9         6A1A
+97FA        236AD
+97FB        26CB7
+97FC         843E
+97FD         44DF
+97FE         44CE
+9840        26D26
+9841        26D51
+9842        26C82
+9843        26FDE
+9844         6F17
+9845        27109
+9846         833D
+9847        2173A
+9848         83ED
+9849        26C80
+984A        27053
+984B        217DB
+984C         5989
+984D         5A82
+984E        217B3
+984F         5A61
+9850         5A71
+9851        21905
+9852        241FC
+9853         372D
+9854         59EF
+9855        2173C
+9856         36C7
+9857         718E
+9858         9390
+9859         669A
+985A        242A5
+985B         5A6E
+985C         5A2B
+985D        24293
+985E         6A2B
+985F        23EF9
+9860        27736
+9861        2445B
+9862        242CA
+9863         711D
+9864        24259
+9865        289E1
+9866         4FB0
+9867        26D28
+9868         5CC2
+9869        244CE
+986A        27E4D
+986B        243BD
+986C         6A0C
+986D        24256
+986E        21304
+986F         70A6
+9870         7133
+9871        243E9
+9872         3DA5
+9873         6CDF
+9874        2F825
+9875        24A4F
+9876         7E65
+9877         59EB
+9878         5D2F
+9879         3DF3
+987A         5F5C
+987B        24A5D
+987C        217DF
+987D         7DA4
+987E         8426
+98A1         5485
+98A2        23AFA
+98A3        23300
+98A4        20214
+98A5         577E
+98A6        208D5
+98A7        20619
+98A8         3FE5
+98A9        21F9E
+98AA        2A2B6
+98AB         7003
+98AC        2915B
+98AD         5D70
+98AE         738F
+98AF         7CD3
+98B0        28A59
+98B1        29420
+98B2         4FC8
+98B3         7FE7
+98B4         72CD
+98B5         7310
+98B6        27AF4
+98B7         7338
+98B8         7339
+98B9        256F6
+98BA         7341
+98BB         7348
+98BC         3EA9
+98BD        27B18
+98BE         906C
+98BF         71F5
+98C0        248F2
+98C1         73E1
+98C2         81F6
+98C3         3ECA
+98C4         770C
+98C5         3ED1
+98C6         6CA2
+98C7         56FD
+98C8         7419
+98C9         741E
+98CA         741F
+98CB         3EE2
+98CC         3EF0
+98CD         3EF4
+98CE         3EFA
+98CF         74D3
+98D0         3F0E
+98D1         3F53
+98D2         7542
+98D3         756D
+98D4         7572
+98D5         758D
+98D6         3F7C
+98D7         75C8
+98D8         75DC
+98D9         3FC0
+98DA         764D
+98DB         3FD7
+98DC         7674
+98DD         3FDC
+98DE         767A
+98DF        24F5C
+98E0         7188
+98E1         5623
+98E2         8980
+98E3         5869
+98E4         401D
+98E5         7743
+98E6         4039
+98E7         6761
+98E8         4045
+98E9         35DB
+98EA         7798
+98EB         406A
+98EC         406F
+98ED         5C5E
+98EE         77BE
+98EF         77CB
+98F0         58F2
+98F1         7818
+98F2         70B9
+98F3         781C
+98F4         40A8
+98F5         7839
+98F6         7847
+98F7         7851
+98F8         7866
+98F9         8448
+98FA        25535
+98FB         7933
+98FC         6803
+98FD         7932
+98FE         4103
+9940         4109
+9941         7991
+9942         7999
+9943         8FBB
+9944         7A06
+9945         8FBC
+9946         4167
+9947         7A91
+9948         41B2
+9949         7ABC
+994A         8279
+994B         41C4
+994C         7ACF
+994D         7ADB
+994E         41CF
+994F         4E21
+9950         7B62
+9951         7B6C
+9952         7B7B
+9953         7C12
+9954         7C1B
+9955         4260
+9956         427A
+9957         7C7B
+9958         7C9C
+9959         428C
+995A         7CB8
+995B         4294
+995C         7CED
+995D         8F93
+995E         70C0
+995F        20CCF
+9960         7DCF
+9961         7DD4
+9962         7DD0
+9963         7DFD
+9964         7FAE
+9965         7FB4
+9966         729F
+9967         4397
+9968         8020
+9969         8025
+996A         7B39
+996B         802E
+996C         8031
+996D         8054
+996E         3DCC
+996F         57B4
+9970         70A0
+9971         80B7
+9972         80E9
+9973         43ED
+9974         810C
+9975         732A
+9976         810E
+9977         8112
+9978         7560
+9979         8114
+997A         4401
+997B         3B39
+997C         8156
+997D         8159
+997E         815A
+99A1         4413
+99A2         583A
+99A3         817C
+99A4         8184
+99A5         4425
+99A6         8193
+99A7         442D
+99A8         81A5
+99A9         57EF
+99AA         81C1
+99AB         81E4
+99AC         8254
+99AD         448F
+99AE         82A6
+99AF         8276
+99B0         82CA
+99B1         82D8
+99B2         82FF
+99B3         44B0
+99B4         8357
+99B5         9669
+99B6         698A
+99B7         8405
+99B8         70F5
+99B9         8464
+99BA         60E3
+99BB         8488
+99BC         4504
+99BD         84BE
+99BE         84E1
+99BF         84F8
+99C0         8510
+99C1         8538
+99C2         8552
+99C3         453B
+99C4         856F
+99C5         8570
+99C6         85E0
+99C7         4577
+99C8         8672
+99C9         8692
+99CA         86B2
+99CB         86EF
+99CC         9645
+99CD         878B
+99CE         4606
+99CF         4617
+99D0         88AE
+99D1         88FF
+99D2         8924
+99D3         8947
+99D4         8991
+99D5        27967
+99D6         8A29
+99D7         8A38
+99D8         8A94
+99D9         8AB4
+99DA         8C51
+99DB         8CD4
+99DC         8CF2
+99DD         8D1C
+99DE         4798
+99DF         585F
+99E0         8DC3
+99E1         47ED
+99E2         4EEE
+99E3         8E3A
+99E4         55D8
+99E5         5754
+99E6         8E71
+99E7         55F5
+99E8         8EB0
+99E9         4837
+99EA         8ECE
+99EB         8EE2
+99EC         8EE4
+99ED         8EED
+99EE         8EF2
+99EF         8FB7
+99F0         8FC1
+99F1         8FCA
+99F2         8FCC
+99F3         9033
+99F4         99C4
+99F5         48AD
+99F6         98E0
+99F7         9213
+99F8         491E
+99F9         9228
+99FA         9258
+99FB         926B
+99FC         92B1
+99FD         92AE
+99FE         92BF
+9A40         92E3
+9A41         92EB
+9A42         92F3
+9A43         92F4
+9A44         92FD
+9A45         9343
+9A46         9384
+9A47         93AD
+9A48         4945
+9A49         4951
+9A4A         9EBF
+9A4B         9417
+9A4C         5301
+9A4D         941D
+9A4E         942D
+9A4F         943E
+9A50         496A
+9A51         9454
+9A52         9479
+9A53         952D
+9A54         95A2
+9A55         49A7
+9A56         95F4
+9A57         9633
+9A58         49E5
+9A59         67A0
+9A5A         4A24
+9A5B         9740
+9A5C         4A35
+9A5D         97B2
+9A5E         97C2
+9A5F         5654
+9A60         4AE4
+9A61         60E8
+9A62         98B9
+9A63         4B19
+9A64         98F1
+9A65         5844
+9A66         990E
+9A67         9919
+9A68         51B4
+9A69         991C
+9A6A         9937
+9A6B         9942
+9A6C         995D
+9A6D         9962
+9A6E         4B70
+9A6F         99C5
+9A70         4B9D
+9A71         9A3C
+9A72         9B0F
+9A73         7A83
+9A74         9B69
+9A75         9B81
+9A76         9BDD
+9A77         9BF1
+9A78         9BF4
+9A79         4C6D
+9A7A         9C20
+9A7B         376F
+9A7C        21BC2
+9A7D         9D49
+9A7E         9C3A
+9AA1         9EFE
+9AA2         5650
+9AA3         9D93
+9AA4         9DBD
+9AA5         9DC0
+9AA6         9DFC
+9AA7         94F6
+9AA8         8FB6
+9AA9         9E7B
+9AAA         9EAC
+9AAB         9EB1
+9AAC         9EBD
+9AAD         9EC6
+9AAE         94DC
+9AAF         9EE2
+9AB0         9EF1
+9AB1         9EF8
+9AB2         7AC8
+9AB3         9F44
+9AB4        20094
+9AB5        202B7
+9AB6        203A0
+9AB7         691A
+9AB8         94C3
+9AB9         59AC
+9ABA        204D7
+9ABB         5840
+9ABC         94C1
+9ABD         37B9
+9ABE        205D5
+9ABF        20615
+9AC0        20676
+9AC1        216BA
+9AC2         5757
+9AC3         7173
+9AC4        20AC2
+9AC5        20ACD
+9AC6        20BBF
+9AC7         546A
+9AC8        2F83B
+9AC9        20BCB
+9ACA         549E
+9ACB        20BFB
+9ACC        20C3B
+9ACD        20C53
+9ACE        20C65
+9ACF        20C7C
+9AD0         60E7
+9AD1        20C8D
+9AD2         567A
+9AD3        20CB5
+9AD4        20CDD
+9AD5        20CED
+9AD6        20D6F
+9AD7        20DB2
+9AD8        20DC8
+9AD9         6955
+9ADA         9C2F
+9ADB         87A5
+9ADC        20E04
+9ADD        20E0E
+9ADE        20ED7
+9ADF        20F90
+9AE0        20F2D
+9AE1        20E73
+9AE2         5C20
+9AE3        20FBC
+9AE4         5E0B
+9AE5        2105C
+9AE6        2104F
+9AE7        21076
+9AE8         671E
+9AE9        2107B
+9AEA        21088
+9AEB        21096
+9AEC         3647
+9AED        210BF
+9AEE        210D3
+9AEF        2112F
+9AF0        2113B
+9AF1         5364
+9AF2         84AD
+9AF3        212E3
+9AF4        21375
+9AF5        21336
+9AF6         8B81
+9AF7        21577
+9AF8        21619
+9AF9        217C3
+9AFA        217C7
+9AFB         4E78
+9AFC         70BB
+9AFD        2182D
+9AFE        2196A
+9B40        21A2D
+9B41        21A45
+9B42        21C2A
+9B43        21C70
+9B44        21CAC
+9B45        21EC8
+9B46         62C3
+9B47        21ED5
+9B48        21F15
+9B49         7198
+9B4A         6855
+9B4B        22045
+9B4C         69E9
+9B4D         36C8
+9B4E        2227C
+9B4F        223D7
+9B50        223FA
+9B51        2272A
+9B52        22871
+9B53        2294F
+9B54         82FD
+9B55        22967
+9B56        22993
+9B57        22AD5
+9B58         89A5
+9B59        22AE8
+9B5A         8FA0
+9B5B        22B0E
+9B5C         97B8
+9B5D        22B3F
+9B5E         9847
+9B5F         9ABD
+9B60        22C4C
+9B62        22C88
+9B63        22CB7
+9B64        25BE8
+9B65        22D08
+9B66        22D12
+9B67        22DB7
+9B68        22D95
+9B69        22E42
+9B6A        22F74
+9B6B        22FCC
+9B6C        23033
+9B6D        23066
+9B6E        2331F
+9B6F        233DE
+9B70         5FB1
+9B71         6648
+9B72         66BF
+9B73        27A79
+9B74        23567
+9B75        235F3
+9B77        249BA
+9B79        2361A
+9B7A        23716
+9B7C        20346
+9B7D         58B5
+9B7E         670E
+9BA1         6918
+9BA2        23AA7
+9BA3        27657
+9BA4        25FE2
+9BA5        23E11
+9BA6        23EB9
+9BA7        275FE
+9BA8        2209A
+9BA9         48D0
+9BAA         4AB8
+9BAB        24119
+9BAC        28A9A
+9BAD        242EE
+9BAE        2430D
+9BAF        2403B
+9BB0        24334
+9BB1        24396
+9BB2        24A45
+9BB3        205CA
+9BB4         51D2
+9BB5        20611
+9BB6         599F
+9BB7        21EA8
+9BB8         3BBE
+9BB9        23CFF
+9BBA        24404
+9BBB        244D6
+9BBC         5788
+9BBD        24674
+9BBE         399B
+9BBF        2472F
+9BC0        285E8
+9BC1        299C9
+9BC2         3762
+9BC3        221C3
+9BC4         8B5E
+9BC5        28B4E
+9BC7        24812
+9BC8        248FB
+9BC9        24A15
+9BCA         7209
+9BCB        24AC0
+9BCC        20C78
+9BCD         5965
+9BCE        24EA5
+9BCF        24F86
+9BD0        20779
+9BD1         8EDA
+9BD2        2502C
+9BD3         528F
+9BD4         573F
+9BD5         7171
+9BD6        25299
+9BD7        25419
+9BD8        23F4A
+9BD9        24AA7
+9BDA         55BC
+9BDB        25446
+9BDC        2546E
+9BDD        26B52
+9BDF         3473
+9BE0        2553F
+9BE1        27632
+9BE2        2555E
+9BE3         4718
+9BE4        25562
+9BE5        25566
+9BE6        257C7
+9BE7        2493F
+9BE8        2585D
+9BE9         5066
+9BEA         34FB
+9BEB        233CC
+9BED        25903
+9BEE         477C
+9BEF        28948
+9BF0        25AAE
+9BF1        25B89
+9BF2        25C06
+9BF3        21D90
+9BF4         57A1
+9BF5         7151
+9BF7        26102
+9BF8        27C12
+9BF9         9056
+9BFA        261B2
+9BFB        24F9A
+9BFC         8B62
+9BFD        26402
+9BFE        2644A
+9C40         5D5B
+9C41        26BF7
+9C43        26484
+9C44        2191C
+9C45         8AEA
+9C46        249F6
+9C47        26488
+9C48        23FEF
+9C49        26512
+9C4A         4BC0
+9C4B        265BF
+9C4C        266B5
+9C4D        2271B
+9C4E         9465
+9C4F        257E1
+9C50         6195
+9C51         5A27
+9C52        2F8CD
+9C54         56B9
+9C55        24521
+9C56        266FC
+9C57         4E6A
+9C58        24934
+9C59         9656
+9C5A         6D8F
+9C5B        26CBD
+9C5C         3618
+9C5D         8977
+9C5E        26799
+9C5F        2686E
+9C60        26411
+9C61        2685E
+9C63        268C7
+9C64         7B42
+9C65        290C0
+9C66        20A11
+9C67        26926
+9C69        26939
+9C6A         7A45
+9C6C        269FA
+9C6D         9A26
+9C6E        26A2D
+9C6F         365F
+9C70        26469
+9C71        20021
+9C72         7983
+9C73        26A34
+9C74        26B5B
+9C75         5D2C
+9C76        23519
+9C78        26B9D
+9C79         46D0
+9C7A        26CA4
+9C7B         753B
+9C7C         8865
+9C7D        26DAE
+9C7E         58B6
+9CA1         371C
+9CA2        2258D
+9CA3        2704B
+9CA4        271CD
+9CA5         3C54
+9CA6        27280
+9CA7        27285
+9CA8         9281
+9CA9        2217A
+9CAA        2728B
+9CAB         9330
+9CAC        272E6
+9CAD        249D0
+9CAE         6C39
+9CAF         949F
+9CB0        27450
+9CB1        20EF8
+9CB2         8827
+9CB3         88F5
+9CB4        22926
+9CB5        28473
+9CB6        217B1
+9CB7         6EB8
+9CB8        24A2A
+9CB9        21820
+9CBA         39A4
+9CBB         36B9
+9CBE         453F
+9CBF         66B6
+9CC0        29CAD
+9CC1        298A4
+9CC2         8943
+9CC3        277CC
+9CC4        27858
+9CC5         56D6
+9CC6         40DF
+9CC7        2160A
+9CC8         39A1
+9CC9        2372F
+9CCA        280E8
+9CCB        213C5
+9CCC         71AD
+9CCD         8366
+9CCE        279DD
+9CCF        291A8
+9CD1         4CB7
+9CD2        270AF
+9CD3        289AB
+9CD4        279FD
+9CD5        27A0A
+9CD6        27B0B
+9CD7        27D66
+9CD8        2417A
+9CD9         7B43
+9CDA         797E
+9CDB        28009
+9CDC         6FB5
+9CDD        2A2DF
+9CDE         6A03
+9CDF        28318
+9CE0         53A2
+9CE1        26E07
+9CE2         93BF
+9CE3         6836
+9CE4         975D
+9CE5        2816F
+9CE6        28023
+9CE7        269B5
+9CE8        213ED
+9CE9        2322F
+9CEA        28048
+9CEB         5D85
+9CEC        28C30
+9CED        28083
+9CEE         5715
+9CEF         9823
+9CF0        28949
+9CF1         5DAB
+9CF2        24988
+9CF3         65BE
+9CF4         69D5
+9CF5         53D2
+9CF6        24AA5
+9CF7        23F81
+9CF8         3C11
+9CF9         6736
+9CFA        28090
+9CFB        280F4
+9CFC        2812E
+9CFD        21FA1
+9CFE        2814F
+9D40        28189
+9D41        281AF
+9D42        2821A
+9D43        28306
+9D44        2832F
+9D45        2838A
+9D46         35CA
+9D47        28468
+9D48        286AA
+9D49         48FA
+9D4A         63E6
+9D4B        28956
+9D4C         7808
+9D4D         9255
+9D4E        289B8
+9D4F         43F2
+9D50        289E7
+9D51         43DF
+9D52        289E8
+9D53        28B46
+9D54        28BD4
+9D55         59F8
+9D56        28C09
+9D58        28FC5
+9D59        290EC
+9D5B        29110
+9D5C        2913C
+9D5D         3DF7
+9D5E        2915E
+9D5F        24ACA
+9D60         8FD0
+9D61         728F
+9D62         568B
+9D63        294E7
+9D64        295E9
+9D65        295B0
+9D66        295B8
+9D67        29732
+9D68        298D1
+9D69        29949
+9D6A        2996A
+9D6B        299C3
+9D6C        29A28
+9D6D        29B0E
+9D6E        29D5A
+9D6F        29D9B
+9D70         7E9F
+9D71        29EF8
+9D72        29F23
+9D73         4CA4
+9D74         9547
+9D75        2A293
+9D76         71A2
+9D77        2A2FF
+9D78         4D91
+9D79         9012
+9D7A        2A5CB
+9D7B         4D9C
+9D7C        20C9C
+9D7D         8FBE
+9D7E         55C1
+9DA1         8FBA
+9DA2        224B0
+9DA3         8FB9
+9DA4        24A93
+9DA5         4509
+9DA6         7E7F
+9DA7         6F56
+9DA8         6AB1
+9DA9         4EEA
+9DAA         34E4
+9DAB        28B2C
+9DAC        2789D
+9DAD         373A
+9DAE         8E80
+9DAF        217F5
+9DB0        28024
+9DB1        28B6C
+9DB2        28B99
+9DB3        27A3E
+9DB4        266AF
+9DB5         3DEB
+9DB6        27655
+9DB7        23CB7
+9DB8        25635
+9DB9        25956
+9DBA         4E9A
+9DBB        25E81
+9DBC        26258
+9DBD         56BF
+9DBE        20E6D
+9DBF         8E0E
+9DC0         5B6D
+9DC1        23E88
+9DC2        24C9E
+9DC3         63DE
+9DC5        217F6
+9DC6        2187B
+9DC7         6530
+9DC8         562D
+9DC9        25C4A
+9DCA         541A
+9DCB        25311
+9DCC         3DC6
+9DCD        29D98
+9DCE         4C7D
+9DCF         5622
+9DD0         561E
+9DD1         7F49
+9DD2        25ED8
+9DD3         5975
+9DD4        23D40
+9DD5         8770
+9DD6         4E1C
+9DD7        20FEA
+9DD8        20D49
+9DD9        236BA
+9DDA         8117
+9DDB         9D5E
+9DDC         8D18
+9DDD         763B
+9DDE         9C45
+9DDF         764E
+9DE0         77B9
+9DE1         9345
+9DE2         5432
+9DE3         8148
+9DE4         82F7
+9DE5         5625
+9DE6         8132
+9DE7         8418
+9DE8         80BD
+9DE9         55EA
+9DEA         7962
+9DEB         5643
+9DEC         5416
+9DED        20E9D
+9DEE         35CE
+9DEF         5605
+9DF0         55F1
+9DF1         66F1
+9DF2        282E2
+9DF3         362D
+9DF4         7534
+9DF5         55F0
+9DF6         55BA
+9DF7         5497
+9DF8         5572
+9DF9        20C41
+9DFA        20C96
+9DFB         5ED0
+9DFC        25148
+9DFD        20E76
+9DFE        22C62
+9E40        20EA2
+9E41         9EAB
+9E42         7D5A
+9E43         55DE
+9E44        21075
+9E45         629D
+9E46         976D
+9E47         5494
+9E48         8CCD
+9E49         71F6
+9E4A         9176
+9E4B         63FC
+9E4C         63B9
+9E4D         63FE
+9E4E         5569
+9E4F        22B43
+9E50         9C72
+9E51        22EB3
+9E52         519A
+9E53         34DF
+9E54        20DA7
+9E55         51A7
+9E56         544D
+9E57         551E
+9E58         5513
+9E59         7666
+9E5A         8E2D
+9E5B        2688A
+9E5C         75B1
+9E5D         80B6
+9E5E         8804
+9E5F         8786
+9E60         88C7
+9E61         81B6
+9E62         841C
+9E63        210C1
+9E64         44EC
+9E65         7304
+9E66        24706
+9E67         5B90
+9E68         830B
+9E69        26893
+9E6A         567B
+9E6B        226F4
+9E6C        27D2F
+9E6D        241A3
+9E6E        27D73
+9E6F        26ED0
+9E70        272B6
+9E71         9170
+9E72        211D9
+9E73         9208
+9E74        23CFC
+9E75        2A6A9
+9E76        20EAC
+9E77        20EF9
+9E78         7266
+9E79        21CA2
+9E7A         474E
+9E7B        24FC2
+9E7C        27FF9
+9E7D        20FEB
+9E7E         40FA
+9EA1         9C5D
+9EA2         651F
+9EA3        22DA0
+9EA4         48F3
+9EA5        247E0
+9EA6        29D7C
+9EA7        20FEC
+9EA8        20E0A
+9EAA        275A3
+9EAB        20FED
+9EAD        26048
+9EAE        21187
+9EAF         71A3
+9EB0         7E8E
+9EB1         9D50
+9EB2         4E1A
+9EB3         4E04
+9EB4         3577
+9EB5         5B0D
+9EB6         6CB2
+9EB7         5367
+9EB8         36AC
+9EB9         39DC
+9EBA         537D
+9EBB         36A5
+9EBC        24618
+9EBD         589A
+9EBE        24B6E
+9EBF         822D
+9EC0         544B
+9EC1         57AA
+9EC2        25A95
+9EC3        20979
+9EC5         3A52
+9EC6        22465
+9EC7         7374
+9EC8        29EAC
+9EC9         4D09
+9ECA         9BED
+9ECB        23CFE
+9ECC        29F30
+9ECD         4C5B
+9ECE        24FA9
+9ECF        2959E
+9ED0        29FDE
+9ED1         845C
+9ED2        23DB6
+9ED3        272B2
+9ED4        267B3
+9ED5        23720
+9ED6         632E
+9ED7         7D25
+9ED8        23EF7
+9ED9        23E2C
+9EDA         3A2A
+9EDB         9008
+9EDC         52CC
+9EDD         3E74
+9EDE         367A
+9EDF         45E9
+9EE0        2048E
+9EE1         7640
+9EE2         5AF0
+9EE3        20EB6
+9EE4         787A
+9EE5        27F2E
+9EE6         58A7
+9EE7         40BF
+9EE8         567C
+9EE9         9B8B
+9EEA         5D74
+9EEB         7654
+9EEC        2A434
+9EED         9E85
+9EEE         4CE1
+9EF0         37FB
+9EF1         6119
+9EF2        230DA
+9EF3        243F2
+9EF5         565D
+9EF6        212A9
+9EF7         57A7
+9EF8        24963
+9EF9        29E06
+9EFA         5234
+9EFB        270AE
+9EFC         35AD
+9EFE         9D7C
+9F40         7C56
+9F41         9B39
+9F42         57DE
+9F43        2176C
+9F44         5C53
+9F45         64D3
+9F46        294D0
+9F47        26335
+9F48        27164
+9F49         86AD
+9F4A        20D28
+9F4B        26D22
+9F4C        24AE2
+9F4D        20D71
+9F4F         51FE
+9F50        21F0F
+9F51         5D8E
+9F52         9703
+9F53        21DD1
+9F54         9E81
+9F55         904C
+9F56         7B1F
+9F57         9B02
+9F58         5CD1
+9F59         7BA3
+9F5A         6268
+9F5B         6335
+9F5C         9AFF
+9F5D         7BCF
+9F5E         9B2A
+9F5F         7C7E
+9F61         7C42
+9F62         7C86
+9F63         9C15
+9F64         7BFC
+9F65         9B09
+9F67         9C1B
+9F68        2493E
+9F69         9F5A
+9F6A         5573
+9F6B         5BC3
+9F6C         4FFD
+9F6D         9E98
+9F6E         4FF2
+9F6F         5260
+9F70         3E06
+9F71         52D1
+9F72         5767
+9F73         5056
+9F74         59B7
+9F75         5E12
+9F76         97C8
+9F77         9DAB
+9F78         8F5C
+9F79         5469
+9F7A         97B4
+9F7B         9940
+9F7C         97BA
+9F7D         532C
+9F7E         6130
+9FA1         692C
+9FA2         53DA
+9FA3         9C0A
+9FA4         9D02
+9FA5         4C3B
+9FA6         9641
+9FA7         6980
+9FA8         50A6
+9FA9         7546
+9FAA        2176D
+9FAB         99DA
+9FAC         5273
+9FAE         9159
+9FAF         9681
+9FB0         915C
+9FB2         9151
+9FB3        28E97
+9FB4         637F
+9FB5        26D23
+9FB6         6ACA
+9FB7         5611
+9FB8         918E
+9FB9         757A
+9FBA         6285
+9FBB        203FC
+9FBC         734F
+9FBD         7C70
+9FBE        25C21
+9FBF        23CFD
+9FC1        24919
+9FC2         76D6
+9FC3         9B9D
+9FC4         4E2A
+9FC5        20CD4
+9FC6         83BE
+9FC7         8842
+9FC9         5C4A
+9FCA         69C0
+9FCC         577A
+9FCD         521F
+9FCE         5DF5
+9FCF         4ECE
+9FD0         6C31
+9FD1        201F2
+9FD2         4F39
+9FD3         549C
+9FD4         54DA
+9FD5         529A
+9FD6         8D82
+9FD7         35FE
+9FD9         35F3
+9FDB         6B52
+9FDC         917C
+9FDD         9FA5
+9FDE         9B97
+9FDF         982E
+9FE0         98B4
+9FE1         9ABA
+9FE2         9EA8
+9FE3         9E84
+9FE4         717A
+9FE5         7B14
+9FE7         6BFA
+9FE8         8818
+9FE9         7F78
+9FEB         5620
+9FEC        2A64A
+9FED         8E77
+9FEE         9F53
+9FF0         8DD4
+9FF1         8E4F
+9FF2         9E1C
+9FF3         8E01
+9FF4         6282
+9FF5        2837D
+9FF6         8E28
+9FF7         8E75
+9FF8         7AD3
+9FF9        24A77
+9FFA         7A3E
+9FFB         78D8
+9FFC         6CEA
+9FFD         8A67
+9FFE         7607
+A040        28A5A
+A041         9F26
+A042         6CCE
+A043         87D6
+A044         75C3
+A045        2A2B2
+A046         7853
+A047        2F840
+A048         8D0C
+A049         72E2
+A04A         7371
+A04B         8B2D
+A04C         7302
+A04D         74F1
+A04E         8CEB
+A04F        24ABB
+A050         862F
+A051         5FBA
+A052         88A0
+A053         44B7
+A055        2183B
+A056        26E05
+A058         8A7E
+A059        2251B
+A05B         60FD
+A05C         7667
+A05D         9AD7
+A05E         9D44
+A05F         936E
+A060         9B8F
+A061         87F5
+A064         8CF7
+A065         732C
+A066         9721
+A067         9BB0
+A068         35D6
+A069         72B2
+A06A         4C07
+A06B         7C51
+A06C         994A
+A06D        26159
+A06E         6159
+A06F         4C04
+A070         9E96
+A071         617D
+A073         575F
+A074         616F
+A075         62A6
+A076         6239
+A078         3A5C
+A079         61E2
+A07A         53AA
+A07B        233F5
+A07C         6364
+A07D         6802
+A07E         35D2
+A0A1         5D57
+A0A2        28BC2
+A0A3         8FDA
+A0A4        28E39
+A0A6         50D9
+A0A7        21D46
+A0A8         7906
+A0A9         5332
+A0AA         9638
+A0AB        20F3B
+A0AC         4065
+A0AE         77FE
+A0B0         7CC2
+A0B1        25F1A
+A0B2         7CDA
+A0B3         7A2D
+A0B4         8066
+A0B5         8063
+A0B6         7D4D
+A0B7         7505
+A0B8         74F2
+A0B9         8994
+A0BA         821A
+A0BB         670C
+A0BC         8062
+A0BD        27486
+A0BE         805B
+A0BF         74F0
+A0C0         8103
+A0C1         7724
+A0C2         8989
+A0C3        267CC
+A0C4         7553
+A0C5        26ED1
+A0C6         87A9
+A0C7         87CE
+A0C8         81C8
+A0C9         878C
+A0CA         8A49
+A0CB         8CAD
+A0CC         8B43
+A0CD         772B
+A0CE         74F8
+A0CF         84DA
+A0D0         3635
+A0D1         69B2
+A0D2         8DA6
+A0D4         89A9
+A0D6         6DB9
+A0D7         87C1
+A0D8        24011
+A0D9         74E7
+A0DA         3DDB
+A0DB         7176
+A0DC         60A4
+A0DD         619C
+A0DE         3CD1
+A0E0         6077
+A0E2         7F71
+A0E3        28B2D
+A0E5         60E9
+A0E6         4B7E
+A0E7         5220
+A0E8         3C18
+A0E9        23CC7
+A0EA        25ED7
+A0EB        27656
+A0EC        25531
+A0ED        21944
+A0EE        212FE
+A0EF        29903
+A0F0        26DDC
+A0F1        270AD
+A0F2         5CC1
+A0F3        261AD
+A0F4        28A0F
+A0F5        23677
+A0F6        200EE
+A0F7        26846
+A0F8        24F0E
+A0F9         4562
+A0FA         5B1F
+A0FB        2634C
+A0FC         9F50
+A0FD         9EA6
+A0FE        2626B
+C6A1         2460
+C6A2         2461
+C6A3         2462
+C6A4         2463
+C6A5         2464
+C6A6         2465
+C6A7         2466
+C6A8         2467
+C6A9         2468
+C6AA         2469
+C6AB         2474
+C6AC         2475
+C6AD         2476
+C6AE         2477
+C6AF         2478
+C6B0         2479
+C6B1         247A
+C6B2         247B
+C6B3         247C
+C6B4         247D
+C6B5         2170
+C6B6         2171
+C6B7         2172
+C6B8         2173
+C6B9         2174
+C6BA         2175
+C6BB         2176
+C6BC         2177
+C6BD         2178
+C6BE         2179
+C6BF         4E36
+C6C0         4E3F
+C6C1         4E85
+C6C2         4EA0
+C6C3         5182
+C6C4         5196
+C6C5         51AB
+C6C6         52F9
+C6C7         5338
+C6C8         5369
+C6C9         53B6
+C6CA         590A
+C6CB         5B80
+C6CC         5DDB
+C6CD         2F33
+C6CE         5E7F
+C6D0         5F50
+C6D1         5F61
+C6D2         6534
+C6D4         7592
+C6D6         8FB5
+C6D8         00A8
+C6D9         02C6
+C6DA         30FD
+C6DB         30FE
+C6DC         309D
+C6DD         309E
+C6E0         3005
+C6E1         3006
+C6E2         3007
+C6E3         30FC
+C6E4         FF3B
+C6E5         FF3D
+C6E6         273D
+C6E7         3041
+C6E8         3042
+C6E9         3043
+C6EA         3044
+C6EB         3045
+C6EC         3046
+C6ED         3047
+C6EE         3048
+C6EF         3049
+C6F0         304A
+C6F1         304B
+C6F2         304C
+C6F3         304D
+C6F4         304E
+C6F5         304F
+C6F6         3050
+C6F7         3051
+C6F8         3052
+C6F9         3053
+C6FA         3054
+C6FB         3055
+C6FC         3056
+C6FD         3057
+C6FE         3058
+C740         3059
+C741         305A
+C742         305B
+C743         305C
+C744         305D
+C745         305E
+C746         305F
+C747         3060
+C748         3061
+C749         3062
+C74A         3063
+C74B         3064
+C74C         3065
+C74D         3066
+C74E         3067
+C74F         3068
+C750         3069
+C751         306A
+C752         306B
+C753         306C
+C754         306D
+C755         306E
+C756         306F
+C757         3070
+C758         3071
+C759         3072
+C75A         3073
+C75B         3074
+C75C         3075
+C75D         3076
+C75E         3077
+C75F         3078
+C760         3079
+C761         307A
+C762         307B
+C763         307C
+C764         307D
+C765         307E
+C766         307F
+C767         3080
+C768         3081
+C769         3082
+C76A         3083
+C76B         3084
+C76C         3085
+C76D         3086
+C76E         3087
+C76F         3088
+C770         3089
+C771         308A
+C772         308B
+C773         308C
+C774         308D
+C775         308E
+C776         308F
+C777         3090
+C778         3091
+C779         3092
+C77A         3093
+C77B         30A1
+C77C         30A2
+C77D         30A3
+C77E         30A4
+C7A1         30A5
+C7A2         30A6
+C7A3         30A7
+C7A4         30A8
+C7A5         30A9
+C7A6         30AA
+C7A7         30AB
+C7A8         30AC
+C7A9         30AD
+C7AA         30AE
+C7AB         30AF
+C7AC         30B0
+C7AD         30B1
+C7AE         30B2
+C7AF         30B3
+C7B0         30B4
+C7B1         30B5
+C7B2         30B6
+C7B3         30B7
+C7B4         30B8
+C7B5         30B9
+C7B6         30BA
+C7B7         30BB
+C7B8         30BC
+C7B9         30BD
+C7BA         30BE
+C7BB         30BF
+C7BC         30C0
+C7BD         30C1
+C7BE         30C2
+C7BF         30C3
+C7C0         30C4
+C7C1         30C5
+C7C2         30C6
+C7C3         30C7
+C7C4         30C8
+C7C5         30C9
+C7C6         30CA
+C7C7         30CB
+C7C8         30CC
+C7C9         30CD
+C7CA         30CE
+C7CB         30CF
+C7CC         30D0
+C7CD         30D1
+C7CE         30D2
+C7CF         30D3
+C7D0         30D4
+C7D1         30D5
+C7D2         30D6
+C7D3         30D7
+C7D4         30D8
+C7D5         30D9
+C7D6         30DA
+C7D7         30DB
+C7D8         30DC
+C7D9         30DD
+C7DA         30DE
+C7DB         30DF
+C7DC         30E0
+C7DD         30E1
+C7DE         30E2
+C7DF         30E3
+C7E0         30E4
+C7E1         30E5
+C7E2         30E6
+C7E3         30E7
+C7E4         30E8
+C7E5         30E9
+C7E6         30EA
+C7E7         30EB
+C7E8         30EC
+C7E9         30ED
+C7EA         30EE
+C7EB         30EF
+C7EC         30F0
+C7ED         30F1
+C7EE         30F2
+C7EF         30F3
+C7F0         30F4
+C7F1         30F5
+C7F2         30F6
+C7F3         0410
+C7F4         0411
+C7F5         0412
+C7F6         0413
+C7F7         0414
+C7F8         0415
+C7F9         0401
+C7FA         0416
+C7FB         0417
+C7FC         0418
+C7FD         0419
+C7FE         041A
+C840         041B
+C841         041C
+C842         041D
+C843         041E
+C844         041F
+C845         0420
+C846         0421
+C847         0422
+C848         0423
+C849         0424
+C84A         0425
+C84B         0426
+C84C         0427
+C84D         0428
+C84E         0429
+C84F         042A
+C850         042B
+C851         042C
+C852         042D
+C853         042E
+C854         042F
+C855         0430
+C856         0431
+C857         0432
+C858         0433
+C859         0434
+C85A         0435
+C85B         0451
+C85C         0436
+C85D         0437
+C85E         0438
+C85F         0439
+C860         043A
+C861         043B
+C862         043C
+C863         043D
+C864         043E
+C865         043F
+C866         0440
+C867         0441
+C868         0442
+C869         0443
+C86A         0444
+C86B         0445
+C86C         0446
+C86D         0447
+C86E         0448
+C86F         0449
+C870         044A
+C871         044B
+C872         044C
+C873         044D
+C874         044E
+C875         044F
+C876         21E7
+C877         21B8
+C878         21B9
+C879         31CF
+C87A        200CC
+C87B         4E5A
+C87C        2008A
+C87D         5202
+C87E         4491
+C8A1         9FB0
+C8A2         5188
+C8A3         9FB1
+C8A4        27607
+C8CD         FFE2
+C8CE         FFE4
+C8CF         FF07
+C8D0         FF02
+C8D1         3231
+C8D2         2116
+C8D3         2121
+C8D4         309B
+C8D5         309C
+C8D6         2E80
+C8D7         2E84
+C8D8         2E86
+C8D9         2E87
+C8DA         2E88
+C8DB         2E8A
+C8DC         2E8C
+C8DD         2E8D
+C8DE         2E95
+C8DF         2E9C
+C8E0         2E9D
+C8E1         2EA5
+C8E2         2EA7
+C8E3         2EAA
+C8E4         2EAC
+C8E5         2EAE
+C8E6         2EB6
+C8E7         2EBC
+C8E8         2EBE
+C8E9         2EC6
+C8EA         2ECA
+C8EB         2ECC
+C8EC         2ECD
+C8ED         2ECF
+C8EE         2ED6
+C8EF         2ED7
+C8F0         2EDE
+C8F1         2EE3
+C8F5         0283
+C8F6         0250
+C8F7         025B
+C8F8         0254
+C8F9         0275
+C8FA         0153
+C8FB         00F8
+C8FC         014B
+C8FD         028A
+C8FE         026A
+F9D6         7881
+F9D7         92B9
+F9D8         88CF
+F9D9         58BB
+F9DA         6052
+F9DB         7CA7
+F9DC         5AFA
+F9DD         2554
+F9DE         2566
+F9DF         2557
+F9E0         2560
+F9E1         256C
+F9E2         2563
+F9E3         255A
+F9E4         2569
+F9E5         255D
+F9E6         2552
+F9E7         2564
+F9E8         2555
+F9E9         255E
+F9EA         256A
+F9EB         2561
+F9EC         2558
+F9ED         2567
+F9EE         255B
+F9EF         2553
+F9F0         2565
+F9F1         2556
+F9F2         255F
+F9F3         256B
+F9F4         2562
+F9F5         2559
+F9F6         2568
+F9F7         255C
+F9F8         2551
+F9F9         2550
+F9FA         256D
+F9FB         256E
+F9FC         2570
+F9FD         256F
+F9FE         FFED
+FA40        20547
+FA41         92DB
+FA42        205DF
+FA43        23FC5
+FA44         854C
+FA45         42B5
+FA46         73EF
+FA47         51B5
+FA48         3649
+FA49        24942
+FA4A        289E4
+FA4B         9344
+FA4C        219DB
+FA4D         82EE
+FA4E        23CC8
+FA4F         783C
+FA50         6744
+FA51         62DF
+FA52        24933
+FA53        289AA
+FA54        202A0
+FA55        26BB3
+FA56        21305
+FA57         4FAB
+FA58        224ED
+FA59         5008
+FA5A        26D29
+FA5B        27A84
+FA5C        23600
+FA5D        24AB1
+FA5E        22513
+FA60        2037E
+FA61         5FA4
+FA62        20380
+FA63        20347
+FA64         6EDB
+FA65        2041F
+FA67         5101
+FA68         347A
+FA69         510E
+FA6A         986C
+FA6B         3743
+FA6C         8416
+FA6D        249A4
+FA6E        20487
+FA6F         5160
+FA70        233B4
+FA71         516A
+FA72        20BFF
+FA73        220FC
+FA74        202E5
+FA75        22530
+FA76        2058E
+FA77        23233
+FA78        21983
+FA79         5B82
+FA7A         877D
+FA7B        205B3
+FA7C        23C99
+FA7D         51B2
+FA7E         51B8
+FAA1         9D34
+FAA2         51C9
+FAA3         51CF
+FAA4         51D1
+FAA5         3CDC
+FAA6         51D3
+FAA7        24AA6
+FAA8         51B3
+FAA9         51E2
+FAAA         5342
+FAAB         51ED
+FAAC         83CD
+FAAD         693E
+FAAE        2372D
+FAAF         5F7B
+FAB0         520B
+FAB1         5226
+FAB2         523C
+FAB3         52B5
+FAB4         5257
+FAB5         5294
+FAB6         52B9
+FAB7         52C5
+FAB8         7C15
+FAB9         8542
+FABA         52E0
+FABB         860D
+FABC        26B13
+FABE        28ADE
+FABF         5549
+FAC0         6ED9
+FAC1        23F80
+FAC2        20954
+FAC3        23FEC
+FAC4         5333
+FAC6        20BE2
+FAC7         6CCB
+FAC8        21726
+FAC9         681B
+FACA         73D5
+FACB         604A
+FACC         3EAA
+FACD         38CC
+FACE        216E8
+FACF         71DD
+FAD0         44A2
+FAD1         536D
+FAD2         5374
+FAD3        286AB
+FAD4         537E
+FAD6        21596
+FAD7        21613
+FAD8         77E6
+FAD9         5393
+FADA        28A9B
+FADB         53A0
+FADC         53AB
+FADD         53AE
+FADE         73A7
+FADF        25772
+FAE0         3F59
+FAE1         739C
+FAE2         53C1
+FAE3         53C5
+FAE4         6C49
+FAE5         4E49
+FAE6         57FE
+FAE7         53D9
+FAE8         3AAB
+FAE9        20B8F
+FAEA         53E0
+FAEB        23FEB
+FAEC        22DA3
+FAED         53F6
+FAEE        20C77
+FAEF         5413
+FAF0         7079
+FAF1         552B
+FAF2         6657
+FAF3         6D5B
+FAF4         546D
+FAF5        26B53
+FAF6        20D74
+FAF7         555D
+FAF8         548F
+FAF9         54A4
+FAFA         47A6
+FAFB        2170D
+FAFC        20EDD
+FAFD         3DB4
+FAFE        20D4D
+FB40        289BC
+FB41        22698
+FB42         5547
+FB43         4CED
+FB44         542F
+FB45         7417
+FB46         5586
+FB47         55A9
+FB49        218D7
+FB4A        2403A
+FB4B         4552
+FB4C        24435
+FB4D         66B3
+FB4E        210B4
+FB4F         5637
+FB50         66CD
+FB51        2328A
+FB52         66A4
+FB53         66AD
+FB54         564D
+FB55         564F
+FB56         78F1
+FB57         56F1
+FB58         9787
+FB59         53FE
+FB5A         5700
+FB5B         56EF
+FB5C         56ED
+FB5D        28B66
+FB5E         3623
+FB5F        2124F
+FB60         5746
+FB61        241A5
+FB62         6C6E
+FB63         708B
+FB64         5742
+FB65         36B1
+FB66        26C7E
+FB67         57E6
+FB68        21416
+FB69         5803
+FB6A        21454
+FB6B        24363
+FB6C         5826
+FB6D        24BF5
+FB6E         585C
+FB6F         58AA
+FB70         3561
+FB71         58E0
+FB72         58DC
+FB73        2123C
+FB74         58FB
+FB75         5BFF
+FB76         5743
+FB77        2A150
+FB78        24278
+FB79         93D3
+FB7A         35A1
+FB7B         591F
+FB7C         68A6
+FB7D         36C3
+FB7E         6E59
+FBA1        2163E
+FBA2         5A24
+FBA3         5553
+FBA4        21692
+FBA5         8505
+FBA6         59C9
+FBA7        20D4E
+FBA8        26C81
+FBA9        26D2A
+FBAA        217DC
+FBAB         59D9
+FBAC        217FB
+FBAD        217B2
+FBAE        26DA6
+FBAF         6D71
+FBB0        21828
+FBB1        216D5
+FBB2         59F9
+FBB3        26E45
+FBB4         5AAB
+FBB5         5A63
+FBB6         36E6
+FBB7        249A9
+FBB9         3708
+FBBA         5A96
+FBBB         7465
+FBBC         5AD3
+FBBD        26FA1
+FBBE        22554
+FBBF         3D85
+FBC0        21911
+FBC1         3732
+FBC2        216B8
+FBC3         5E83
+FBC4         52D0
+FBC5         5B76
+FBC6         6588
+FBC7         5B7C
+FBC8        27A0E
+FBC9         4004
+FBCA         485D
+FBCB        20204
+FBCC         5BD5
+FBCD         6160
+FBCE        21A34
+FBCF        259CC
+FBD0        205A5
+FBD1         5BF3
+FBD2         5B9D
+FBD3         4D10
+FBD4         5C05
+FBD5        21B44
+FBD6         5C13
+FBD7         73CE
+FBD8         5C14
+FBD9        21CA5
+FBDA        26B28
+FBDB         5C49
+FBDC         48DD
+FBDD         5C85
+FBDE         5CE9
+FBDF         5CEF
+FBE0         5D8B
+FBE1        21DF9
+FBE2        21E37
+FBE3         5D10
+FBE4         5D18
+FBE5         5D46
+FBE6        21EA4
+FBE7         5CBA
+FBE8         5DD7
+FBE9         82FC
+FBEA         382D
+FBEB        24901
+FBEC        22049
+FBED        22173
+FBEE         8287
+FBEF         3836
+FBF0         3BC2
+FBF1         5E2E
+FBF2         6A8A
+FBF4         5E7A
+FBF5        244BC
+FBF6        20CD3
+FBF7         53A6
+FBF8         4EB7
+FBFA         53A8
+FBFB        21771
+FBFC         5E09
+FBFD         5EF4
+FBFE        28482
+FC40         5EF9
+FC41         5EFB
+FC42         38A0
+FC43         5EFC
+FC44         683E
+FC45         941B
+FC46         5F0D
+FC47        201C1
+FC48        2F894
+FC49         3ADE
+FC4A         48AE
+FC4B        2133A
+FC4C         5F3A
+FC4D        26888
+FC4E        223D0
+FC50        22471
+FC51         5F63
+FC52         97BD
+FC53        26E6E
+FC54         5F72
+FC55         9340
+FC56        28A36
+FC57         5FA7
+FC58         5DB6
+FC59         3D5F
+FC5A        25250
+FC5B        21F6A
+FC5C        270F8
+FC5D        22668
+FC5E         91D6
+FC5F        2029E
+FC60        28A29
+FC61         6031
+FC62         6685
+FC63        21877
+FC64         3963
+FC65         3DC7
+FC66         3639
+FC67         5790
+FC68        227B4
+FC69         7971
+FC6A         3E40
+FC6B         609E
+FC6D         60B3
+FC6E        24982
+FC6F        2498F
+FC70        27A53
+FC71         74A4
+FC72         50E1
+FC73         5AA0
+FC74         6164
+FC75         8424
+FC76         6142
+FC77        2F8A6
+FC78        26ED2
+FC79         6181
+FC7A         51F4
+FC7B        20656
+FC7C         6187
+FC7D         5BAA
+FC7E        23FB7
+FCA1        2285F
+FCA2         61D3
+FCA3        28B9D
+FCA4        2995D
+FCA5         61D0
+FCA6         3932
+FCA7        22980
+FCA8        228C1
+FCA9         6023
+FCAA         615C
+FCAB         651E
+FCAC         638B
+FCAD        20118
+FCAE         62C5
+FCAF        21770
+FCB0         62D5
+FCB1        22E0D
+FCB2         636C
+FCB3        249DF
+FCB4         3A17
+FCB5         6438
+FCB6         63F8
+FCB7        2138E
+FCB8        217FC
+FCBA         6F8A
+FCBB        22E36
+FCBC         9814
+FCBD        2408C
+FCBE        2571D
+FCBF         64E1
+FCC0         64E5
+FCC1         947B
+FCC2         3A66
+FCC3         643A
+FCC4         3A57
+FCC5         654D
+FCC6         6F16
+FCC7        24A28
+FCC8        24A23
+FCC9         6585
+FCCA         656D
+FCCB         655F
+FCCC        2307E
+FCCD         65B5
+FCCE        24940
+FCCF         4B37
+FCD0         65D1
+FCD1         40D8
+FCD2        21829
+FCD3         65E0
+FCD4         65E3
+FCD5         5FDF
+FCD6        23400
+FCD7         6618
+FCD8        231F7
+FCD9        231F8
+FCDA         6644
+FCDB        231A4
+FCDC        231A5
+FCDD         664B
+FCDE        20E75
+FCDF         6667
+FCE0        251E6
+FCE1         6673
+FCE3        21E3D
+FCE4        23231
+FCE5        285F4
+FCE6        231C8
+FCE7        25313
+FCE8         77C5
+FCE9        228F7
+FCEA         99A4
+FCEB         6702
+FCEC        2439C
+FCED        24A21
+FCEE         3B2B
+FCEF         69FA
+FCF0        237C2
+FCF2         6767
+FCF3         6762
+FCF4        241CD
+FCF5        290ED
+FCF6         67D7
+FCF7         44E9
+FCF8         6822
+FCF9         6E50
+FCFA         923C
+FCFB         6801
+FCFC        233E6
+FCFD        26DA0
+FCFE         685D
+FD40        2346F
+FD41         69E1
+FD42         6A0B
+FD43        28ADF
+FD44         6973
+FD45         68C3
+FD46        235CD
+FD47         6901
+FD48         6900
+FD49         3D32
+FD4A         3A01
+FD4B        2363C
+FD4C         3B80
+FD4D         67AC
+FD4E         6961
+FD4F        28A4A
+FD50         42FC
+FD51         6936
+FD52         6998
+FD53         3BA1
+FD54        203C9
+FD55         8363
+FD56         5090
+FD57         69F9
+FD58        23659
+FD59        2212A
+FD5A         6A45
+FD5B        23703
+FD5C         6A9D
+FD5D         3BF3
+FD5E         67B1
+FD5F         6AC8
+FD60        2919C
+FD61         3C0D
+FD62         6B1D
+FD63        20923
+FD64         60DE
+FD65         6B35
+FD66         6B74
+FD67        227CD
+FD68         6EB5
+FD69        23ADB
+FD6A        203B5
+FD6B        21958
+FD6C         3740
+FD6D         5421
+FD6E        23B5A
+FD6F         6BE1
+FD70        23EFC
+FD71         6BDC
+FD72         6C37
+FD73        2248B
+FD74        248F1
+FD75        26B51
+FD76         6C5A
+FD77         8226
+FD78         6C79
+FD79        23DBC
+FD7A         44C5
+FD7B        23DBD
+FD7C        241A4
+FD7D        2490C
+FD7E        24900
+FDA1        23CC9
+FDA2         36E5
+FDA3         3CEB
+FDA4        20D32
+FDA5         9B83
+FDA6        231F9
+FDA7        22491
+FDA8         7F8F
+FDA9         6837
+FDAA        26D25
+FDAB        26DA1
+FDAC        26DEB
+FDAD         6D96
+FDAE         6D5C
+FDAF         6E7C
+FDB0         6F04
+FDB1        2497F
+FDB2        24085
+FDB3        26E72
+FDB4         8533
+FDB5        26F74
+FDB6         51C7
+FDB9         842E
+FDBA        28B21
+FDBC        23E2F
+FDBD         7453
+FDBE        23F82
+FDBF         79CC
+FDC0         6E4F
+FDC1         5A91
+FDC2        2304B
+FDC3         6FF8
+FDC4         370D
+FDC5         6F9D
+FDC6        23E30
+FDC7         6EFA
+FDC8        21497
+FDC9        2403D
+FDCA         4555
+FDCB         93F0
+FDCC         6F44
+FDCD         6F5C
+FDCE         3D4E
+FDCF         6F74
+FDD0        29170
+FDD1         3D3B
+FDD2         6F9F
+FDD3        24144
+FDD4         6FD3
+FDD5        24091
+FDD6        24155
+FDD7        24039
+FDD8        23FF0
+FDD9        23FB4
+FDDA        2413F
+FDDB         51DF
+FDDC        24156
+FDDD        24157
+FDDE        24140
+FDDF        261DD
+FDE0         704B
+FDE1         707E
+FDE2         70A7
+FDE3         7081
+FDE4         70CC
+FDE5         70D5
+FDE6         70D6
+FDE7         70DF
+FDE8         4104
+FDE9         3DE8
+FDEA         71B4
+FDEB         7196
+FDEC        24277
+FDED         712B
+FDEE         7145
+FDEF         5A88
+FDF0         714A
+FDF2         5C9C
+FDF3        24365
+FDF4         714F
+FDF5         9362
+FDF6        242C1
+FDF7         712C
+FDF8        2445A
+FDF9        24A27
+FDFA        24A22
+FDFB         71BA
+FDFC        28BE8
+FDFD         70BD
+FDFE         720E
+FE40         9442
+FE41         7215
+FE42         5911
+FE43         9443
+FE44         7224
+FE45         9341
+FE46        25605
+FE47         722E
+FE48         7240
+FE49        24974
+FE4A         68BD
+FE4B         7255
+FE4C         7257
+FE4D         3E55
+FE4E        23044
+FE4F         680D
+FE50         6F3D
+FE51         7282
+FE53         732B
+FE54        24823
+FE55        2882B
+FE56         48ED
+FE57        28804
+FE58         7328
+FE59         732E
+FE5A         73CF
+FE5B         73AA
+FE5C        20C3A
+FE5D        26A2E
+FE5E         73C9
+FE5F         7449
+FE60        241E2
+FE61        216E7
+FE62        24A24
+FE63         6623
+FE64         36C5
+FE65        249B7
+FE66        2498D
+FE67        249FB
+FE68         73F7
+FE69         7415
+FE6A         6903
+FE6B        24A26
+FE6C         7439
+FE6D        205C3
+FE6E         3ED7
+FE70        228AD
+FE71         7460
+FE72        28EB2
+FE73         7447
+FE74         73E4
+FE75         7476
+FE76         83B9
+FE77         746C
+FE78         3730
+FE79         7474
+FE7A         93F1
+FE7B         6A2C
+FE7C         7482
+FE7D         4953
+FE7E        24A8C
+FEA1        2415F
+FEA2        24A79
+FEA3        28B8F
+FEA4         5B46
+FEA5        28C03
+FEA6        2189E
+FEA7         74C8
+FEA8        21988
+FEA9         750E
+FEAB         751E
+FEAC        28ED9
+FEAD        21A4B
+FEAE         5BD7
+FEAF        28EAC
+FEB0         9385
+FEB1         754D
+FEB2         754A
+FEB3         7567
+FEB4         756E
+FEB5        24F82
+FEB6         3F04
+FEB7        24D13
+FEB8         758E
+FEB9         745D
+FEBA         759E
+FEBB         75B4
+FEBC         7602
+FEBD         762C
+FEBE         7651
+FEBF         764F
+FEC0         766F
+FEC1         7676
+FEC2        263F5
+FEC3         7690
+FEC4         81EF
+FEC5         37F8
+FEC6        26911
+FEC7        2690E
+FEC8         76A1
+FEC9         76A5
+FECA         76B7
+FECB         76CC
+FECC        26F9F
+FECD         8462
+FECE        2509D
+FECF        2517D
+FED0        21E1C
+FED1         771E
+FED2         7726
+FED3         7740
+FED4         64AF
+FED5        25220
+FED6         7758
+FED7        232AC
+FED8         77AF
+FED9        28964
+FEDA        28968
+FEDB        216C1
+FEDC         77F4
+FEDE        21376
+FEDF        24A12
+FEE0         68CA
+FEE1         78AF
+FEE2         78C7
+FEE3         78D3
+FEE4         96A5
+FEE5         792E
+FEE6        255E0
+FEE7         78D7
+FEE8         7934
+FEE9         78B1
+FEEA        2760C
+FEEB         8FB8
+FEEC         8884
+FEED        28B2B
+FEEE        26083
+FEEF        2261C
+FEF0         7986
+FEF1         8900
+FEF2         6902
+FEF3         7980
+FEF4        25857
+FEF5         799D
+FEF6        27B39
+FEF7         793C
+FEF8         79A9
+FEF9         6E2A
+FEFA        27126
+FEFB         3EA8
+FEFC         79C6
+FEFD        2910D
+FEFE         79D4
diff --git a/make/data/currency/CurrencyData.properties b/make/data/currency/CurrencyData.properties
index 12c0c69..26f4aa2 100644
--- a/make/data/currency/CurrencyData.properties
+++ b/make/data/currency/CurrencyData.properties
@@ -32,7 +32,7 @@
 # Version of the currency code information in this class.
 # It is a serial number that accompanies with each amendment.
 
-dataVersion=175
+dataVersion=176
 
 # List of all valid ISO 4217 currency codes.
 # To ensure compatibility, do not remove codes.
@@ -55,7 +55,7 @@
     SRD968-SRG740-SSP728-STD678-STN930-SVC222-SYP760-SZL748-THB764-TJS972-TMM795-TMT934-TND788-TOP776-\
     TPE626-TRL792-TRY949-TTD780-TWD901-TZS834-UAH980-UGX800-USD840-USN997-USS998-UYI940-\
     UYU858-UZS860-VEB862-VED926-VEF937-VES928-VND704-VUV548-WST882-XAF950-XAG961-XAU959-XBA955-\
-    XBB956-XBC957-XBD958-XCD951-XDR960-XFO000-XFU000-XOF952-XPD964-XPF953-\
+    XBB956-XBC957-XBD958-XCD951-XCG532-XDR960-XFO000-XFU000-XOF952-XPD964-XPF953-\
     XPT962-XSU994-XTS963-XUA965-XXX999-YER886-YUM891-ZAR710-ZMK894-ZMW967-ZWD716-ZWL932-\
     ZWN942-ZWR935
 
@@ -189,11 +189,11 @@
 # COTE D'IVOIRE
 CI=XOF
 # CROATIA
-HR=HRK;2022-12-31-23-00-00;EUR
+HR=EUR
 # CUBA
 CU=CUP
 # Cura\u00e7ao
-CW=ANG
+CW=ANG;2025-04-01-04-00-00;XCG
 # CYPRUS
 CY=EUR
 # CZECHIA
@@ -510,7 +510,7 @@
 # SVALBARD AND JAN MAYEN
 SJ=NOK
 # Sint Maarten (Dutch part)
-SX=ANG
+SX=ANG;2025-04-01-04-00-00;XCG
 # ESWATINI
 SZ=SZL
 # SWEDEN
diff --git a/make/data/publicsuffixlist/VERSION b/make/data/publicsuffixlist/VERSION
index 4ffc88d..f86d2df 100644
--- a/make/data/publicsuffixlist/VERSION
+++ b/make/data/publicsuffixlist/VERSION
@@ -1,2 +1,2 @@
-Github: https://raw.githubusercontent.com/publicsuffix/list/88467c960d6cdad2ca1623e892e5e17506bc269f/public_suffix_list.dat
-Date: 2023-04-14
+Github: https://raw.githubusercontent.com/publicsuffix/list/b5bf572c52988dbe9d865b8f090ea819024a9936/public_suffix_list.dat
+Date: 2023-11-09
diff --git a/make/data/publicsuffixlist/public_suffix_list.dat b/make/data/publicsuffixlist/public_suffix_list.dat
index d9f0c71..fff6e9a 100644
--- a/make/data/publicsuffixlist/public_suffix_list.dat
+++ b/make/data/publicsuffixlist/public_suffix_list.dat
@@ -1059,22 +1059,11 @@
 nom.fr
 prd.fr
 tm.fr
-// Former "domaines sectoriels", still registration suffixes
-aeroport.fr
-avocat.fr
+// Other SLDs now selfmanaged out of AFNIC range. Former "domaines sectoriels", still registration suffixes
 avoues.fr
 cci.fr
-chambagri.fr
-chirurgiens-dentistes.fr
-experts-comptables.fr
-geometre-expert.fr
 greta.fr
 huissier-justice.fr
-medecin.fr
-notaires.fr
-pharmacien.fr
-port.fr
-veterinaire.fr
 
 // ga : https://en.wikipedia.org/wiki/.ga
 ga
@@ -5146,52 +5135,60 @@
 // Government domains
 gov.pl
 ap.gov.pl
+griw.gov.pl
 ic.gov.pl
 is.gov.pl
-us.gov.pl
 kmpsp.gov.pl
+konsulat.gov.pl
 kppsp.gov.pl
-kwpsp.gov.pl
-psp.gov.pl
-wskr.gov.pl
 kwp.gov.pl
+kwpsp.gov.pl
+mup.gov.pl
 mw.gov.pl
-ug.gov.pl
-um.gov.pl
-umig.gov.pl
-ugim.gov.pl
-upow.gov.pl
-uw.gov.pl
-starostwo.gov.pl
+oia.gov.pl
+oirm.gov.pl
+oke.gov.pl
+oow.gov.pl
+oschr.gov.pl
+oum.gov.pl
 pa.gov.pl
+pinb.gov.pl
+piw.gov.pl
 po.gov.pl
+pr.gov.pl
+psp.gov.pl
 psse.gov.pl
 pup.gov.pl
 rzgw.gov.pl
 sa.gov.pl
+sdn.gov.pl
+sko.gov.pl
 so.gov.pl
 sr.gov.pl
-wsa.gov.pl
-sko.gov.pl
+starostwo.gov.pl
+ug.gov.pl
+ugim.gov.pl
+um.gov.pl
+umig.gov.pl
+upow.gov.pl
+uppo.gov.pl
+us.gov.pl
+uw.gov.pl
 uzs.gov.pl
+wif.gov.pl
 wiih.gov.pl
 winb.gov.pl
-pinb.gov.pl
 wios.gov.pl
 witd.gov.pl
-wzmiuw.gov.pl
-piw.gov.pl
 wiw.gov.pl
-griw.gov.pl
-wif.gov.pl
-oum.gov.pl
-sdn.gov.pl
-zp.gov.pl
-uppo.gov.pl
-mup.gov.pl
+wkz.gov.pl
+wsa.gov.pl
+wskr.gov.pl
+wsse.gov.pl
 wuoz.gov.pl
-konsulat.gov.pl
-oirm.gov.pl
+wzmiuw.gov.pl
+zp.gov.pl
+zpisdn.gov.pl
 // pl regional domains (http://www.dns.pl/english/index.html)
 augustow.pl
 babia-gora.pl
@@ -5876,6 +5873,7 @@
 kirovograd.ua
 km.ua
 kr.ua
+kropyvnytskyi.ua
 krym.ua
 ks.ua
 kv.ua
@@ -5883,6 +5881,7 @@
 lg.ua
 lt.ua
 lugansk.ua
+luhansk.ua
 lutsk.ua
 lv.ua
 lviv.ua
@@ -5906,11 +5905,13 @@
 ternopil.ua
 uz.ua
 uzhgorod.ua
+uzhhorod.ua
 vinnica.ua
 vinnytsia.ua
 vn.ua
 volyn.ua
 yalta.ua
+zakarpattia.ua
 zaporizhzhe.ua
 zaporizhzhia.ua
 zhitomir.ua
@@ -6022,7 +6023,6 @@
 k12.co.us
 k12.ct.us
 k12.dc.us
-k12.de.us
 k12.fl.us
 k12.ga.us
 k12.gu.us
@@ -6264,20 +6264,89 @@
 net.vi
 org.vi
 
-// vn : https://www.dot.vn/vnnic/vnnic/domainregistration.jsp
+// vn : https://www.vnnic.vn/en/domain/cctld-vn
+// https://vnnic.vn/sites/default/files/tailieu/vn.cctld.domains.txt
 vn
+ac.vn
+ai.vn
+biz.vn
 com.vn
-net.vn
-org.vn
 edu.vn
 gov.vn
-int.vn
-ac.vn
-biz.vn
-info.vn
-name.vn
-pro.vn
 health.vn
+id.vn
+info.vn
+int.vn
+io.vn
+name.vn
+net.vn
+org.vn
+pro.vn
+
+// vn geographical names
+angiang.vn
+bacgiang.vn
+backan.vn
+baclieu.vn
+bacninh.vn
+baria-vungtau.vn
+bentre.vn
+binhdinh.vn
+binhduong.vn
+binhphuoc.vn
+binhthuan.vn
+camau.vn
+cantho.vn
+caobang.vn
+daklak.vn
+daknong.vn
+danang.vn
+dienbien.vn
+dongnai.vn
+dongthap.vn
+gialai.vn
+hagiang.vn
+haiduong.vn
+haiphong.vn
+hanam.vn
+hanoi.vn
+hatinh.vn
+haugiang.vn
+hoabinh.vn
+hungyen.vn
+khanhhoa.vn
+kiengiang.vn
+kontum.vn
+laichau.vn
+lamdong.vn
+langson.vn
+laocai.vn
+longan.vn
+namdinh.vn
+nghean.vn
+ninhbinh.vn
+ninhthuan.vn
+phutho.vn
+phuyen.vn
+quangbinh.vn
+quangnam.vn
+quangngai.vn
+quangninh.vn
+quangtri.vn
+soctrang.vn
+sonla.vn
+tayninh.vn
+thaibinh.vn
+thainguyen.vn
+thanhhoa.vn
+thanhphohochiminh.vn
+thuathienhue.vn
+tiengiang.vn
+travinh.vn
+tuyenquang.vn
+vinhlong.vn
+vinhphuc.vn
+yenbai.vn
 
 // vu : https://en.wikipedia.org/wiki/.vu
 // http://www.vunic.vu/
@@ -6641,3447 +6710,4506 @@
 
 // newGTLDs
 
-// List of new gTLDs imported from https://www.icann.org/resources/registries/gtlds/v2/gtlds.json on 2023-04-14T15:13:16Z
+// List of new gTLDs imported from https://www.icann.org/resources/registries/gtlds/v2/gtlds.json on 2023-11-03T15:13:18Z
 // This list is auto-generated, don't edit it manually.
-// aaa : 2015-02-26 American Automobile Association, Inc.
+// aaa : American Automobile Association, Inc.
+// https://www.iana.org/domains/root/db/aaa.html
 aaa
 
-// aarp : 2015-05-21 AARP
+// aarp : AARP
+// https://www.iana.org/domains/root/db/aarp.html
 aarp
 
-// abarth : 2015-07-30 Fiat Chrysler Automobiles N.V.
-abarth
-
-// abb : 2014-10-24 ABB Ltd
+// abb : ABB Ltd
+// https://www.iana.org/domains/root/db/abb.html
 abb
 
-// abbott : 2014-07-24 Abbott Laboratories, Inc.
+// abbott : Abbott Laboratories, Inc.
+// https://www.iana.org/domains/root/db/abbott.html
 abbott
 
-// abbvie : 2015-07-30 AbbVie Inc.
+// abbvie : AbbVie Inc.
+// https://www.iana.org/domains/root/db/abbvie.html
 abbvie
 
-// abc : 2015-07-30 Disney Enterprises, Inc.
+// abc : Disney Enterprises, Inc.
+// https://www.iana.org/domains/root/db/abc.html
 abc
 
-// able : 2015-06-25 Able Inc.
+// able : Able Inc.
+// https://www.iana.org/domains/root/db/able.html
 able
 
-// abogado : 2014-04-24 Registry Services, LLC
+// abogado : Registry Services, LLC
+// https://www.iana.org/domains/root/db/abogado.html
 abogado
 
-// abudhabi : 2015-07-30 Abu Dhabi Systems and Information Centre
+// abudhabi : Abu Dhabi Systems and Information Centre
+// https://www.iana.org/domains/root/db/abudhabi.html
 abudhabi
 
-// academy : 2013-11-07 Binky Moon, LLC
+// academy : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/academy.html
 academy
 
-// accenture : 2014-08-15 Accenture plc
+// accenture : Accenture plc
+// https://www.iana.org/domains/root/db/accenture.html
 accenture
 
-// accountant : 2014-11-20 dot Accountant Limited
+// accountant : dot Accountant Limited
+// https://www.iana.org/domains/root/db/accountant.html
 accountant
 
-// accountants : 2014-03-20 Binky Moon, LLC
+// accountants : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/accountants.html
 accountants
 
-// aco : 2015-01-08 ACO Severin Ahlmann GmbH & Co. KG
+// aco : ACO Severin Ahlmann GmbH & Co. KG
+// https://www.iana.org/domains/root/db/aco.html
 aco
 
-// actor : 2013-12-12 Dog Beach, LLC
+// actor : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/actor.html
 actor
 
-// ads : 2014-12-04 Charleston Road Registry Inc.
+// ads : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/ads.html
 ads
 
-// adult : 2014-10-16 ICM Registry AD LLC
+// adult : ICM Registry AD LLC
+// https://www.iana.org/domains/root/db/adult.html
 adult
 
-// aeg : 2015-03-19 Aktiebolaget Electrolux
+// aeg : Aktiebolaget Electrolux
+// https://www.iana.org/domains/root/db/aeg.html
 aeg
 
-// aetna : 2015-05-21 Aetna Life Insurance Company
+// aetna : Aetna Life Insurance Company
+// https://www.iana.org/domains/root/db/aetna.html
 aetna
 
-// afl : 2014-10-02 Australian Football League
+// afl : Australian Football League
+// https://www.iana.org/domains/root/db/afl.html
 afl
 
-// africa : 2014-03-24 ZA Central Registry NPC trading as Registry.Africa
+// africa : ZA Central Registry NPC trading as Registry.Africa
+// https://www.iana.org/domains/root/db/africa.html
 africa
 
-// agakhan : 2015-04-23 Fondation Aga Khan (Aga Khan Foundation)
+// agakhan : Fondation Aga Khan (Aga Khan Foundation)
+// https://www.iana.org/domains/root/db/agakhan.html
 agakhan
 
-// agency : 2013-11-14 Binky Moon, LLC
+// agency : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/agency.html
 agency
 
-// aig : 2014-12-18 American International Group, Inc.
+// aig : American International Group, Inc.
+// https://www.iana.org/domains/root/db/aig.html
 aig
 
-// airbus : 2015-07-30 Airbus S.A.S.
+// airbus : Airbus S.A.S.
+// https://www.iana.org/domains/root/db/airbus.html
 airbus
 
-// airforce : 2014-03-06 Dog Beach, LLC
+// airforce : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/airforce.html
 airforce
 
-// airtel : 2014-10-24 Bharti Airtel Limited
+// airtel : Bharti Airtel Limited
+// https://www.iana.org/domains/root/db/airtel.html
 airtel
 
-// akdn : 2015-04-23 Fondation Aga Khan (Aga Khan Foundation)
+// akdn : Fondation Aga Khan (Aga Khan Foundation)
+// https://www.iana.org/domains/root/db/akdn.html
 akdn
 
-// alfaromeo : 2015-07-31 Fiat Chrysler Automobiles N.V.
-alfaromeo
-
-// alibaba : 2015-01-15 Alibaba Group Holding Limited
+// alibaba : Alibaba Group Holding Limited
+// https://www.iana.org/domains/root/db/alibaba.html
 alibaba
 
-// alipay : 2015-01-15 Alibaba Group Holding Limited
+// alipay : Alibaba Group Holding Limited
+// https://www.iana.org/domains/root/db/alipay.html
 alipay
 
-// allfinanz : 2014-07-03 Allfinanz Deutsche Vermögensberatung Aktiengesellschaft
+// allfinanz : Allfinanz Deutsche Vermögensberatung Aktiengesellschaft
+// https://www.iana.org/domains/root/db/allfinanz.html
 allfinanz
 
-// allstate : 2015-07-31 Allstate Fire and Casualty Insurance Company
+// allstate : Allstate Fire and Casualty Insurance Company
+// https://www.iana.org/domains/root/db/allstate.html
 allstate
 
-// ally : 2015-06-18 Ally Financial Inc.
+// ally : Ally Financial Inc.
+// https://www.iana.org/domains/root/db/ally.html
 ally
 
-// alsace : 2014-07-02 Region Grand Est
+// alsace : Region Grand Est
+// https://www.iana.org/domains/root/db/alsace.html
 alsace
 
-// alstom : 2015-07-30 ALSTOM
+// alstom : ALSTOM
+// https://www.iana.org/domains/root/db/alstom.html
 alstom
 
-// amazon : 2019-12-19 Amazon Registry Services, Inc.
+// amazon : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/amazon.html
 amazon
 
-// americanexpress : 2015-07-31 American Express Travel Related Services Company, Inc.
+// americanexpress : American Express Travel Related Services Company, Inc.
+// https://www.iana.org/domains/root/db/americanexpress.html
 americanexpress
 
-// americanfamily : 2015-07-23 AmFam, Inc.
+// americanfamily : AmFam, Inc.
+// https://www.iana.org/domains/root/db/americanfamily.html
 americanfamily
 
-// amex : 2015-07-31 American Express Travel Related Services Company, Inc.
+// amex : American Express Travel Related Services Company, Inc.
+// https://www.iana.org/domains/root/db/amex.html
 amex
 
-// amfam : 2015-07-23 AmFam, Inc.
+// amfam : AmFam, Inc.
+// https://www.iana.org/domains/root/db/amfam.html
 amfam
 
-// amica : 2015-05-28 Amica Mutual Insurance Company
+// amica : Amica Mutual Insurance Company
+// https://www.iana.org/domains/root/db/amica.html
 amica
 
-// amsterdam : 2014-07-24 Gemeente Amsterdam
+// amsterdam : Gemeente Amsterdam
+// https://www.iana.org/domains/root/db/amsterdam.html
 amsterdam
 
-// analytics : 2014-12-18 Campus IP LLC
+// analytics : Campus IP LLC
+// https://www.iana.org/domains/root/db/analytics.html
 analytics
 
-// android : 2014-08-07 Charleston Road Registry Inc.
+// android : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/android.html
 android
 
-// anquan : 2015-01-08 Beijing Qihu Keji Co., Ltd.
+// anquan : Beijing Qihu Keji Co., Ltd.
+// https://www.iana.org/domains/root/db/anquan.html
 anquan
 
-// anz : 2015-07-31 Australia and New Zealand Banking Group Limited
+// anz : Australia and New Zealand Banking Group Limited
+// https://www.iana.org/domains/root/db/anz.html
 anz
 
-// aol : 2015-09-17 Oath Inc.
+// aol : Oath Inc.
+// https://www.iana.org/domains/root/db/aol.html
 aol
 
-// apartments : 2014-12-11 Binky Moon, LLC
+// apartments : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/apartments.html
 apartments
 
-// app : 2015-05-14 Charleston Road Registry Inc.
+// app : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/app.html
 app
 
-// apple : 2015-05-14 Apple Inc.
+// apple : Apple Inc.
+// https://www.iana.org/domains/root/db/apple.html
 apple
 
-// aquarelle : 2014-07-24 Aquarelle.com
+// aquarelle : Aquarelle.com
+// https://www.iana.org/domains/root/db/aquarelle.html
 aquarelle
 
-// arab : 2015-11-12 League of Arab States
+// arab : League of Arab States
+// https://www.iana.org/domains/root/db/arab.html
 arab
 
-// aramco : 2014-11-20 Aramco Services Company
+// aramco : Aramco Services Company
+// https://www.iana.org/domains/root/db/aramco.html
 aramco
 
-// archi : 2014-02-06 Identity Digital Limited
+// archi : Identity Digital Limited
+// https://www.iana.org/domains/root/db/archi.html
 archi
 
-// army : 2014-03-06 Dog Beach, LLC
+// army : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/army.html
 army
 
-// art : 2016-03-24 UK Creative Ideas Limited
+// art : UK Creative Ideas Limited
+// https://www.iana.org/domains/root/db/art.html
 art
 
-// arte : 2014-12-11 Association Relative à la Télévision Européenne G.E.I.E.
+// arte : Association Relative à la Télévision Européenne G.E.I.E.
+// https://www.iana.org/domains/root/db/arte.html
 arte
 
-// asda : 2015-07-31 Wal-Mart Stores, Inc.
+// asda : Wal-Mart Stores, Inc.
+// https://www.iana.org/domains/root/db/asda.html
 asda
 
-// associates : 2014-03-06 Binky Moon, LLC
+// associates : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/associates.html
 associates
 
-// athleta : 2015-07-30 The Gap, Inc.
+// athleta : The Gap, Inc.
+// https://www.iana.org/domains/root/db/athleta.html
 athleta
 
-// attorney : 2014-03-20 Dog Beach, LLC
+// attorney : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/attorney.html
 attorney
 
-// auction : 2014-03-20 Dog Beach, LLC
+// auction : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/auction.html
 auction
 
-// audi : 2015-05-21 AUDI Aktiengesellschaft
+// audi : AUDI Aktiengesellschaft
+// https://www.iana.org/domains/root/db/audi.html
 audi
 
-// audible : 2015-06-25 Amazon Registry Services, Inc.
+// audible : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/audible.html
 audible
 
-// audio : 2014-03-20 XYZ.COM LLC
+// audio : XYZ.COM LLC
+// https://www.iana.org/domains/root/db/audio.html
 audio
 
-// auspost : 2015-08-13 Australian Postal Corporation
+// auspost : Australian Postal Corporation
+// https://www.iana.org/domains/root/db/auspost.html
 auspost
 
-// author : 2014-12-18 Amazon Registry Services, Inc.
+// author : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/author.html
 author
 
-// auto : 2014-11-13 XYZ.COM LLC
+// auto : XYZ.COM LLC
+// https://www.iana.org/domains/root/db/auto.html
 auto
 
-// autos : 2014-01-09 XYZ.COM LLC
+// autos : XYZ.COM LLC
+// https://www.iana.org/domains/root/db/autos.html
 autos
 
-// avianca : 2015-01-08 Avianca Inc.
+// avianca : Avianca Inc.
+// https://www.iana.org/domains/root/db/avianca.html
 avianca
 
-// aws : 2015-06-25 AWS Registry LLC
+// aws : AWS Registry LLC
+// https://www.iana.org/domains/root/db/aws.html
 aws
 
-// axa : 2013-12-19 AXA Group Operations SAS
+// axa : AXA Group Operations SAS
+// https://www.iana.org/domains/root/db/axa.html
 axa
 
-// azure : 2014-12-18 Microsoft Corporation
+// azure : Microsoft Corporation
+// https://www.iana.org/domains/root/db/azure.html
 azure
 
-// baby : 2015-04-09 XYZ.COM LLC
+// baby : XYZ.COM LLC
+// https://www.iana.org/domains/root/db/baby.html
 baby
 
-// baidu : 2015-01-08 Baidu, Inc.
+// baidu : Baidu, Inc.
+// https://www.iana.org/domains/root/db/baidu.html
 baidu
 
-// banamex : 2015-07-30 Citigroup Inc.
+// banamex : Citigroup Inc.
+// https://www.iana.org/domains/root/db/banamex.html
 banamex
 
-// bananarepublic : 2015-07-31 The Gap, Inc.
+// bananarepublic : The Gap, Inc.
+// https://www.iana.org/domains/root/db/bananarepublic.html
 bananarepublic
 
-// band : 2014-06-12 Dog Beach, LLC
+// band : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/band.html
 band
 
-// bank : 2014-09-25 fTLD Registry Services LLC
+// bank : fTLD Registry Services LLC
+// https://www.iana.org/domains/root/db/bank.html
 bank
 
-// bar : 2013-12-12 Punto 2012 Sociedad Anonima Promotora de Inversion de Capital Variable
+// bar : Punto 2012 Sociedad Anonima Promotora de Inversion de Capital Variable
+// https://www.iana.org/domains/root/db/bar.html
 bar
 
-// barcelona : 2014-07-24 Municipi de Barcelona
+// barcelona : Municipi de Barcelona
+// https://www.iana.org/domains/root/db/barcelona.html
 barcelona
 
-// barclaycard : 2014-11-20 Barclays Bank PLC
+// barclaycard : Barclays Bank PLC
+// https://www.iana.org/domains/root/db/barclaycard.html
 barclaycard
 
-// barclays : 2014-11-20 Barclays Bank PLC
+// barclays : Barclays Bank PLC
+// https://www.iana.org/domains/root/db/barclays.html
 barclays
 
-// barefoot : 2015-06-11 Gallo Vineyards, Inc.
+// barefoot : Gallo Vineyards, Inc.
+// https://www.iana.org/domains/root/db/barefoot.html
 barefoot
 
-// bargains : 2013-11-14 Binky Moon, LLC
+// bargains : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/bargains.html
 bargains
 
-// baseball : 2015-10-29 MLB Advanced Media DH, LLC
+// baseball : MLB Advanced Media DH, LLC
+// https://www.iana.org/domains/root/db/baseball.html
 baseball
 
-// basketball : 2015-08-20 Fédération Internationale de Basketball (FIBA)
+// basketball : Fédération Internationale de Basketball (FIBA)
+// https://www.iana.org/domains/root/db/basketball.html
 basketball
 
-// bauhaus : 2014-04-17 Werkhaus GmbH
+// bauhaus : Werkhaus GmbH
+// https://www.iana.org/domains/root/db/bauhaus.html
 bauhaus
 
-// bayern : 2014-01-23 Bayern Connect GmbH
+// bayern : Bayern Connect GmbH
+// https://www.iana.org/domains/root/db/bayern.html
 bayern
 
-// bbc : 2014-12-18 British Broadcasting Corporation
+// bbc : British Broadcasting Corporation
+// https://www.iana.org/domains/root/db/bbc.html
 bbc
 
-// bbt : 2015-07-23 BB&T Corporation
+// bbt : BB&T Corporation
+// https://www.iana.org/domains/root/db/bbt.html
 bbt
 
-// bbva : 2014-10-02 BANCO BILBAO VIZCAYA ARGENTARIA, S.A.
+// bbva : BANCO BILBAO VIZCAYA ARGENTARIA, S.A.
+// https://www.iana.org/domains/root/db/bbva.html
 bbva
 
-// bcg : 2015-04-02 The Boston Consulting Group, Inc.
+// bcg : The Boston Consulting Group, Inc.
+// https://www.iana.org/domains/root/db/bcg.html
 bcg
 
-// bcn : 2014-07-24 Municipi de Barcelona
+// bcn : Municipi de Barcelona
+// https://www.iana.org/domains/root/db/bcn.html
 bcn
 
-// beats : 2015-05-14 Beats Electronics, LLC
+// beats : Beats Electronics, LLC
+// https://www.iana.org/domains/root/db/beats.html
 beats
 
-// beauty : 2015-12-03 XYZ.COM LLC
+// beauty : XYZ.COM LLC
+// https://www.iana.org/domains/root/db/beauty.html
 beauty
 
-// beer : 2014-01-09 Registry Services, LLC
+// beer : Registry Services, LLC
+// https://www.iana.org/domains/root/db/beer.html
 beer
 
-// bentley : 2014-12-18 Bentley Motors Limited
+// bentley : Bentley Motors Limited
+// https://www.iana.org/domains/root/db/bentley.html
 bentley
 
-// berlin : 2013-10-31 dotBERLIN GmbH & Co. KG
+// berlin : dotBERLIN GmbH & Co. KG
+// https://www.iana.org/domains/root/db/berlin.html
 berlin
 
-// best : 2013-12-19 BestTLD Pty Ltd
+// best : BestTLD Pty Ltd
+// https://www.iana.org/domains/root/db/best.html
 best
 
-// bestbuy : 2015-07-31 BBY Solutions, Inc.
+// bestbuy : BBY Solutions, Inc.
+// https://www.iana.org/domains/root/db/bestbuy.html
 bestbuy
 
-// bet : 2015-05-07 Identity Digital Limited
+// bet : Identity Digital Limited
+// https://www.iana.org/domains/root/db/bet.html
 bet
 
-// bharti : 2014-01-09 Bharti Enterprises (Holding) Private Limited
+// bharti : Bharti Enterprises (Holding) Private Limited
+// https://www.iana.org/domains/root/db/bharti.html
 bharti
 
-// bible : 2014-06-19 American Bible Society
+// bible : American Bible Society
+// https://www.iana.org/domains/root/db/bible.html
 bible
 
-// bid : 2013-12-19 dot Bid Limited
+// bid : dot Bid Limited
+// https://www.iana.org/domains/root/db/bid.html
 bid
 
-// bike : 2013-08-27 Binky Moon, LLC
+// bike : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/bike.html
 bike
 
-// bing : 2014-12-18 Microsoft Corporation
+// bing : Microsoft Corporation
+// https://www.iana.org/domains/root/db/bing.html
 bing
 
-// bingo : 2014-12-04 Binky Moon, LLC
+// bingo : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/bingo.html
 bingo
 
-// bio : 2014-03-06 Identity Digital Limited
+// bio : Identity Digital Limited
+// https://www.iana.org/domains/root/db/bio.html
 bio
 
-// black : 2014-01-16 Identity Digital Limited
+// black : Identity Digital Limited
+// https://www.iana.org/domains/root/db/black.html
 black
 
-// blackfriday : 2014-01-16 Registry Services, LLC
+// blackfriday : Registry Services, LLC
+// https://www.iana.org/domains/root/db/blackfriday.html
 blackfriday
 
-// blockbuster : 2015-07-30 Dish DBS Corporation
+// blockbuster : Dish DBS Corporation
+// https://www.iana.org/domains/root/db/blockbuster.html
 blockbuster
 
-// blog : 2015-05-14 Knock Knock WHOIS There, LLC
+// blog : Knock Knock WHOIS There, LLC
+// https://www.iana.org/domains/root/db/blog.html
 blog
 
-// bloomberg : 2014-07-17 Bloomberg IP Holdings LLC
+// bloomberg : Bloomberg IP Holdings LLC
+// https://www.iana.org/domains/root/db/bloomberg.html
 bloomberg
 
-// blue : 2013-11-07 Identity Digital Limited
+// blue : Identity Digital Limited
+// https://www.iana.org/domains/root/db/blue.html
 blue
 
-// bms : 2014-10-30 Bristol-Myers Squibb Company
+// bms : Bristol-Myers Squibb Company
+// https://www.iana.org/domains/root/db/bms.html
 bms
 
-// bmw : 2014-01-09 Bayerische Motoren Werke Aktiengesellschaft
+// bmw : Bayerische Motoren Werke Aktiengesellschaft
+// https://www.iana.org/domains/root/db/bmw.html
 bmw
 
-// bnpparibas : 2014-05-29 BNP Paribas
+// bnpparibas : BNP Paribas
+// https://www.iana.org/domains/root/db/bnpparibas.html
 bnpparibas
 
-// boats : 2014-12-04 XYZ.COM LLC
+// boats : XYZ.COM LLC
+// https://www.iana.org/domains/root/db/boats.html
 boats
 
-// boehringer : 2015-07-09 Boehringer Ingelheim International GmbH
+// boehringer : Boehringer Ingelheim International GmbH
+// https://www.iana.org/domains/root/db/boehringer.html
 boehringer
 
-// bofa : 2015-07-31 Bank of America Corporation
+// bofa : Bank of America Corporation
+// https://www.iana.org/domains/root/db/bofa.html
 bofa
 
-// bom : 2014-10-16 Núcleo de Informação e Coordenação do Ponto BR - NIC.br
+// bom : Núcleo de Informação e Coordenação do Ponto BR - NIC.br
+// https://www.iana.org/domains/root/db/bom.html
 bom
 
-// bond : 2014-06-05 ShortDot SA
+// bond : ShortDot SA
+// https://www.iana.org/domains/root/db/bond.html
 bond
 
-// boo : 2014-01-30 Charleston Road Registry Inc.
+// boo : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/boo.html
 boo
 
-// book : 2015-08-27 Amazon Registry Services, Inc.
+// book : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/book.html
 book
 
-// booking : 2015-07-16 Booking.com B.V.
+// booking : Booking.com B.V.
+// https://www.iana.org/domains/root/db/booking.html
 booking
 
-// bosch : 2015-06-18 Robert Bosch GMBH
+// bosch : Robert Bosch GMBH
+// https://www.iana.org/domains/root/db/bosch.html
 bosch
 
-// bostik : 2015-05-28 Bostik SA
+// bostik : Bostik SA
+// https://www.iana.org/domains/root/db/bostik.html
 bostik
 
-// boston : 2015-12-10 Registry Services, LLC
+// boston : Registry Services, LLC
+// https://www.iana.org/domains/root/db/boston.html
 boston
 
-// bot : 2014-12-18 Amazon Registry Services, Inc.
+// bot : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/bot.html
 bot
 
-// boutique : 2013-11-14 Binky Moon, LLC
+// boutique : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/boutique.html
 boutique
 
-// box : 2015-11-12 Intercap Registry Inc.
+// box : Intercap Registry Inc.
+// https://www.iana.org/domains/root/db/box.html
 box
 
-// bradesco : 2014-12-18 Banco Bradesco S.A.
+// bradesco : Banco Bradesco S.A.
+// https://www.iana.org/domains/root/db/bradesco.html
 bradesco
 
-// bridgestone : 2014-12-18 Bridgestone Corporation
+// bridgestone : Bridgestone Corporation
+// https://www.iana.org/domains/root/db/bridgestone.html
 bridgestone
 
-// broadway : 2014-12-22 Celebrate Broadway, Inc.
+// broadway : Celebrate Broadway, Inc.
+// https://www.iana.org/domains/root/db/broadway.html
 broadway
 
-// broker : 2014-12-11 Dog Beach, LLC
+// broker : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/broker.html
 broker
 
-// brother : 2015-01-29 Brother Industries, Ltd.
+// brother : Brother Industries, Ltd.
+// https://www.iana.org/domains/root/db/brother.html
 brother
 
-// brussels : 2014-02-06 DNS.be vzw
+// brussels : DNS.be vzw
+// https://www.iana.org/domains/root/db/brussels.html
 brussels
 
-// build : 2013-11-07 Plan Bee LLC
+// build : Plan Bee LLC
+// https://www.iana.org/domains/root/db/build.html
 build
 
-// builders : 2013-11-07 Binky Moon, LLC
+// builders : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/builders.html
 builders
 
-// business : 2013-11-07 Binky Moon, LLC
+// business : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/business.html
 business
 
-// buy : 2014-12-18 Amazon Registry Services, Inc.
+// buy : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/buy.html
 buy
 
-// buzz : 2013-10-02 DOTSTRATEGY CO.
+// buzz : DOTSTRATEGY CO.
+// https://www.iana.org/domains/root/db/buzz.html
 buzz
 
-// bzh : 2014-02-27 Association www.bzh
+// bzh : Association www.bzh
+// https://www.iana.org/domains/root/db/bzh.html
 bzh
 
-// cab : 2013-10-24 Binky Moon, LLC
+// cab : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/cab.html
 cab
 
-// cafe : 2015-02-11 Binky Moon, LLC
+// cafe : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/cafe.html
 cafe
 
-// cal : 2014-07-24 Charleston Road Registry Inc.
+// cal : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/cal.html
 cal
 
-// call : 2014-12-18 Amazon Registry Services, Inc.
+// call : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/call.html
 call
 
-// calvinklein : 2015-07-30 PVH gTLD Holdings LLC
+// calvinklein : PVH gTLD Holdings LLC
+// https://www.iana.org/domains/root/db/calvinklein.html
 calvinklein
 
-// cam : 2016-04-21 Cam Connecting SARL
+// cam : Cam Connecting SARL
+// https://www.iana.org/domains/root/db/cam.html
 cam
 
-// camera : 2013-08-27 Binky Moon, LLC
+// camera : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/camera.html
 camera
 
-// camp : 2013-11-07 Binky Moon, LLC
+// camp : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/camp.html
 camp
 
-// canon : 2014-09-12 Canon Inc.
+// canon : Canon Inc.
+// https://www.iana.org/domains/root/db/canon.html
 canon
 
-// capetown : 2014-03-24 ZA Central Registry NPC trading as ZA Central Registry
+// capetown : ZA Central Registry NPC trading as ZA Central Registry
+// https://www.iana.org/domains/root/db/capetown.html
 capetown
 
-// capital : 2014-03-06 Binky Moon, LLC
+// capital : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/capital.html
 capital
 
-// capitalone : 2015-08-06 Capital One Financial Corporation
+// capitalone : Capital One Financial Corporation
+// https://www.iana.org/domains/root/db/capitalone.html
 capitalone
 
-// car : 2015-01-22 XYZ.COM LLC
+// car : XYZ.COM LLC
+// https://www.iana.org/domains/root/db/car.html
 car
 
-// caravan : 2013-12-12 Caravan International, Inc.
+// caravan : Caravan International, Inc.
+// https://www.iana.org/domains/root/db/caravan.html
 caravan
 
-// cards : 2013-12-05 Binky Moon, LLC
+// cards : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/cards.html
 cards
 
-// care : 2014-03-06 Binky Moon, LLC
+// care : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/care.html
 care
 
-// career : 2013-10-09 dotCareer LLC
+// career : dotCareer LLC
+// https://www.iana.org/domains/root/db/career.html
 career
 
-// careers : 2013-10-02 Binky Moon, LLC
+// careers : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/careers.html
 careers
 
-// cars : 2014-11-13 XYZ.COM LLC
+// cars : XYZ.COM LLC
+// https://www.iana.org/domains/root/db/cars.html
 cars
 
-// casa : 2013-11-21 Registry Services, LLC
+// casa : Registry Services, LLC
+// https://www.iana.org/domains/root/db/casa.html
 casa
 
-// case : 2015-09-03 Digity, LLC
+// case : Digity, LLC
+// https://www.iana.org/domains/root/db/case.html
 case
 
-// cash : 2014-03-06 Binky Moon, LLC
+// cash : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/cash.html
 cash
 
-// casino : 2014-12-18 Binky Moon, LLC
+// casino : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/casino.html
 casino
 
-// catering : 2013-12-05 Binky Moon, LLC
+// catering : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/catering.html
 catering
 
-// catholic : 2015-10-21 Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication)
+// catholic : Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication)
+// https://www.iana.org/domains/root/db/catholic.html
 catholic
 
-// cba : 2014-06-26 COMMONWEALTH BANK OF AUSTRALIA
+// cba : COMMONWEALTH BANK OF AUSTRALIA
+// https://www.iana.org/domains/root/db/cba.html
 cba
 
-// cbn : 2014-08-22 The Christian Broadcasting Network, Inc.
+// cbn : The Christian Broadcasting Network, Inc.
+// https://www.iana.org/domains/root/db/cbn.html
 cbn
 
-// cbre : 2015-07-02 CBRE, Inc.
+// cbre : CBRE, Inc.
+// https://www.iana.org/domains/root/db/cbre.html
 cbre
 
-// cbs : 2015-08-06 CBS Domains Inc.
-cbs
-
-// center : 2013-11-07 Binky Moon, LLC
+// center : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/center.html
 center
 
-// ceo : 2013-11-07 CEOTLD Pty Ltd
+// ceo : XYZ.COM LLC
+// https://www.iana.org/domains/root/db/ceo.html
 ceo
 
-// cern : 2014-06-05 European Organization for Nuclear Research ("CERN")
+// cern : European Organization for Nuclear Research ("CERN")
+// https://www.iana.org/domains/root/db/cern.html
 cern
 
-// cfa : 2014-08-28 CFA Institute
+// cfa : CFA Institute
+// https://www.iana.org/domains/root/db/cfa.html
 cfa
 
-// cfd : 2014-12-11 ShortDot SA
+// cfd : ShortDot SA
+// https://www.iana.org/domains/root/db/cfd.html
 cfd
 
-// chanel : 2015-04-09 Chanel International B.V.
+// chanel : Chanel International B.V.
+// https://www.iana.org/domains/root/db/chanel.html
 chanel
 
-// channel : 2014-05-08 Charleston Road Registry Inc.
+// channel : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/channel.html
 channel
 
-// charity : 2018-04-11 Public Interest Registry
+// charity : Public Interest Registry
+// https://www.iana.org/domains/root/db/charity.html
 charity
 
-// chase : 2015-04-30 JPMorgan Chase Bank, National Association
+// chase : JPMorgan Chase Bank, National Association
+// https://www.iana.org/domains/root/db/chase.html
 chase
 
-// chat : 2014-12-04 Binky Moon, LLC
+// chat : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/chat.html
 chat
 
-// cheap : 2013-11-14 Binky Moon, LLC
+// cheap : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/cheap.html
 cheap
 
-// chintai : 2015-06-11 CHINTAI Corporation
+// chintai : CHINTAI Corporation
+// https://www.iana.org/domains/root/db/chintai.html
 chintai
 
-// christmas : 2013-11-21 XYZ.COM LLC
+// christmas : XYZ.COM LLC
+// https://www.iana.org/domains/root/db/christmas.html
 christmas
 
-// chrome : 2014-07-24 Charleston Road Registry Inc.
+// chrome : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/chrome.html
 chrome
 
-// church : 2014-02-06 Binky Moon, LLC
+// church : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/church.html
 church
 
-// cipriani : 2015-02-19 Hotel Cipriani Srl
+// cipriani : Hotel Cipriani Srl
+// https://www.iana.org/domains/root/db/cipriani.html
 cipriani
 
-// circle : 2014-12-18 Amazon Registry Services, Inc.
+// circle : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/circle.html
 circle
 
-// cisco : 2014-12-22 Cisco Technology, Inc.
+// cisco : Cisco Technology, Inc.
+// https://www.iana.org/domains/root/db/cisco.html
 cisco
 
-// citadel : 2015-07-23 Citadel Domain LLC
+// citadel : Citadel Domain LLC
+// https://www.iana.org/domains/root/db/citadel.html
 citadel
 
-// citi : 2015-07-30 Citigroup Inc.
+// citi : Citigroup Inc.
+// https://www.iana.org/domains/root/db/citi.html
 citi
 
-// citic : 2014-01-09 CITIC Group Corporation
+// citic : CITIC Group Corporation
+// https://www.iana.org/domains/root/db/citic.html
 citic
 
-// city : 2014-05-29 Binky Moon, LLC
+// city : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/city.html
 city
 
-// cityeats : 2014-12-11 Lifestyle Domain Holdings, Inc.
-cityeats
-
-// claims : 2014-03-20 Binky Moon, LLC
+// claims : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/claims.html
 claims
 
-// cleaning : 2013-12-05 Binky Moon, LLC
+// cleaning : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/cleaning.html
 cleaning
 
-// click : 2014-06-05 Internet Naming Company LLC
+// click : Internet Naming Company LLC
+// https://www.iana.org/domains/root/db/click.html
 click
 
-// clinic : 2014-03-20 Binky Moon, LLC
+// clinic : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/clinic.html
 clinic
 
-// clinique : 2015-10-01 The Estée Lauder Companies Inc.
+// clinique : The Estée Lauder Companies Inc.
+// https://www.iana.org/domains/root/db/clinique.html
 clinique
 
-// clothing : 2013-08-27 Binky Moon, LLC
+// clothing : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/clothing.html
 clothing
 
-// cloud : 2015-04-16 Aruba PEC S.p.A.
+// cloud : Aruba PEC S.p.A.
+// https://www.iana.org/domains/root/db/cloud.html
 cloud
 
-// club : 2013-11-08 Registry Services, LLC
+// club : Registry Services, LLC
+// https://www.iana.org/domains/root/db/club.html
 club
 
-// clubmed : 2015-06-25 Club Méditerranée S.A.
+// clubmed : Club Méditerranée S.A.
+// https://www.iana.org/domains/root/db/clubmed.html
 clubmed
 
-// coach : 2014-10-09 Binky Moon, LLC
+// coach : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/coach.html
 coach
 
-// codes : 2013-10-31 Binky Moon, LLC
+// codes : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/codes.html
 codes
 
-// coffee : 2013-10-17 Binky Moon, LLC
+// coffee : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/coffee.html
 coffee
 
-// college : 2014-01-16 XYZ.COM LLC
+// college : XYZ.COM LLC
+// https://www.iana.org/domains/root/db/college.html
 college
 
-// cologne : 2014-02-05 dotKoeln GmbH
+// cologne : dotKoeln GmbH
+// https://www.iana.org/domains/root/db/cologne.html
 cologne
 
-// comcast : 2015-07-23 Comcast IP Holdings I, LLC
+// comcast : Comcast IP Holdings I, LLC
+// https://www.iana.org/domains/root/db/comcast.html
 comcast
 
-// commbank : 2014-06-26 COMMONWEALTH BANK OF AUSTRALIA
+// commbank : COMMONWEALTH BANK OF AUSTRALIA
+// https://www.iana.org/domains/root/db/commbank.html
 commbank
 
-// community : 2013-12-05 Binky Moon, LLC
+// community : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/community.html
 community
 
-// company : 2013-11-07 Binky Moon, LLC
+// company : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/company.html
 company
 
-// compare : 2015-10-08 Registry Services, LLC
+// compare : Registry Services, LLC
+// https://www.iana.org/domains/root/db/compare.html
 compare
 
-// computer : 2013-10-24 Binky Moon, LLC
+// computer : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/computer.html
 computer
 
-// comsec : 2015-01-08 VeriSign, Inc.
+// comsec : VeriSign, Inc.
+// https://www.iana.org/domains/root/db/comsec.html
 comsec
 
-// condos : 2013-12-05 Binky Moon, LLC
+// condos : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/condos.html
 condos
 
-// construction : 2013-09-16 Binky Moon, LLC
+// construction : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/construction.html
 construction
 
-// consulting : 2013-12-05 Dog Beach, LLC
+// consulting : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/consulting.html
 consulting
 
-// contact : 2015-01-08 Dog Beach, LLC
+// contact : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/contact.html
 contact
 
-// contractors : 2013-09-10 Binky Moon, LLC
+// contractors : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/contractors.html
 contractors
 
-// cooking : 2013-11-21 Registry Services, LLC
+// cooking : Registry Services, LLC
+// https://www.iana.org/domains/root/db/cooking.html
 cooking
 
-// cookingchannel : 2015-07-02 Lifestyle Domain Holdings, Inc.
-cookingchannel
-
-// cool : 2013-11-14 Binky Moon, LLC
+// cool : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/cool.html
 cool
 
-// corsica : 2014-09-25 Collectivité de Corse
+// corsica : Collectivité de Corse
+// https://www.iana.org/domains/root/db/corsica.html
 corsica
 
-// country : 2013-12-19 Internet Naming Company LLC
+// country : Internet Naming Company LLC
+// https://www.iana.org/domains/root/db/country.html
 country
 
-// coupon : 2015-02-26 Amazon Registry Services, Inc.
+// coupon : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/coupon.html
 coupon
 
-// coupons : 2015-03-26 Binky Moon, LLC
+// coupons : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/coupons.html
 coupons
 
-// courses : 2014-12-04 Registry Services, LLC
+// courses : Registry Services, LLC
+// https://www.iana.org/domains/root/db/courses.html
 courses
 
-// cpa : 2019-06-10 American Institute of Certified Public Accountants
+// cpa : American Institute of Certified Public Accountants
+// https://www.iana.org/domains/root/db/cpa.html
 cpa
 
-// credit : 2014-03-20 Binky Moon, LLC
+// credit : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/credit.html
 credit
 
-// creditcard : 2014-03-20 Binky Moon, LLC
+// creditcard : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/creditcard.html
 creditcard
 
-// creditunion : 2015-01-22 DotCooperation LLC
+// creditunion : DotCooperation LLC
+// https://www.iana.org/domains/root/db/creditunion.html
 creditunion
 
-// cricket : 2014-10-09 dot Cricket Limited
+// cricket : dot Cricket Limited
+// https://www.iana.org/domains/root/db/cricket.html
 cricket
 
-// crown : 2014-10-24 Crown Equipment Corporation
+// crown : Crown Equipment Corporation
+// https://www.iana.org/domains/root/db/crown.html
 crown
 
-// crs : 2014-04-03 Federated Co-operatives Limited
+// crs : Federated Co-operatives Limited
+// https://www.iana.org/domains/root/db/crs.html
 crs
 
-// cruise : 2015-12-10 Viking River Cruises (Bermuda) Ltd.
+// cruise : Viking River Cruises (Bermuda) Ltd.
+// https://www.iana.org/domains/root/db/cruise.html
 cruise
 
-// cruises : 2013-12-05 Binky Moon, LLC
+// cruises : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/cruises.html
 cruises
 
-// cuisinella : 2014-04-03 SCHMIDT GROUPE S.A.S.
+// cuisinella : SCHMIDT GROUPE S.A.S.
+// https://www.iana.org/domains/root/db/cuisinella.html
 cuisinella
 
-// cymru : 2014-05-08 Nominet UK
+// cymru : Nominet UK
+// https://www.iana.org/domains/root/db/cymru.html
 cymru
 
-// cyou : 2015-01-22 ShortDot SA
+// cyou : ShortDot SA
+// https://www.iana.org/domains/root/db/cyou.html
 cyou
 
-// dabur : 2014-02-06 Dabur India Limited
+// dabur : Dabur India Limited
+// https://www.iana.org/domains/root/db/dabur.html
 dabur
 
-// dad : 2014-01-23 Charleston Road Registry Inc.
+// dad : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/dad.html
 dad
 
-// dance : 2013-10-24 Dog Beach, LLC
+// dance : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/dance.html
 dance
 
-// data : 2016-06-02 Dish DBS Corporation
+// data : Dish DBS Corporation
+// https://www.iana.org/domains/root/db/data.html
 data
 
-// date : 2014-11-20 dot Date Limited
+// date : dot Date Limited
+// https://www.iana.org/domains/root/db/date.html
 date
 
-// dating : 2013-12-05 Binky Moon, LLC
+// dating : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/dating.html
 dating
 
-// datsun : 2014-03-27 NISSAN MOTOR CO., LTD.
+// datsun : NISSAN MOTOR CO., LTD.
+// https://www.iana.org/domains/root/db/datsun.html
 datsun
 
-// day : 2014-01-30 Charleston Road Registry Inc.
+// day : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/day.html
 day
 
-// dclk : 2014-11-20 Charleston Road Registry Inc.
+// dclk : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/dclk.html
 dclk
 
-// dds : 2015-05-07 Registry Services, LLC
+// dds : Registry Services, LLC
+// https://www.iana.org/domains/root/db/dds.html
 dds
 
-// deal : 2015-06-25 Amazon Registry Services, Inc.
+// deal : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/deal.html
 deal
 
-// dealer : 2014-12-22 Intercap Registry Inc.
+// dealer : Intercap Registry Inc.
+// https://www.iana.org/domains/root/db/dealer.html
 dealer
 
-// deals : 2014-05-22 Binky Moon, LLC
+// deals : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/deals.html
 deals
 
-// degree : 2014-03-06 Dog Beach, LLC
+// degree : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/degree.html
 degree
 
-// delivery : 2014-09-11 Binky Moon, LLC
+// delivery : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/delivery.html
 delivery
 
-// dell : 2014-10-24 Dell Inc.
+// dell : Dell Inc.
+// https://www.iana.org/domains/root/db/dell.html
 dell
 
-// deloitte : 2015-07-31 Deloitte Touche Tohmatsu
+// deloitte : Deloitte Touche Tohmatsu
+// https://www.iana.org/domains/root/db/deloitte.html
 deloitte
 
-// delta : 2015-02-19 Delta Air Lines, Inc.
+// delta : Delta Air Lines, Inc.
+// https://www.iana.org/domains/root/db/delta.html
 delta
 
-// democrat : 2013-10-24 Dog Beach, LLC
+// democrat : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/democrat.html
 democrat
 
-// dental : 2014-03-20 Binky Moon, LLC
+// dental : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/dental.html
 dental
 
-// dentist : 2014-03-20 Dog Beach, LLC
+// dentist : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/dentist.html
 dentist
 
-// desi : 2013-11-14 Desi Networks LLC
-desi
-
-// design : 2014-11-07 Registry Services, LLC
+// design : Registry Services, LLC
+// https://www.iana.org/domains/root/db/design.html
 design
 
-// dev : 2014-10-16 Charleston Road Registry Inc.
+// dev : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/dev.html
 dev
 
-// dhl : 2015-07-23 Deutsche Post AG
+// dhl : Deutsche Post AG
+// https://www.iana.org/domains/root/db/dhl.html
 dhl
 
-// diamonds : 2013-09-22 Binky Moon, LLC
+// diamonds : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/diamonds.html
 diamonds
 
-// diet : 2014-06-26 XYZ.COM LLC
+// diet : XYZ.COM LLC
+// https://www.iana.org/domains/root/db/diet.html
 diet
 
-// digital : 2014-03-06 Binky Moon, LLC
+// digital : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/digital.html
 digital
 
-// direct : 2014-04-10 Binky Moon, LLC
+// direct : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/direct.html
 direct
 
-// directory : 2013-09-20 Binky Moon, LLC
+// directory : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/directory.html
 directory
 
-// discount : 2014-03-06 Binky Moon, LLC
+// discount : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/discount.html
 discount
 
-// discover : 2015-07-23 Discover Financial Services
+// discover : Discover Financial Services
+// https://www.iana.org/domains/root/db/discover.html
 discover
 
-// dish : 2015-07-30 Dish DBS Corporation
+// dish : Dish DBS Corporation
+// https://www.iana.org/domains/root/db/dish.html
 dish
 
-// diy : 2015-11-05 Lifestyle Domain Holdings, Inc.
+// diy : Lifestyle Domain Holdings, Inc.
+// https://www.iana.org/domains/root/db/diy.html
 diy
 
-// dnp : 2013-12-13 Dai Nippon Printing Co., Ltd.
+// dnp : Dai Nippon Printing Co., Ltd.
+// https://www.iana.org/domains/root/db/dnp.html
 dnp
 
-// docs : 2014-10-16 Charleston Road Registry Inc.
+// docs : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/docs.html
 docs
 
-// doctor : 2016-06-02 Binky Moon, LLC
+// doctor : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/doctor.html
 doctor
 
-// dog : 2014-12-04 Binky Moon, LLC
+// dog : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/dog.html
 dog
 
-// domains : 2013-10-17 Binky Moon, LLC
+// domains : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/domains.html
 domains
 
-// dot : 2015-05-21 Dish DBS Corporation
+// dot : Dish DBS Corporation
+// https://www.iana.org/domains/root/db/dot.html
 dot
 
-// download : 2014-11-20 dot Support Limited
+// download : dot Support Limited
+// https://www.iana.org/domains/root/db/download.html
 download
 
-// drive : 2015-03-05 Charleston Road Registry Inc.
+// drive : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/drive.html
 drive
 
-// dtv : 2015-06-04 Dish DBS Corporation
+// dtv : Dish DBS Corporation
+// https://www.iana.org/domains/root/db/dtv.html
 dtv
 
-// dubai : 2015-01-01 Dubai Smart Government Department
+// dubai : Dubai Smart Government Department
+// https://www.iana.org/domains/root/db/dubai.html
 dubai
 
-// dunlop : 2015-07-02 The Goodyear Tire & Rubber Company
+// dunlop : The Goodyear Tire & Rubber Company
+// https://www.iana.org/domains/root/db/dunlop.html
 dunlop
 
-// dupont : 2015-06-25 DuPont Specialty Products USA, LLC
+// dupont : DuPont Specialty Products USA, LLC
+// https://www.iana.org/domains/root/db/dupont.html
 dupont
 
-// durban : 2014-03-24 ZA Central Registry NPC trading as ZA Central Registry
+// durban : ZA Central Registry NPC trading as ZA Central Registry
+// https://www.iana.org/domains/root/db/durban.html
 durban
 
-// dvag : 2014-06-23 Deutsche Vermögensberatung Aktiengesellschaft DVAG
+// dvag : Deutsche Vermögensberatung Aktiengesellschaft DVAG
+// https://www.iana.org/domains/root/db/dvag.html
 dvag
 
-// dvr : 2016-05-26 DISH Technologies L.L.C.
+// dvr : DISH Technologies L.L.C.
+// https://www.iana.org/domains/root/db/dvr.html
 dvr
 
-// earth : 2014-12-04 Interlink Systems Innovation Institute K.K.
+// earth : Interlink Systems Innovation Institute K.K.
+// https://www.iana.org/domains/root/db/earth.html
 earth
 
-// eat : 2014-01-23 Charleston Road Registry Inc.
+// eat : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/eat.html
 eat
 
-// eco : 2016-07-08 Big Room Inc.
+// eco : Big Room Inc.
+// https://www.iana.org/domains/root/db/eco.html
 eco
 
-// edeka : 2014-12-18 EDEKA Verband kaufmännischer Genossenschaften e.V.
+// edeka : EDEKA Verband kaufmännischer Genossenschaften e.V.
+// https://www.iana.org/domains/root/db/edeka.html
 edeka
 
-// education : 2013-11-07 Binky Moon, LLC
+// education : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/education.html
 education
 
-// email : 2013-10-31 Binky Moon, LLC
+// email : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/email.html
 email
 
-// emerck : 2014-04-03 Merck KGaA
+// emerck : Merck KGaA
+// https://www.iana.org/domains/root/db/emerck.html
 emerck
 
-// energy : 2014-09-11 Binky Moon, LLC
+// energy : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/energy.html
 energy
 
-// engineer : 2014-03-06 Dog Beach, LLC
+// engineer : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/engineer.html
 engineer
 
-// engineering : 2014-03-06 Binky Moon, LLC
+// engineering : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/engineering.html
 engineering
 
-// enterprises : 2013-09-20 Binky Moon, LLC
+// enterprises : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/enterprises.html
 enterprises
 
-// epson : 2014-12-04 Seiko Epson Corporation
+// epson : Seiko Epson Corporation
+// https://www.iana.org/domains/root/db/epson.html
 epson
 
-// equipment : 2013-08-27 Binky Moon, LLC
+// equipment : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/equipment.html
 equipment
 
-// ericsson : 2015-07-09 Telefonaktiebolaget L M Ericsson
+// ericsson : Telefonaktiebolaget L M Ericsson
+// https://www.iana.org/domains/root/db/ericsson.html
 ericsson
 
-// erni : 2014-04-03 ERNI Group Holding AG
+// erni : ERNI Group Holding AG
+// https://www.iana.org/domains/root/db/erni.html
 erni
 
-// esq : 2014-05-08 Charleston Road Registry Inc.
+// esq : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/esq.html
 esq
 
-// estate : 2013-08-27 Binky Moon, LLC
+// estate : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/estate.html
 estate
 
-// etisalat : 2015-09-03 Emirates Telecommunications Corporation (trading as Etisalat)
+// etisalat : Emirates Telecommunications Corporation (trading as Etisalat)
+// https://www.iana.org/domains/root/db/etisalat.html
 etisalat
 
-// eurovision : 2014-04-24 European Broadcasting Union (EBU)
+// eurovision : European Broadcasting Union (EBU)
+// https://www.iana.org/domains/root/db/eurovision.html
 eurovision
 
-// eus : 2013-12-12 Puntueus Fundazioa
+// eus : Puntueus Fundazioa
+// https://www.iana.org/domains/root/db/eus.html
 eus
 
-// events : 2013-12-05 Binky Moon, LLC
+// events : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/events.html
 events
 
-// exchange : 2014-03-06 Binky Moon, LLC
+// exchange : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/exchange.html
 exchange
 
-// expert : 2013-11-21 Binky Moon, LLC
+// expert : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/expert.html
 expert
 
-// exposed : 2013-12-05 Binky Moon, LLC
+// exposed : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/exposed.html
 exposed
 
-// express : 2015-02-11 Binky Moon, LLC
+// express : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/express.html
 express
 
-// extraspace : 2015-05-14 Extra Space Storage LLC
+// extraspace : Extra Space Storage LLC
+// https://www.iana.org/domains/root/db/extraspace.html
 extraspace
 
-// fage : 2014-12-18 Fage International S.A.
+// fage : Fage International S.A.
+// https://www.iana.org/domains/root/db/fage.html
 fage
 
-// fail : 2014-03-06 Binky Moon, LLC
+// fail : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/fail.html
 fail
 
-// fairwinds : 2014-11-13 FairWinds Partners, LLC
+// fairwinds : FairWinds Partners, LLC
+// https://www.iana.org/domains/root/db/fairwinds.html
 fairwinds
 
-// faith : 2014-11-20 dot Faith Limited
+// faith : dot Faith Limited
+// https://www.iana.org/domains/root/db/faith.html
 faith
 
-// family : 2015-04-02 Dog Beach, LLC
+// family : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/family.html
 family
 
-// fan : 2014-03-06 Dog Beach, LLC
+// fan : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/fan.html
 fan
 
-// fans : 2014-11-07 ZDNS International Limited
+// fans : ZDNS International Limited
+// https://www.iana.org/domains/root/db/fans.html
 fans
 
-// farm : 2013-11-07 Binky Moon, LLC
+// farm : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/farm.html
 farm
 
-// farmers : 2015-07-09 Farmers Insurance Exchange
+// farmers : Farmers Insurance Exchange
+// https://www.iana.org/domains/root/db/farmers.html
 farmers
 
-// fashion : 2014-07-03 Registry Services, LLC
+// fashion : Registry Services, LLC
+// https://www.iana.org/domains/root/db/fashion.html
 fashion
 
-// fast : 2014-12-18 Amazon Registry Services, Inc.
+// fast : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/fast.html
 fast
 
-// fedex : 2015-08-06 Federal Express Corporation
+// fedex : Federal Express Corporation
+// https://www.iana.org/domains/root/db/fedex.html
 fedex
 
-// feedback : 2013-12-19 Top Level Spectrum, Inc.
+// feedback : Top Level Spectrum, Inc.
+// https://www.iana.org/domains/root/db/feedback.html
 feedback
 
-// ferrari : 2015-07-31 Fiat Chrysler Automobiles N.V.
+// ferrari : Fiat Chrysler Automobiles N.V.
+// https://www.iana.org/domains/root/db/ferrari.html
 ferrari
 
-// ferrero : 2014-12-18 Ferrero Trading Lux S.A.
+// ferrero : Ferrero Trading Lux S.A.
+// https://www.iana.org/domains/root/db/ferrero.html
 ferrero
 
-// fiat : 2015-07-31 Fiat Chrysler Automobiles N.V.
-fiat
-
-// fidelity : 2015-07-30 Fidelity Brokerage Services LLC
+// fidelity : Fidelity Brokerage Services LLC
+// https://www.iana.org/domains/root/db/fidelity.html
 fidelity
 
-// fido : 2015-08-06 Rogers Communications Canada Inc.
+// fido : Rogers Communications Canada Inc.
+// https://www.iana.org/domains/root/db/fido.html
 fido
 
-// film : 2015-01-08 Motion Picture Domain Registry Pty Ltd
+// film : Motion Picture Domain Registry Pty Ltd
+// https://www.iana.org/domains/root/db/film.html
 film
 
-// final : 2014-10-16 Núcleo de Informação e Coordenação do Ponto BR - NIC.br
+// final : Núcleo de Informação e Coordenação do Ponto BR - NIC.br
+// https://www.iana.org/domains/root/db/final.html
 final
 
-// finance : 2014-03-20 Binky Moon, LLC
+// finance : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/finance.html
 finance
 
-// financial : 2014-03-06 Binky Moon, LLC
+// financial : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/financial.html
 financial
 
-// fire : 2015-06-25 Amazon Registry Services, Inc.
+// fire : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/fire.html
 fire
 
-// firestone : 2014-12-18 Bridgestone Licensing Services, Inc
+// firestone : Bridgestone Licensing Services, Inc
+// https://www.iana.org/domains/root/db/firestone.html
 firestone
 
-// firmdale : 2014-03-27 Firmdale Holdings Limited
+// firmdale : Firmdale Holdings Limited
+// https://www.iana.org/domains/root/db/firmdale.html
 firmdale
 
-// fish : 2013-12-12 Binky Moon, LLC
+// fish : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/fish.html
 fish
 
-// fishing : 2013-11-21 Registry Services, LLC
+// fishing : Registry Services, LLC
+// https://www.iana.org/domains/root/db/fishing.html
 fishing
 
-// fit : 2014-11-07 Registry Services, LLC
+// fit : Registry Services, LLC
+// https://www.iana.org/domains/root/db/fit.html
 fit
 
-// fitness : 2014-03-06 Binky Moon, LLC
+// fitness : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/fitness.html
 fitness
 
-// flickr : 2015-04-02 Flickr, Inc.
+// flickr : Flickr, Inc.
+// https://www.iana.org/domains/root/db/flickr.html
 flickr
 
-// flights : 2013-12-05 Binky Moon, LLC
+// flights : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/flights.html
 flights
 
-// flir : 2015-07-23 FLIR Systems, Inc.
+// flir : FLIR Systems, Inc.
+// https://www.iana.org/domains/root/db/flir.html
 flir
 
-// florist : 2013-11-07 Binky Moon, LLC
+// florist : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/florist.html
 florist
 
-// flowers : 2014-10-09 XYZ.COM LLC
+// flowers : XYZ.COM LLC
+// https://www.iana.org/domains/root/db/flowers.html
 flowers
 
-// fly : 2014-05-08 Charleston Road Registry Inc.
+// fly : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/fly.html
 fly
 
-// foo : 2014-01-23 Charleston Road Registry Inc.
+// foo : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/foo.html
 foo
 
-// food : 2016-04-21 Lifestyle Domain Holdings, Inc.
+// food : Lifestyle Domain Holdings, Inc.
+// https://www.iana.org/domains/root/db/food.html
 food
 
-// foodnetwork : 2015-07-02 Lifestyle Domain Holdings, Inc.
-foodnetwork
-
-// football : 2014-12-18 Binky Moon, LLC
+// football : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/football.html
 football
 
-// ford : 2014-11-13 Ford Motor Company
+// ford : Ford Motor Company
+// https://www.iana.org/domains/root/db/ford.html
 ford
 
-// forex : 2014-12-11 Dog Beach, LLC
+// forex : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/forex.html
 forex
 
-// forsale : 2014-05-22 Dog Beach, LLC
+// forsale : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/forsale.html
 forsale
 
-// forum : 2015-04-02 Fegistry, LLC
+// forum : Fegistry, LLC
+// https://www.iana.org/domains/root/db/forum.html
 forum
 
-// foundation : 2013-12-05 Public Interest Registry
+// foundation : Public Interest Registry
+// https://www.iana.org/domains/root/db/foundation.html
 foundation
 
-// fox : 2015-09-11 FOX Registry, LLC
+// fox : FOX Registry, LLC
+// https://www.iana.org/domains/root/db/fox.html
 fox
 
-// free : 2015-12-10 Amazon Registry Services, Inc.
+// free : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/free.html
 free
 
-// fresenius : 2015-07-30 Fresenius Immobilien-Verwaltungs-GmbH
+// fresenius : Fresenius Immobilien-Verwaltungs-GmbH
+// https://www.iana.org/domains/root/db/fresenius.html
 fresenius
 
-// frl : 2014-05-15 FRLregistry B.V.
+// frl : FRLregistry B.V.
+// https://www.iana.org/domains/root/db/frl.html
 frl
 
-// frogans : 2013-12-19 OP3FT
+// frogans : OP3FT
+// https://www.iana.org/domains/root/db/frogans.html
 frogans
 
-// frontdoor : 2015-07-02 Lifestyle Domain Holdings, Inc.
-frontdoor
-
-// frontier : 2015-02-05 Frontier Communications Corporation
+// frontier : Frontier Communications Corporation
+// https://www.iana.org/domains/root/db/frontier.html
 frontier
 
-// ftr : 2015-07-16 Frontier Communications Corporation
+// ftr : Frontier Communications Corporation
+// https://www.iana.org/domains/root/db/ftr.html
 ftr
 
-// fujitsu : 2015-07-30 Fujitsu Limited
+// fujitsu : Fujitsu Limited
+// https://www.iana.org/domains/root/db/fujitsu.html
 fujitsu
 
-// fun : 2016-01-14 Radix FZC
+// fun : Radix FZC DMCC
+// https://www.iana.org/domains/root/db/fun.html
 fun
 
-// fund : 2014-03-20 Binky Moon, LLC
+// fund : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/fund.html
 fund
 
-// furniture : 2014-03-20 Binky Moon, LLC
+// furniture : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/furniture.html
 furniture
 
-// futbol : 2013-09-20 Dog Beach, LLC
+// futbol : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/futbol.html
 futbol
 
-// fyi : 2015-04-02 Binky Moon, LLC
+// fyi : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/fyi.html
 fyi
 
-// gal : 2013-11-07 Asociación puntoGAL
+// gal : Asociación puntoGAL
+// https://www.iana.org/domains/root/db/gal.html
 gal
 
-// gallery : 2013-09-13 Binky Moon, LLC
+// gallery : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/gallery.html
 gallery
 
-// gallo : 2015-06-11 Gallo Vineyards, Inc.
+// gallo : Gallo Vineyards, Inc.
+// https://www.iana.org/domains/root/db/gallo.html
 gallo
 
-// gallup : 2015-02-19 Gallup, Inc.
+// gallup : Gallup, Inc.
+// https://www.iana.org/domains/root/db/gallup.html
 gallup
 
-// game : 2015-05-28 XYZ.COM LLC
+// game : XYZ.COM LLC
+// https://www.iana.org/domains/root/db/game.html
 game
 
-// games : 2015-05-28 Dog Beach, LLC
+// games : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/games.html
 games
 
-// gap : 2015-07-31 The Gap, Inc.
+// gap : The Gap, Inc.
+// https://www.iana.org/domains/root/db/gap.html
 gap
 
-// garden : 2014-06-26 Registry Services, LLC
+// garden : Registry Services, LLC
+// https://www.iana.org/domains/root/db/garden.html
 garden
 
-// gay : 2019-05-23 Top Level Design, LLC
+// gay : Registry Services, LLC
+// https://www.iana.org/domains/root/db/gay.html
 gay
 
-// gbiz : 2014-07-17 Charleston Road Registry Inc.
+// gbiz : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/gbiz.html
 gbiz
 
-// gdn : 2014-07-31 Joint Stock Company "Navigation-information systems"
+// gdn : Joint Stock Company "Navigation-information systems"
+// https://www.iana.org/domains/root/db/gdn.html
 gdn
 
-// gea : 2014-12-04 GEA Group Aktiengesellschaft
+// gea : GEA Group Aktiengesellschaft
+// https://www.iana.org/domains/root/db/gea.html
 gea
 
-// gent : 2014-01-23 Easyhost BV
+// gent : Easyhost BV
+// https://www.iana.org/domains/root/db/gent.html
 gent
 
-// genting : 2015-03-12 Resorts World Inc Pte. Ltd.
+// genting : Resorts World Inc Pte. Ltd.
+// https://www.iana.org/domains/root/db/genting.html
 genting
 
-// george : 2015-07-31 Wal-Mart Stores, Inc.
+// george : Wal-Mart Stores, Inc.
+// https://www.iana.org/domains/root/db/george.html
 george
 
-// ggee : 2014-01-09 GMO Internet, Inc.
+// ggee : GMO Internet, Inc.
+// https://www.iana.org/domains/root/db/ggee.html
 ggee
 
-// gift : 2013-10-17 DotGift, LLC
+// gift : DotGift, LLC
+// https://www.iana.org/domains/root/db/gift.html
 gift
 
-// gifts : 2014-07-03 Binky Moon, LLC
+// gifts : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/gifts.html
 gifts
 
-// gives : 2014-03-06 Public Interest Registry
+// gives : Public Interest Registry
+// https://www.iana.org/domains/root/db/gives.html
 gives
 
-// giving : 2014-11-13 Public Interest Registry
+// giving : Public Interest Registry
+// https://www.iana.org/domains/root/db/giving.html
 giving
 
-// glass : 2013-11-07 Binky Moon, LLC
+// glass : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/glass.html
 glass
 
-// gle : 2014-07-24 Charleston Road Registry Inc.
+// gle : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/gle.html
 gle
 
-// global : 2014-04-17 Identity Digital Limited
+// global : Identity Digital Limited
+// https://www.iana.org/domains/root/db/global.html
 global
 
-// globo : 2013-12-19 Globo Comunicação e Participações S.A
+// globo : Globo Comunicação e Participações S.A
+// https://www.iana.org/domains/root/db/globo.html
 globo
 
-// gmail : 2014-05-01 Charleston Road Registry Inc.
+// gmail : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/gmail.html
 gmail
 
-// gmbh : 2016-01-29 Binky Moon, LLC
+// gmbh : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/gmbh.html
 gmbh
 
-// gmo : 2014-01-09 GMO Internet, Inc.
+// gmo : GMO Internet, Inc.
+// https://www.iana.org/domains/root/db/gmo.html
 gmo
 
-// gmx : 2014-04-24 1&1 Mail & Media GmbH
+// gmx : 1&1 Mail & Media GmbH
+// https://www.iana.org/domains/root/db/gmx.html
 gmx
 
-// godaddy : 2015-07-23 Go Daddy East, LLC
+// godaddy : Go Daddy East, LLC
+// https://www.iana.org/domains/root/db/godaddy.html
 godaddy
 
-// gold : 2015-01-22 Binky Moon, LLC
+// gold : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/gold.html
 gold
 
-// goldpoint : 2014-11-20 YODOBASHI CAMERA CO.,LTD.
+// goldpoint : YODOBASHI CAMERA CO.,LTD.
+// https://www.iana.org/domains/root/db/goldpoint.html
 goldpoint
 
-// golf : 2014-12-18 Binky Moon, LLC
+// golf : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/golf.html
 golf
 
-// goo : 2014-12-18 NTT Resonant Inc.
+// goo : NTT Resonant Inc.
+// https://www.iana.org/domains/root/db/goo.html
 goo
 
-// goodyear : 2015-07-02 The Goodyear Tire & Rubber Company
+// goodyear : The Goodyear Tire & Rubber Company
+// https://www.iana.org/domains/root/db/goodyear.html
 goodyear
 
-// goog : 2014-11-20 Charleston Road Registry Inc.
+// goog : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/goog.html
 goog
 
-// google : 2014-07-24 Charleston Road Registry Inc.
+// google : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/google.html
 google
 
-// gop : 2014-01-16 Republican State Leadership Committee, Inc.
+// gop : Republican State Leadership Committee, Inc.
+// https://www.iana.org/domains/root/db/gop.html
 gop
 
-// got : 2014-12-18 Amazon Registry Services, Inc.
+// got : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/got.html
 got
 
-// grainger : 2015-05-07 Grainger Registry Services, LLC
+// grainger : Grainger Registry Services, LLC
+// https://www.iana.org/domains/root/db/grainger.html
 grainger
 
-// graphics : 2013-09-13 Binky Moon, LLC
+// graphics : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/graphics.html
 graphics
 
-// gratis : 2014-03-20 Binky Moon, LLC
+// gratis : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/gratis.html
 gratis
 
-// green : 2014-05-08 Identity Digital Limited
+// green : Identity Digital Limited
+// https://www.iana.org/domains/root/db/green.html
 green
 
-// gripe : 2014-03-06 Binky Moon, LLC
+// gripe : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/gripe.html
 gripe
 
-// grocery : 2016-06-16 Wal-Mart Stores, Inc.
+// grocery : Wal-Mart Stores, Inc.
+// https://www.iana.org/domains/root/db/grocery.html
 grocery
 
-// group : 2014-08-15 Binky Moon, LLC
+// group : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/group.html
 group
 
-// guardian : 2015-07-30 The Guardian Life Insurance Company of America
+// guardian : The Guardian Life Insurance Company of America
+// https://www.iana.org/domains/root/db/guardian.html
 guardian
 
-// gucci : 2014-11-13 Guccio Gucci S.p.a.
+// gucci : Guccio Gucci S.p.a.
+// https://www.iana.org/domains/root/db/gucci.html
 gucci
 
-// guge : 2014-08-28 Charleston Road Registry Inc.
+// guge : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/guge.html
 guge
 
-// guide : 2013-09-13 Binky Moon, LLC
+// guide : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/guide.html
 guide
 
-// guitars : 2013-11-14 XYZ.COM LLC
+// guitars : XYZ.COM LLC
+// https://www.iana.org/domains/root/db/guitars.html
 guitars
 
-// guru : 2013-08-27 Binky Moon, LLC
+// guru : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/guru.html
 guru
 
-// hair : 2015-12-03 XYZ.COM LLC
+// hair : XYZ.COM LLC
+// https://www.iana.org/domains/root/db/hair.html
 hair
 
-// hamburg : 2014-02-20 Hamburg Top-Level-Domain GmbH
+// hamburg : Hamburg Top-Level-Domain GmbH
+// https://www.iana.org/domains/root/db/hamburg.html
 hamburg
 
-// hangout : 2014-11-13 Charleston Road Registry Inc.
+// hangout : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/hangout.html
 hangout
 
-// haus : 2013-12-05 Dog Beach, LLC
+// haus : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/haus.html
 haus
 
-// hbo : 2015-07-30 HBO Registry Services, Inc.
+// hbo : HBO Registry Services, Inc.
+// https://www.iana.org/domains/root/db/hbo.html
 hbo
 
-// hdfc : 2015-07-30 HOUSING DEVELOPMENT FINANCE CORPORATION LIMITED
+// hdfc : HOUSING DEVELOPMENT FINANCE CORPORATION LIMITED
+// https://www.iana.org/domains/root/db/hdfc.html
 hdfc
 
-// hdfcbank : 2015-02-12 HDFC Bank Limited
+// hdfcbank : HDFC Bank Limited
+// https://www.iana.org/domains/root/db/hdfcbank.html
 hdfcbank
 
-// health : 2015-02-11 DotHealth, LLC
+// health : Registry Services, LLC
+// https://www.iana.org/domains/root/db/health.html
 health
 
-// healthcare : 2014-06-12 Binky Moon, LLC
+// healthcare : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/healthcare.html
 healthcare
 
-// help : 2014-06-26 Innovation service Limited
+// help : Innovation service Limited
+// https://www.iana.org/domains/root/db/help.html
 help
 
-// helsinki : 2015-02-05 City of Helsinki
+// helsinki : City of Helsinki
+// https://www.iana.org/domains/root/db/helsinki.html
 helsinki
 
-// here : 2014-02-06 Charleston Road Registry Inc.
+// here : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/here.html
 here
 
-// hermes : 2014-07-10 HERMES INTERNATIONAL
+// hermes : HERMES INTERNATIONAL
+// https://www.iana.org/domains/root/db/hermes.html
 hermes
 
-// hgtv : 2015-07-02 Lifestyle Domain Holdings, Inc.
-hgtv
-
-// hiphop : 2014-03-06 Dot Hip Hop, LLC
+// hiphop : Dot Hip Hop, LLC
+// https://www.iana.org/domains/root/db/hiphop.html
 hiphop
 
-// hisamitsu : 2015-07-16 Hisamitsu Pharmaceutical Co.,Inc.
+// hisamitsu : Hisamitsu Pharmaceutical Co.,Inc.
+// https://www.iana.org/domains/root/db/hisamitsu.html
 hisamitsu
 
-// hitachi : 2014-10-31 Hitachi, Ltd.
+// hitachi : Hitachi, Ltd.
+// https://www.iana.org/domains/root/db/hitachi.html
 hitachi
 
-// hiv : 2014-03-13 Internet Naming Company LLC
+// hiv : Internet Naming Company LLC
+// https://www.iana.org/domains/root/db/hiv.html
 hiv
 
-// hkt : 2015-05-14 PCCW-HKT DataCom Services Limited
+// hkt : PCCW-HKT DataCom Services Limited
+// https://www.iana.org/domains/root/db/hkt.html
 hkt
 
-// hockey : 2015-03-19 Binky Moon, LLC
+// hockey : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/hockey.html
 hockey
 
-// holdings : 2013-08-27 Binky Moon, LLC
+// holdings : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/holdings.html
 holdings
 
-// holiday : 2013-11-07 Binky Moon, LLC
+// holiday : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/holiday.html
 holiday
 
-// homedepot : 2015-04-02 Home Depot Product Authority, LLC
+// homedepot : Home Depot Product Authority, LLC
+// https://www.iana.org/domains/root/db/homedepot.html
 homedepot
 
-// homegoods : 2015-07-16 The TJX Companies, Inc.
+// homegoods : The TJX Companies, Inc.
+// https://www.iana.org/domains/root/db/homegoods.html
 homegoods
 
-// homes : 2014-01-09 XYZ.COM LLC
+// homes : XYZ.COM LLC
+// https://www.iana.org/domains/root/db/homes.html
 homes
 
-// homesense : 2015-07-16 The TJX Companies, Inc.
+// homesense : The TJX Companies, Inc.
+// https://www.iana.org/domains/root/db/homesense.html
 homesense
 
-// honda : 2014-12-18 Honda Motor Co., Ltd.
+// honda : Honda Motor Co., Ltd.
+// https://www.iana.org/domains/root/db/honda.html
 honda
 
-// horse : 2013-11-21 Registry Services, LLC
+// horse : Registry Services, LLC
+// https://www.iana.org/domains/root/db/horse.html
 horse
 
-// hospital : 2016-10-20 Binky Moon, LLC
+// hospital : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/hospital.html
 hospital
 
-// host : 2014-04-17 Radix FZC
+// host : Radix FZC DMCC
+// https://www.iana.org/domains/root/db/host.html
 host
 
-// hosting : 2014-05-29 XYZ.COM LLC
+// hosting : XYZ.COM LLC
+// https://www.iana.org/domains/root/db/hosting.html
 hosting
 
-// hot : 2015-08-27 Amazon Registry Services, Inc.
+// hot : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/hot.html
 hot
 
-// hoteles : 2015-03-05 Travel Reservations SRL
-hoteles
-
-// hotels : 2016-04-07 Booking.com B.V.
+// hotels : Booking.com B.V.
+// https://www.iana.org/domains/root/db/hotels.html
 hotels
 
-// hotmail : 2014-12-18 Microsoft Corporation
+// hotmail : Microsoft Corporation
+// https://www.iana.org/domains/root/db/hotmail.html
 hotmail
 
-// house : 2013-11-07 Binky Moon, LLC
+// house : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/house.html
 house
 
-// how : 2014-01-23 Charleston Road Registry Inc.
+// how : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/how.html
 how
 
-// hsbc : 2014-10-24 HSBC Global Services (UK) Limited
+// hsbc : HSBC Global Services (UK) Limited
+// https://www.iana.org/domains/root/db/hsbc.html
 hsbc
 
-// hughes : 2015-07-30 Hughes Satellite Systems Corporation
+// hughes : Hughes Satellite Systems Corporation
+// https://www.iana.org/domains/root/db/hughes.html
 hughes
 
-// hyatt : 2015-07-30 Hyatt GTLD, L.L.C.
+// hyatt : Hyatt GTLD, L.L.C.
+// https://www.iana.org/domains/root/db/hyatt.html
 hyatt
 
-// hyundai : 2015-07-09 Hyundai Motor Company
+// hyundai : Hyundai Motor Company
+// https://www.iana.org/domains/root/db/hyundai.html
 hyundai
 
-// ibm : 2014-07-31 International Business Machines Corporation
+// ibm : International Business Machines Corporation
+// https://www.iana.org/domains/root/db/ibm.html
 ibm
 
-// icbc : 2015-02-19 Industrial and Commercial Bank of China Limited
+// icbc : Industrial and Commercial Bank of China Limited
+// https://www.iana.org/domains/root/db/icbc.html
 icbc
 
-// ice : 2014-10-30 IntercontinentalExchange, Inc.
+// ice : IntercontinentalExchange, Inc.
+// https://www.iana.org/domains/root/db/ice.html
 ice
 
-// icu : 2015-01-08 ShortDot SA
+// icu : ShortDot SA
+// https://www.iana.org/domains/root/db/icu.html
 icu
 
-// ieee : 2015-07-23 IEEE Global LLC
+// ieee : IEEE Global LLC
+// https://www.iana.org/domains/root/db/ieee.html
 ieee
 
-// ifm : 2014-01-30 ifm electronic gmbh
+// ifm : ifm electronic gmbh
+// https://www.iana.org/domains/root/db/ifm.html
 ifm
 
-// ikano : 2015-07-09 Ikano S.A.
+// ikano : Ikano S.A.
+// https://www.iana.org/domains/root/db/ikano.html
 ikano
 
-// imamat : 2015-08-06 Fondation Aga Khan (Aga Khan Foundation)
+// imamat : Fondation Aga Khan (Aga Khan Foundation)
+// https://www.iana.org/domains/root/db/imamat.html
 imamat
 
-// imdb : 2015-06-25 Amazon Registry Services, Inc.
+// imdb : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/imdb.html
 imdb
 
-// immo : 2014-07-10 Binky Moon, LLC
+// immo : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/immo.html
 immo
 
-// immobilien : 2013-11-07 Dog Beach, LLC
+// immobilien : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/immobilien.html
 immobilien
 
-// inc : 2018-03-10 Intercap Registry Inc.
+// inc : Intercap Registry Inc.
+// https://www.iana.org/domains/root/db/inc.html
 inc
 
-// industries : 2013-12-05 Binky Moon, LLC
+// industries : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/industries.html
 industries
 
-// infiniti : 2014-03-27 NISSAN MOTOR CO., LTD.
+// infiniti : NISSAN MOTOR CO., LTD.
+// https://www.iana.org/domains/root/db/infiniti.html
 infiniti
 
-// ing : 2014-01-23 Charleston Road Registry Inc.
+// ing : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/ing.html
 ing
 
-// ink : 2013-12-05 Top Level Design, LLC
+// ink : Registry Services, LLC
+// https://www.iana.org/domains/root/db/ink.html
 ink
 
-// institute : 2013-11-07 Binky Moon, LLC
+// institute : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/institute.html
 institute
 
-// insurance : 2015-02-19 fTLD Registry Services LLC
+// insurance : fTLD Registry Services LLC
+// https://www.iana.org/domains/root/db/insurance.html
 insurance
 
-// insure : 2014-03-20 Binky Moon, LLC
+// insure : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/insure.html
 insure
 
-// international : 2013-11-07 Binky Moon, LLC
+// international : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/international.html
 international
 
-// intuit : 2015-07-30 Intuit Administrative Services, Inc.
+// intuit : Intuit Administrative Services, Inc.
+// https://www.iana.org/domains/root/db/intuit.html
 intuit
 
-// investments : 2014-03-20 Binky Moon, LLC
+// investments : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/investments.html
 investments
 
-// ipiranga : 2014-08-28 Ipiranga Produtos de Petroleo S.A.
+// ipiranga : Ipiranga Produtos de Petroleo S.A.
+// https://www.iana.org/domains/root/db/ipiranga.html
 ipiranga
 
-// irish : 2014-08-07 Binky Moon, LLC
+// irish : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/irish.html
 irish
 
-// ismaili : 2015-08-06 Fondation Aga Khan (Aga Khan Foundation)
+// ismaili : Fondation Aga Khan (Aga Khan Foundation)
+// https://www.iana.org/domains/root/db/ismaili.html
 ismaili
 
-// ist : 2014-08-28 Istanbul Metropolitan Municipality
+// ist : Istanbul Metropolitan Municipality
+// https://www.iana.org/domains/root/db/ist.html
 ist
 
-// istanbul : 2014-08-28 Istanbul Metropolitan Municipality
+// istanbul : Istanbul Metropolitan Municipality
+// https://www.iana.org/domains/root/db/istanbul.html
 istanbul
 
-// itau : 2014-10-02 Itau Unibanco Holding S.A.
+// itau : Itau Unibanco Holding S.A.
+// https://www.iana.org/domains/root/db/itau.html
 itau
 
-// itv : 2015-07-09 ITV Services Limited
+// itv : ITV Services Limited
+// https://www.iana.org/domains/root/db/itv.html
 itv
 
-// jaguar : 2014-11-13 Jaguar Land Rover Ltd
+// jaguar : Jaguar Land Rover Ltd
+// https://www.iana.org/domains/root/db/jaguar.html
 jaguar
 
-// java : 2014-06-19 Oracle Corporation
+// java : Oracle Corporation
+// https://www.iana.org/domains/root/db/java.html
 java
 
-// jcb : 2014-11-20 JCB Co., Ltd.
+// jcb : JCB Co., Ltd.
+// https://www.iana.org/domains/root/db/jcb.html
 jcb
 
-// jeep : 2015-07-30 FCA US LLC.
+// jeep : FCA US LLC.
+// https://www.iana.org/domains/root/db/jeep.html
 jeep
 
-// jetzt : 2014-01-09 Binky Moon, LLC
+// jetzt : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/jetzt.html
 jetzt
 
-// jewelry : 2015-03-05 Binky Moon, LLC
+// jewelry : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/jewelry.html
 jewelry
 
-// jio : 2015-04-02 Reliance Industries Limited
+// jio : Reliance Industries Limited
+// https://www.iana.org/domains/root/db/jio.html
 jio
 
-// jll : 2015-04-02 Jones Lang LaSalle Incorporated
+// jll : Jones Lang LaSalle Incorporated
+// https://www.iana.org/domains/root/db/jll.html
 jll
 
-// jmp : 2015-03-26 Matrix IP LLC
+// jmp : Matrix IP LLC
+// https://www.iana.org/domains/root/db/jmp.html
 jmp
 
-// jnj : 2015-06-18 Johnson & Johnson Services, Inc.
+// jnj : Johnson & Johnson Services, Inc.
+// https://www.iana.org/domains/root/db/jnj.html
 jnj
 
-// joburg : 2014-03-24 ZA Central Registry NPC trading as ZA Central Registry
+// joburg : ZA Central Registry NPC trading as ZA Central Registry
+// https://www.iana.org/domains/root/db/joburg.html
 joburg
 
-// jot : 2014-12-18 Amazon Registry Services, Inc.
+// jot : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/jot.html
 jot
 
-// joy : 2014-12-18 Amazon Registry Services, Inc.
+// joy : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/joy.html
 joy
 
-// jpmorgan : 2015-04-30 JPMorgan Chase Bank, National Association
+// jpmorgan : JPMorgan Chase Bank, National Association
+// https://www.iana.org/domains/root/db/jpmorgan.html
 jpmorgan
 
-// jprs : 2014-09-18 Japan Registry Services Co., Ltd.
+// jprs : Japan Registry Services Co., Ltd.
+// https://www.iana.org/domains/root/db/jprs.html
 jprs
 
-// juegos : 2014-03-20 Internet Naming Company LLC
+// juegos : Internet Naming Company LLC
+// https://www.iana.org/domains/root/db/juegos.html
 juegos
 
-// juniper : 2015-07-30 JUNIPER NETWORKS, INC.
+// juniper : JUNIPER NETWORKS, INC.
+// https://www.iana.org/domains/root/db/juniper.html
 juniper
 
-// kaufen : 2013-11-07 Dog Beach, LLC
+// kaufen : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/kaufen.html
 kaufen
 
-// kddi : 2014-09-12 KDDI CORPORATION
+// kddi : KDDI CORPORATION
+// https://www.iana.org/domains/root/db/kddi.html
 kddi
 
-// kerryhotels : 2015-04-30 Kerry Trading Co. Limited
+// kerryhotels : Kerry Trading Co. Limited
+// https://www.iana.org/domains/root/db/kerryhotels.html
 kerryhotels
 
-// kerrylogistics : 2015-04-09 Kerry Trading Co. Limited
+// kerrylogistics : Kerry Trading Co. Limited
+// https://www.iana.org/domains/root/db/kerrylogistics.html
 kerrylogistics
 
-// kerryproperties : 2015-04-09 Kerry Trading Co. Limited
+// kerryproperties : Kerry Trading Co. Limited
+// https://www.iana.org/domains/root/db/kerryproperties.html
 kerryproperties
 
-// kfh : 2014-12-04 Kuwait Finance House
+// kfh : Kuwait Finance House
+// https://www.iana.org/domains/root/db/kfh.html
 kfh
 
-// kia : 2015-07-09 KIA MOTORS CORPORATION
+// kia : KIA MOTORS CORPORATION
+// https://www.iana.org/domains/root/db/kia.html
 kia
 
-// kids : 2021-08-13 DotKids Foundation Limited
+// kids : DotKids Foundation Limited
+// https://www.iana.org/domains/root/db/kids.html
 kids
 
-// kim : 2013-09-23 Identity Digital Limited
+// kim : Identity Digital Limited
+// https://www.iana.org/domains/root/db/kim.html
 kim
 
-// kinder : 2014-11-07 Ferrero Trading Lux S.A.
-kinder
-
-// kindle : 2015-06-25 Amazon Registry Services, Inc.
+// kindle : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/kindle.html
 kindle
 
-// kitchen : 2013-09-20 Binky Moon, LLC
+// kitchen : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/kitchen.html
 kitchen
 
-// kiwi : 2013-09-20 DOT KIWI LIMITED
+// kiwi : DOT KIWI LIMITED
+// https://www.iana.org/domains/root/db/kiwi.html
 kiwi
 
-// koeln : 2014-01-09 dotKoeln GmbH
+// koeln : dotKoeln GmbH
+// https://www.iana.org/domains/root/db/koeln.html
 koeln
 
-// komatsu : 2015-01-08 Komatsu Ltd.
+// komatsu : Komatsu Ltd.
+// https://www.iana.org/domains/root/db/komatsu.html
 komatsu
 
-// kosher : 2015-08-20 Kosher Marketing Assets LLC
+// kosher : Kosher Marketing Assets LLC
+// https://www.iana.org/domains/root/db/kosher.html
 kosher
 
-// kpmg : 2015-04-23 KPMG International Cooperative (KPMG International Genossenschaft)
+// kpmg : KPMG International Cooperative (KPMG International Genossenschaft)
+// https://www.iana.org/domains/root/db/kpmg.html
 kpmg
 
-// kpn : 2015-01-08 Koninklijke KPN N.V.
+// kpn : Koninklijke KPN N.V.
+// https://www.iana.org/domains/root/db/kpn.html
 kpn
 
-// krd : 2013-12-05 KRG Department of Information Technology
+// krd : KRG Department of Information Technology
+// https://www.iana.org/domains/root/db/krd.html
 krd
 
-// kred : 2013-12-19 KredTLD Pty Ltd
+// kred : KredTLD Pty Ltd
+// https://www.iana.org/domains/root/db/kred.html
 kred
 
-// kuokgroup : 2015-04-09 Kerry Trading Co. Limited
+// kuokgroup : Kerry Trading Co. Limited
+// https://www.iana.org/domains/root/db/kuokgroup.html
 kuokgroup
 
-// kyoto : 2014-11-07 Academic Institution: Kyoto Jyoho Gakuen
+// kyoto : Academic Institution: Kyoto Jyoho Gakuen
+// https://www.iana.org/domains/root/db/kyoto.html
 kyoto
 
-// lacaixa : 2014-01-09 Fundación Bancaria Caixa d’Estalvis i Pensions de Barcelona, “la Caixa”
+// lacaixa : Fundación Bancaria Caixa d’Estalvis i Pensions de Barcelona, “la Caixa”
+// https://www.iana.org/domains/root/db/lacaixa.html
 lacaixa
 
-// lamborghini : 2015-06-04 Automobili Lamborghini S.p.A.
+// lamborghini : Automobili Lamborghini S.p.A.
+// https://www.iana.org/domains/root/db/lamborghini.html
 lamborghini
 
-// lamer : 2015-10-01 The Estée Lauder Companies Inc.
+// lamer : The Estée Lauder Companies Inc.
+// https://www.iana.org/domains/root/db/lamer.html
 lamer
 
-// lancaster : 2015-02-12 LANCASTER
+// lancaster : LANCASTER
+// https://www.iana.org/domains/root/db/lancaster.html
 lancaster
 
-// lancia : 2015-07-31 Fiat Chrysler Automobiles N.V.
-lancia
-
-// land : 2013-09-10 Binky Moon, LLC
+// land : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/land.html
 land
 
-// landrover : 2014-11-13 Jaguar Land Rover Ltd
+// landrover : Jaguar Land Rover Ltd
+// https://www.iana.org/domains/root/db/landrover.html
 landrover
 
-// lanxess : 2015-07-30 LANXESS Corporation
+// lanxess : LANXESS Corporation
+// https://www.iana.org/domains/root/db/lanxess.html
 lanxess
 
-// lasalle : 2015-04-02 Jones Lang LaSalle Incorporated
+// lasalle : Jones Lang LaSalle Incorporated
+// https://www.iana.org/domains/root/db/lasalle.html
 lasalle
 
-// lat : 2014-10-16 XYZ.COM LLC
+// lat : XYZ.COM LLC
+// https://www.iana.org/domains/root/db/lat.html
 lat
 
-// latino : 2015-07-30 Dish DBS Corporation
+// latino : Dish DBS Corporation
+// https://www.iana.org/domains/root/db/latino.html
 latino
 
-// latrobe : 2014-06-16 La Trobe University
+// latrobe : La Trobe University
+// https://www.iana.org/domains/root/db/latrobe.html
 latrobe
 
-// law : 2015-01-22 Registry Services, LLC
+// law : Registry Services, LLC
+// https://www.iana.org/domains/root/db/law.html
 law
 
-// lawyer : 2014-03-20 Dog Beach, LLC
+// lawyer : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/lawyer.html
 lawyer
 
-// lds : 2014-03-20 IRI Domain Management, LLC
+// lds : IRI Domain Management, LLC
+// https://www.iana.org/domains/root/db/lds.html
 lds
 
-// lease : 2014-03-06 Binky Moon, LLC
+// lease : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/lease.html
 lease
 
-// leclerc : 2014-08-07 A.C.D. LEC Association des Centres Distributeurs Edouard Leclerc
+// leclerc : A.C.D. LEC Association des Centres Distributeurs Edouard Leclerc
+// https://www.iana.org/domains/root/db/leclerc.html
 leclerc
 
-// lefrak : 2015-07-16 LeFrak Organization, Inc.
+// lefrak : LeFrak Organization, Inc.
+// https://www.iana.org/domains/root/db/lefrak.html
 lefrak
 
-// legal : 2014-10-16 Binky Moon, LLC
+// legal : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/legal.html
 legal
 
-// lego : 2015-07-16 LEGO Juris A/S
+// lego : LEGO Juris A/S
+// https://www.iana.org/domains/root/db/lego.html
 lego
 
-// lexus : 2015-04-23 TOYOTA MOTOR CORPORATION
+// lexus : TOYOTA MOTOR CORPORATION
+// https://www.iana.org/domains/root/db/lexus.html
 lexus
 
-// lgbt : 2014-05-08 Identity Digital Limited
+// lgbt : Identity Digital Limited
+// https://www.iana.org/domains/root/db/lgbt.html
 lgbt
 
-// lidl : 2014-09-18 Schwarz Domains und Services GmbH & Co. KG
+// lidl : Schwarz Domains und Services GmbH & Co. KG
+// https://www.iana.org/domains/root/db/lidl.html
 lidl
 
-// life : 2014-02-06 Binky Moon, LLC
+// life : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/life.html
 life
 
-// lifeinsurance : 2015-01-15 American Council of Life Insurers
+// lifeinsurance : American Council of Life Insurers
+// https://www.iana.org/domains/root/db/lifeinsurance.html
 lifeinsurance
 
-// lifestyle : 2014-12-11 Lifestyle Domain Holdings, Inc.
+// lifestyle : Lifestyle Domain Holdings, Inc.
+// https://www.iana.org/domains/root/db/lifestyle.html
 lifestyle
 
-// lighting : 2013-08-27 Binky Moon, LLC
+// lighting : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/lighting.html
 lighting
 
-// like : 2014-12-18 Amazon Registry Services, Inc.
+// like : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/like.html
 like
 
-// lilly : 2015-07-31 Eli Lilly and Company
+// lilly : Eli Lilly and Company
+// https://www.iana.org/domains/root/db/lilly.html
 lilly
 
-// limited : 2014-03-06 Binky Moon, LLC
+// limited : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/limited.html
 limited
 
-// limo : 2013-10-17 Binky Moon, LLC
+// limo : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/limo.html
 limo
 
-// lincoln : 2014-11-13 Ford Motor Company
+// lincoln : Ford Motor Company
+// https://www.iana.org/domains/root/db/lincoln.html
 lincoln
 
-// link : 2013-11-14 Nova Registry Ltd
+// link : Nova Registry Ltd
+// https://www.iana.org/domains/root/db/link.html
 link
 
-// lipsy : 2015-06-25 Lipsy Ltd
+// lipsy : Lipsy Ltd
+// https://www.iana.org/domains/root/db/lipsy.html
 lipsy
 
-// live : 2014-12-04 Dog Beach, LLC
+// live : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/live.html
 live
 
-// living : 2015-07-30 Lifestyle Domain Holdings, Inc.
+// living : Lifestyle Domain Holdings, Inc.
+// https://www.iana.org/domains/root/db/living.html
 living
 
-// llc : 2017-12-14 Identity Digital Limited
+// llc : Identity Digital Limited
+// https://www.iana.org/domains/root/db/llc.html
 llc
 
-// llp : 2019-08-26 Intercap Registry Inc.
+// llp : Intercap Registry Inc.
+// https://www.iana.org/domains/root/db/llp.html
 llp
 
-// loan : 2014-11-20 dot Loan Limited
+// loan : dot Loan Limited
+// https://www.iana.org/domains/root/db/loan.html
 loan
 
-// loans : 2014-03-20 Binky Moon, LLC
+// loans : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/loans.html
 loans
 
-// locker : 2015-06-04 Dish DBS Corporation
+// locker : Orange Domains LLC
+// https://www.iana.org/domains/root/db/locker.html
 locker
 
-// locus : 2015-06-25 Locus Analytics LLC
+// locus : Locus Analytics LLC
+// https://www.iana.org/domains/root/db/locus.html
 locus
 
-// lol : 2015-01-30 XYZ.COM LLC
+// lol : XYZ.COM LLC
+// https://www.iana.org/domains/root/db/lol.html
 lol
 
-// london : 2013-11-14 Dot London Domains Limited
+// london : Dot London Domains Limited
+// https://www.iana.org/domains/root/db/london.html
 london
 
-// lotte : 2014-11-07 Lotte Holdings Co., Ltd.
+// lotte : Lotte Holdings Co., Ltd.
+// https://www.iana.org/domains/root/db/lotte.html
 lotte
 
-// lotto : 2014-04-10 Identity Digital Limited
+// lotto : Identity Digital Limited
+// https://www.iana.org/domains/root/db/lotto.html
 lotto
 
-// love : 2014-12-22 Merchant Law Group LLP
+// love : Merchant Law Group LLP
+// https://www.iana.org/domains/root/db/love.html
 love
 
-// lpl : 2015-07-30 LPL Holdings, Inc.
+// lpl : LPL Holdings, Inc.
+// https://www.iana.org/domains/root/db/lpl.html
 lpl
 
-// lplfinancial : 2015-07-30 LPL Holdings, Inc.
+// lplfinancial : LPL Holdings, Inc.
+// https://www.iana.org/domains/root/db/lplfinancial.html
 lplfinancial
 
-// ltd : 2014-09-25 Binky Moon, LLC
+// ltd : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/ltd.html
 ltd
 
-// ltda : 2014-04-17 InterNetX, Corp
+// ltda : InterNetX, Corp
+// https://www.iana.org/domains/root/db/ltda.html
 ltda
 
-// lundbeck : 2015-08-06 H. Lundbeck A/S
+// lundbeck : H. Lundbeck A/S
+// https://www.iana.org/domains/root/db/lundbeck.html
 lundbeck
 
-// luxe : 2014-01-09 Registry Services, LLC
+// luxe : Registry Services, LLC
+// https://www.iana.org/domains/root/db/luxe.html
 luxe
 
-// luxury : 2013-10-17 Luxury Partners, LLC
+// luxury : Luxury Partners, LLC
+// https://www.iana.org/domains/root/db/luxury.html
 luxury
 
-// madrid : 2014-05-01 Comunidad de Madrid
+// madrid : Comunidad de Madrid
+// https://www.iana.org/domains/root/db/madrid.html
 madrid
 
-// maif : 2014-10-02 Mutuelle Assurance Instituteur France (MAIF)
+// maif : Mutuelle Assurance Instituteur France (MAIF)
+// https://www.iana.org/domains/root/db/maif.html
 maif
 
-// maison : 2013-12-05 Binky Moon, LLC
+// maison : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/maison.html
 maison
 
-// makeup : 2015-01-15 XYZ.COM LLC
+// makeup : XYZ.COM LLC
+// https://www.iana.org/domains/root/db/makeup.html
 makeup
 
-// man : 2014-12-04 MAN SE
+// man : MAN SE
+// https://www.iana.org/domains/root/db/man.html
 man
 
-// management : 2013-11-07 Binky Moon, LLC
+// management : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/management.html
 management
 
-// mango : 2013-10-24 PUNTO FA S.L.
+// mango : PUNTO FA S.L.
+// https://www.iana.org/domains/root/db/mango.html
 mango
 
-// map : 2016-06-09 Charleston Road Registry Inc.
+// map : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/map.html
 map
 
-// market : 2014-03-06 Dog Beach, LLC
+// market : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/market.html
 market
 
-// marketing : 2013-11-07 Binky Moon, LLC
+// marketing : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/marketing.html
 marketing
 
-// markets : 2014-12-11 Dog Beach, LLC
+// markets : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/markets.html
 markets
 
-// marriott : 2014-10-09 Marriott Worldwide Corporation
+// marriott : Marriott Worldwide Corporation
+// https://www.iana.org/domains/root/db/marriott.html
 marriott
 
-// marshalls : 2015-07-16 The TJX Companies, Inc.
+// marshalls : The TJX Companies, Inc.
+// https://www.iana.org/domains/root/db/marshalls.html
 marshalls
 
-// maserati : 2015-07-31 Fiat Chrysler Automobiles N.V.
-maserati
-
-// mattel : 2015-08-06 Mattel Sites, Inc.
+// mattel : Mattel Sites, Inc.
+// https://www.iana.org/domains/root/db/mattel.html
 mattel
 
-// mba : 2015-04-02 Binky Moon, LLC
+// mba : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/mba.html
 mba
 
-// mckinsey : 2015-07-31 McKinsey Holdings, Inc.
+// mckinsey : McKinsey Holdings, Inc.
+// https://www.iana.org/domains/root/db/mckinsey.html
 mckinsey
 
-// med : 2015-08-06 Medistry LLC
+// med : Medistry LLC
+// https://www.iana.org/domains/root/db/med.html
 med
 
-// media : 2014-03-06 Binky Moon, LLC
+// media : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/media.html
 media
 
-// meet : 2014-01-16 Charleston Road Registry Inc.
+// meet : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/meet.html
 meet
 
-// melbourne : 2014-05-29 The Crown in right of the State of Victoria, represented by its Department of State Development, Business and Innovation
+// melbourne : The Crown in right of the State of Victoria, represented by its Department of State Development, Business and Innovation
+// https://www.iana.org/domains/root/db/melbourne.html
 melbourne
 
-// meme : 2014-01-30 Charleston Road Registry Inc.
+// meme : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/meme.html
 meme
 
-// memorial : 2014-10-16 Dog Beach, LLC
+// memorial : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/memorial.html
 memorial
 
-// men : 2015-02-26 Exclusive Registry Limited
+// men : Exclusive Registry Limited
+// https://www.iana.org/domains/root/db/men.html
 men
 
-// menu : 2013-09-11 Dot Menu Registry, LLC
+// menu : Dot Menu Registry, LLC
+// https://www.iana.org/domains/root/db/menu.html
 menu
 
-// merckmsd : 2016-07-14 MSD Registry Holdings, Inc.
+// merckmsd : MSD Registry Holdings, Inc.
+// https://www.iana.org/domains/root/db/merckmsd.html
 merckmsd
 
-// miami : 2013-12-19 Registry Services, LLC
+// miami : Registry Services, LLC
+// https://www.iana.org/domains/root/db/miami.html
 miami
 
-// microsoft : 2014-12-18 Microsoft Corporation
+// microsoft : Microsoft Corporation
+// https://www.iana.org/domains/root/db/microsoft.html
 microsoft
 
-// mini : 2014-01-09 Bayerische Motoren Werke Aktiengesellschaft
+// mini : Bayerische Motoren Werke Aktiengesellschaft
+// https://www.iana.org/domains/root/db/mini.html
 mini
 
-// mint : 2015-07-30 Intuit Administrative Services, Inc.
+// mint : Intuit Administrative Services, Inc.
+// https://www.iana.org/domains/root/db/mint.html
 mint
 
-// mit : 2015-07-02 Massachusetts Institute of Technology
+// mit : Massachusetts Institute of Technology
+// https://www.iana.org/domains/root/db/mit.html
 mit
 
-// mitsubishi : 2015-07-23 Mitsubishi Corporation
+// mitsubishi : Mitsubishi Corporation
+// https://www.iana.org/domains/root/db/mitsubishi.html
 mitsubishi
 
-// mlb : 2015-05-21 MLB Advanced Media DH, LLC
+// mlb : MLB Advanced Media DH, LLC
+// https://www.iana.org/domains/root/db/mlb.html
 mlb
 
-// mls : 2015-04-23 The Canadian Real Estate Association
+// mls : The Canadian Real Estate Association
+// https://www.iana.org/domains/root/db/mls.html
 mls
 
-// mma : 2014-11-07 MMA IARD
+// mma : MMA IARD
+// https://www.iana.org/domains/root/db/mma.html
 mma
 
-// mobile : 2016-06-02 Dish DBS Corporation
+// mobile : Dish DBS Corporation
+// https://www.iana.org/domains/root/db/mobile.html
 mobile
 
-// moda : 2013-11-07 Dog Beach, LLC
+// moda : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/moda.html
 moda
 
-// moe : 2013-11-13 Interlink Systems Innovation Institute K.K.
+// moe : Interlink Systems Innovation Institute K.K.
+// https://www.iana.org/domains/root/db/moe.html
 moe
 
-// moi : 2014-12-18 Amazon Registry Services, Inc.
+// moi : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/moi.html
 moi
 
-// mom : 2015-04-16 XYZ.COM LLC
+// mom : XYZ.COM LLC
+// https://www.iana.org/domains/root/db/mom.html
 mom
 
-// monash : 2013-09-30 Monash University
+// monash : Monash University
+// https://www.iana.org/domains/root/db/monash.html
 monash
 
-// money : 2014-10-16 Binky Moon, LLC
+// money : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/money.html
 money
 
-// monster : 2015-09-11 XYZ.COM LLC
+// monster : XYZ.COM LLC
+// https://www.iana.org/domains/root/db/monster.html
 monster
 
-// mormon : 2013-12-05 IRI Domain Management, LLC
+// mormon : IRI Domain Management, LLC
+// https://www.iana.org/domains/root/db/mormon.html
 mormon
 
-// mortgage : 2014-03-20 Dog Beach, LLC
+// mortgage : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/mortgage.html
 mortgage
 
-// moscow : 2013-12-19 Foundation for Assistance for Internet Technologies and Infrastructure Development (FAITID)
+// moscow : Foundation for Assistance for Internet Technologies and Infrastructure Development (FAITID)
+// https://www.iana.org/domains/root/db/moscow.html
 moscow
 
-// moto : 2015-06-04 Motorola Trademark Holdings, LLC
+// moto : Motorola Trademark Holdings, LLC
+// https://www.iana.org/domains/root/db/moto.html
 moto
 
-// motorcycles : 2014-01-09 XYZ.COM LLC
+// motorcycles : XYZ.COM LLC
+// https://www.iana.org/domains/root/db/motorcycles.html
 motorcycles
 
-// mov : 2014-01-30 Charleston Road Registry Inc.
+// mov : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/mov.html
 mov
 
-// movie : 2015-02-05 Binky Moon, LLC
+// movie : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/movie.html
 movie
 
-// msd : 2015-07-23 MSD Registry Holdings, Inc.
+// msd : MSD Registry Holdings, Inc.
+// https://www.iana.org/domains/root/db/msd.html
 msd
 
-// mtn : 2014-12-04 MTN Dubai Limited
+// mtn : MTN Dubai Limited
+// https://www.iana.org/domains/root/db/mtn.html
 mtn
 
-// mtr : 2015-03-12 MTR Corporation Limited
+// mtr : MTR Corporation Limited
+// https://www.iana.org/domains/root/db/mtr.html
 mtr
 
-// music : 2021-05-04 DotMusic Limited
+// music : DotMusic Limited
+// https://www.iana.org/domains/root/db/music.html
 music
 
-// mutual : 2015-04-02 Northwestern Mutual MU TLD Registry, LLC
-mutual
-
-// nab : 2015-08-20 National Australia Bank Limited
+// nab : National Australia Bank Limited
+// https://www.iana.org/domains/root/db/nab.html
 nab
 
-// nagoya : 2013-10-24 GMO Registry, Inc.
+// nagoya : GMO Registry, Inc.
+// https://www.iana.org/domains/root/db/nagoya.html
 nagoya
 
-// natura : 2015-03-12 NATURA COSMÉTICOS S.A.
+// natura : NATURA COSMÉTICOS S.A.
+// https://www.iana.org/domains/root/db/natura.html
 natura
 
-// navy : 2014-03-06 Dog Beach, LLC
+// navy : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/navy.html
 navy
 
-// nba : 2015-07-31 NBA REGISTRY, LLC
+// nba : NBA REGISTRY, LLC
+// https://www.iana.org/domains/root/db/nba.html
 nba
 
-// nec : 2015-01-08 NEC Corporation
+// nec : NEC Corporation
+// https://www.iana.org/domains/root/db/nec.html
 nec
 
-// netbank : 2014-06-26 COMMONWEALTH BANK OF AUSTRALIA
+// netbank : COMMONWEALTH BANK OF AUSTRALIA
+// https://www.iana.org/domains/root/db/netbank.html
 netbank
 
-// netflix : 2015-06-18 Netflix, Inc.
+// netflix : Netflix, Inc.
+// https://www.iana.org/domains/root/db/netflix.html
 netflix
 
-// network : 2013-11-14 Binky Moon, LLC
+// network : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/network.html
 network
 
-// neustar : 2013-12-05 NeuStar, Inc.
+// neustar : NeuStar, Inc.
+// https://www.iana.org/domains/root/db/neustar.html
 neustar
 
-// new : 2014-01-30 Charleston Road Registry Inc.
+// new : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/new.html
 new
 
-// news : 2014-12-18 Dog Beach, LLC
+// news : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/news.html
 news
 
-// next : 2015-06-18 Next plc
+// next : Next plc
+// https://www.iana.org/domains/root/db/next.html
 next
 
-// nextdirect : 2015-06-18 Next plc
+// nextdirect : Next plc
+// https://www.iana.org/domains/root/db/nextdirect.html
 nextdirect
 
-// nexus : 2014-07-24 Charleston Road Registry Inc.
+// nexus : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/nexus.html
 nexus
 
-// nfl : 2015-07-23 NFL Reg Ops LLC
+// nfl : NFL Reg Ops LLC
+// https://www.iana.org/domains/root/db/nfl.html
 nfl
 
-// ngo : 2014-03-06 Public Interest Registry
+// ngo : Public Interest Registry
+// https://www.iana.org/domains/root/db/ngo.html
 ngo
 
-// nhk : 2014-02-13 Japan Broadcasting Corporation (NHK)
+// nhk : Japan Broadcasting Corporation (NHK)
+// https://www.iana.org/domains/root/db/nhk.html
 nhk
 
-// nico : 2014-12-04 DWANGO Co., Ltd.
+// nico : DWANGO Co., Ltd.
+// https://www.iana.org/domains/root/db/nico.html
 nico
 
-// nike : 2015-07-23 NIKE, Inc.
+// nike : NIKE, Inc.
+// https://www.iana.org/domains/root/db/nike.html
 nike
 
-// nikon : 2015-05-21 NIKON CORPORATION
+// nikon : NIKON CORPORATION
+// https://www.iana.org/domains/root/db/nikon.html
 nikon
 
-// ninja : 2013-11-07 Dog Beach, LLC
+// ninja : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/ninja.html
 ninja
 
-// nissan : 2014-03-27 NISSAN MOTOR CO., LTD.
+// nissan : NISSAN MOTOR CO., LTD.
+// https://www.iana.org/domains/root/db/nissan.html
 nissan
 
-// nissay : 2015-10-29 Nippon Life Insurance Company
+// nissay : Nippon Life Insurance Company
+// https://www.iana.org/domains/root/db/nissay.html
 nissay
 
-// nokia : 2015-01-08 Nokia Corporation
+// nokia : Nokia Corporation
+// https://www.iana.org/domains/root/db/nokia.html
 nokia
 
-// northwesternmutual : 2015-06-18 Northwestern Mutual Registry, LLC
-northwesternmutual
-
-// norton : 2014-12-04 NortonLifeLock Inc.
+// norton : NortonLifeLock Inc.
+// https://www.iana.org/domains/root/db/norton.html
 norton
 
-// now : 2015-06-25 Amazon Registry Services, Inc.
+// now : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/now.html
 now
 
-// nowruz : 2014-09-04 Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti.
+// nowruz : Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti.
+// https://www.iana.org/domains/root/db/nowruz.html
 nowruz
 
-// nowtv : 2015-05-14 Starbucks (HK) Limited
+// nowtv : Starbucks (HK) Limited
+// https://www.iana.org/domains/root/db/nowtv.html
 nowtv
 
-// nra : 2014-05-22 NRA Holdings Company, INC.
+// nra : NRA Holdings Company, INC.
+// https://www.iana.org/domains/root/db/nra.html
 nra
 
-// nrw : 2013-11-21 Minds + Machines GmbH
+// nrw : Minds + Machines GmbH
+// https://www.iana.org/domains/root/db/nrw.html
 nrw
 
-// ntt : 2014-10-31 NIPPON TELEGRAPH AND TELEPHONE CORPORATION
+// ntt : NIPPON TELEGRAPH AND TELEPHONE CORPORATION
+// https://www.iana.org/domains/root/db/ntt.html
 ntt
 
-// nyc : 2014-01-23 The City of New York by and through the New York City Department of Information Technology & Telecommunications
+// nyc : The City of New York by and through the New York City Department of Information Technology & Telecommunications
+// https://www.iana.org/domains/root/db/nyc.html
 nyc
 
-// obi : 2014-09-25 OBI Group Holding SE & Co. KGaA
+// obi : OBI Group Holding SE & Co. KGaA
+// https://www.iana.org/domains/root/db/obi.html
 obi
 
-// observer : 2015-04-30 Dog Beach, LLC
+// observer : Fegistry, LLC
+// https://www.iana.org/domains/root/db/observer.html
 observer
 
-// office : 2015-03-12 Microsoft Corporation
+// office : Microsoft Corporation
+// https://www.iana.org/domains/root/db/office.html
 office
 
-// okinawa : 2013-12-05 BRregistry, Inc.
+// okinawa : BRregistry, Inc.
+// https://www.iana.org/domains/root/db/okinawa.html
 okinawa
 
-// olayan : 2015-05-14 Crescent Holding GmbH
+// olayan : Competrol (Luxembourg) Sarl
+// https://www.iana.org/domains/root/db/olayan.html
 olayan
 
-// olayangroup : 2015-05-14 Crescent Holding GmbH
+// olayangroup : Competrol (Luxembourg) Sarl
+// https://www.iana.org/domains/root/db/olayangroup.html
 olayangroup
 
-// oldnavy : 2015-07-31 The Gap, Inc.
+// oldnavy : The Gap, Inc.
+// https://www.iana.org/domains/root/db/oldnavy.html
 oldnavy
 
-// ollo : 2015-06-04 Dish DBS Corporation
+// ollo : Dish DBS Corporation
+// https://www.iana.org/domains/root/db/ollo.html
 ollo
 
-// omega : 2015-01-08 The Swatch Group Ltd
+// omega : The Swatch Group Ltd
+// https://www.iana.org/domains/root/db/omega.html
 omega
 
-// one : 2014-11-07 One.com A/S
+// one : One.com A/S
+// https://www.iana.org/domains/root/db/one.html
 one
 
-// ong : 2014-03-06 Public Interest Registry
+// ong : Public Interest Registry
+// https://www.iana.org/domains/root/db/ong.html
 ong
 
-// onl : 2013-09-16 iRegistry GmbH
+// onl : iRegistry GmbH
+// https://www.iana.org/domains/root/db/onl.html
 onl
 
-// online : 2015-01-15 Radix FZC
+// online : Radix FZC DMCC
+// https://www.iana.org/domains/root/db/online.html
 online
 
-// ooo : 2014-01-09 INFIBEAM AVENUES LIMITED
+// ooo : INFIBEAM AVENUES LIMITED
+// https://www.iana.org/domains/root/db/ooo.html
 ooo
 
-// open : 2015-07-31 American Express Travel Related Services Company, Inc.
+// open : American Express Travel Related Services Company, Inc.
+// https://www.iana.org/domains/root/db/open.html
 open
 
-// oracle : 2014-06-19 Oracle Corporation
+// oracle : Oracle Corporation
+// https://www.iana.org/domains/root/db/oracle.html
 oracle
 
-// orange : 2015-03-12 Orange Brand Services Limited
+// orange : Orange Brand Services Limited
+// https://www.iana.org/domains/root/db/orange.html
 orange
 
-// organic : 2014-03-27 Identity Digital Limited
+// organic : Identity Digital Limited
+// https://www.iana.org/domains/root/db/organic.html
 organic
 
-// origins : 2015-10-01 The Estée Lauder Companies Inc.
+// origins : The Estée Lauder Companies Inc.
+// https://www.iana.org/domains/root/db/origins.html
 origins
 
-// osaka : 2014-09-04 Osaka Registry Co., Ltd.
+// osaka : Osaka Registry Co., Ltd.
+// https://www.iana.org/domains/root/db/osaka.html
 osaka
 
-// otsuka : 2013-10-11 Otsuka Holdings Co., Ltd.
+// otsuka : Otsuka Holdings Co., Ltd.
+// https://www.iana.org/domains/root/db/otsuka.html
 otsuka
 
-// ott : 2015-06-04 Dish DBS Corporation
+// ott : Dish DBS Corporation
+// https://www.iana.org/domains/root/db/ott.html
 ott
 
-// ovh : 2014-01-16 MédiaBC
+// ovh : MédiaBC
+// https://www.iana.org/domains/root/db/ovh.html
 ovh
 
-// page : 2014-12-04 Charleston Road Registry Inc.
+// page : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/page.html
 page
 
-// panasonic : 2015-07-30 Panasonic Holdings Corporation
+// panasonic : Panasonic Holdings Corporation
+// https://www.iana.org/domains/root/db/panasonic.html
 panasonic
 
-// paris : 2014-01-30 City of Paris
+// paris : City of Paris
+// https://www.iana.org/domains/root/db/paris.html
 paris
 
-// pars : 2014-09-04 Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti.
+// pars : Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti.
+// https://www.iana.org/domains/root/db/pars.html
 pars
 
-// partners : 2013-12-05 Binky Moon, LLC
+// partners : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/partners.html
 partners
 
-// parts : 2013-12-05 Binky Moon, LLC
+// parts : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/parts.html
 parts
 
-// party : 2014-09-11 Blue Sky Registry Limited
+// party : Blue Sky Registry Limited
+// https://www.iana.org/domains/root/db/party.html
 party
 
-// passagens : 2015-03-05 Travel Reservations SRL
-passagens
-
-// pay : 2015-08-27 Amazon Registry Services, Inc.
+// pay : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/pay.html
 pay
 
-// pccw : 2015-05-14 PCCW Enterprises Limited
+// pccw : PCCW Enterprises Limited
+// https://www.iana.org/domains/root/db/pccw.html
 pccw
 
-// pet : 2015-05-07 Identity Digital Limited
+// pet : Identity Digital Limited
+// https://www.iana.org/domains/root/db/pet.html
 pet
 
-// pfizer : 2015-09-11 Pfizer Inc.
+// pfizer : Pfizer Inc.
+// https://www.iana.org/domains/root/db/pfizer.html
 pfizer
 
-// pharmacy : 2014-06-19 National Association of Boards of Pharmacy
+// pharmacy : National Association of Boards of Pharmacy
+// https://www.iana.org/domains/root/db/pharmacy.html
 pharmacy
 
-// phd : 2016-07-28 Charleston Road Registry Inc.
+// phd : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/phd.html
 phd
 
-// philips : 2014-11-07 Koninklijke Philips N.V.
+// philips : Koninklijke Philips N.V.
+// https://www.iana.org/domains/root/db/philips.html
 philips
 
-// phone : 2016-06-02 Dish DBS Corporation
+// phone : Dish DBS Corporation
+// https://www.iana.org/domains/root/db/phone.html
 phone
 
-// photo : 2013-11-14 Registry Services, LLC
+// photo : Registry Services, LLC
+// https://www.iana.org/domains/root/db/photo.html
 photo
 
-// photography : 2013-09-20 Binky Moon, LLC
+// photography : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/photography.html
 photography
 
-// photos : 2013-10-17 Binky Moon, LLC
+// photos : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/photos.html
 photos
 
-// physio : 2014-05-01 PhysBiz Pty Ltd
+// physio : PhysBiz Pty Ltd
+// https://www.iana.org/domains/root/db/physio.html
 physio
 
-// pics : 2013-11-14 XYZ.COM LLC
+// pics : XYZ.COM LLC
+// https://www.iana.org/domains/root/db/pics.html
 pics
 
-// pictet : 2014-06-26 Pictet Europe S.A.
+// pictet : Pictet Europe S.A.
+// https://www.iana.org/domains/root/db/pictet.html
 pictet
 
-// pictures : 2014-03-06 Binky Moon, LLC
+// pictures : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/pictures.html
 pictures
 
-// pid : 2015-01-08 Top Level Spectrum, Inc.
+// pid : Top Level Spectrum, Inc.
+// https://www.iana.org/domains/root/db/pid.html
 pid
 
-// pin : 2014-12-18 Amazon Registry Services, Inc.
+// pin : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/pin.html
 pin
 
-// ping : 2015-06-11 Ping Registry Provider, Inc.
+// ping : Ping Registry Provider, Inc.
+// https://www.iana.org/domains/root/db/ping.html
 ping
 
-// pink : 2013-10-01 Identity Digital Limited
+// pink : Identity Digital Limited
+// https://www.iana.org/domains/root/db/pink.html
 pink
 
-// pioneer : 2015-07-16 Pioneer Corporation
+// pioneer : Pioneer Corporation
+// https://www.iana.org/domains/root/db/pioneer.html
 pioneer
 
-// pizza : 2014-06-26 Binky Moon, LLC
+// pizza : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/pizza.html
 pizza
 
-// place : 2014-04-24 Binky Moon, LLC
+// place : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/place.html
 place
 
-// play : 2015-03-05 Charleston Road Registry Inc.
+// play : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/play.html
 play
 
-// playstation : 2015-07-02 Sony Interactive Entertainment Inc.
+// playstation : Sony Interactive Entertainment Inc.
+// https://www.iana.org/domains/root/db/playstation.html
 playstation
 
-// plumbing : 2013-09-10 Binky Moon, LLC
+// plumbing : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/plumbing.html
 plumbing
 
-// plus : 2015-02-05 Binky Moon, LLC
+// plus : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/plus.html
 plus
 
-// pnc : 2015-07-02 PNC Domain Co., LLC
+// pnc : PNC Domain Co., LLC
+// https://www.iana.org/domains/root/db/pnc.html
 pnc
 
-// pohl : 2014-06-23 Deutsche Vermögensberatung Aktiengesellschaft DVAG
+// pohl : Deutsche Vermögensberatung Aktiengesellschaft DVAG
+// https://www.iana.org/domains/root/db/pohl.html
 pohl
 
-// poker : 2014-07-03 Identity Digital Limited
+// poker : Identity Digital Limited
+// https://www.iana.org/domains/root/db/poker.html
 poker
 
-// politie : 2015-08-20 Politie Nederland
+// politie : Politie Nederland
+// https://www.iana.org/domains/root/db/politie.html
 politie
 
-// porn : 2014-10-16 ICM Registry PN LLC
+// porn : ICM Registry PN LLC
+// https://www.iana.org/domains/root/db/porn.html
 porn
 
-// pramerica : 2015-07-30 Prudential Financial, Inc.
+// pramerica : Prudential Financial, Inc.
+// https://www.iana.org/domains/root/db/pramerica.html
 pramerica
 
-// praxi : 2013-12-05 Praxi S.p.A.
+// praxi : Praxi S.p.A.
+// https://www.iana.org/domains/root/db/praxi.html
 praxi
 
-// press : 2014-04-03 Radix FZC
+// press : Radix FZC DMCC
+// https://www.iana.org/domains/root/db/press.html
 press
 
-// prime : 2015-06-25 Amazon Registry Services, Inc.
+// prime : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/prime.html
 prime
 
-// prod : 2014-01-23 Charleston Road Registry Inc.
+// prod : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/prod.html
 prod
 
-// productions : 2013-12-05 Binky Moon, LLC
+// productions : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/productions.html
 productions
 
-// prof : 2014-07-24 Charleston Road Registry Inc.
+// prof : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/prof.html
 prof
 
-// progressive : 2015-07-23 Progressive Casualty Insurance Company
+// progressive : Progressive Casualty Insurance Company
+// https://www.iana.org/domains/root/db/progressive.html
 progressive
 
-// promo : 2014-12-18 Identity Digital Limited
+// promo : Identity Digital Limited
+// https://www.iana.org/domains/root/db/promo.html
 promo
 
-// properties : 2013-12-05 Binky Moon, LLC
+// properties : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/properties.html
 properties
 
-// property : 2014-05-22 Internet Naming Company LLC
+// property : Digital Property Infrastructure Limited
+// https://www.iana.org/domains/root/db/property.html
 property
 
-// protection : 2015-04-23 XYZ.COM LLC
+// protection : XYZ.COM LLC
+// https://www.iana.org/domains/root/db/protection.html
 protection
 
-// pru : 2015-07-30 Prudential Financial, Inc.
+// pru : Prudential Financial, Inc.
+// https://www.iana.org/domains/root/db/pru.html
 pru
 
-// prudential : 2015-07-30 Prudential Financial, Inc.
+// prudential : Prudential Financial, Inc.
+// https://www.iana.org/domains/root/db/prudential.html
 prudential
 
-// pub : 2013-12-12 Dog Beach, LLC
+// pub : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/pub.html
 pub
 
-// pwc : 2015-10-29 PricewaterhouseCoopers LLP
+// pwc : PricewaterhouseCoopers LLP
+// https://www.iana.org/domains/root/db/pwc.html
 pwc
 
-// qpon : 2013-11-14 dotQPON LLC
+// qpon : dotQPON LLC
+// https://www.iana.org/domains/root/db/qpon.html
 qpon
 
-// quebec : 2013-12-19 PointQuébec Inc
+// quebec : PointQuébec Inc
+// https://www.iana.org/domains/root/db/quebec.html
 quebec
 
-// quest : 2015-03-26 XYZ.COM LLC
+// quest : XYZ.COM LLC
+// https://www.iana.org/domains/root/db/quest.html
 quest
 
-// racing : 2014-12-04 Premier Registry Limited
+// racing : Premier Registry Limited
+// https://www.iana.org/domains/root/db/racing.html
 racing
 
-// radio : 2016-07-21 European Broadcasting Union (EBU)
+// radio : European Broadcasting Union (EBU)
+// https://www.iana.org/domains/root/db/radio.html
 radio
 
-// read : 2014-12-18 Amazon Registry Services, Inc.
+// read : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/read.html
 read
 
-// realestate : 2015-09-11 dotRealEstate LLC
+// realestate : dotRealEstate LLC
+// https://www.iana.org/domains/root/db/realestate.html
 realestate
 
-// realtor : 2014-05-29 Real Estate Domains LLC
+// realtor : Real Estate Domains LLC
+// https://www.iana.org/domains/root/db/realtor.html
 realtor
 
-// realty : 2015-03-19 Dog Beach, LLC
+// realty : Internet Naming Company LLC
+// https://www.iana.org/domains/root/db/realty.html
 realty
 
-// recipes : 2013-10-17 Binky Moon, LLC
+// recipes : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/recipes.html
 recipes
 
-// red : 2013-11-07 Identity Digital Limited
+// red : Identity Digital Limited
+// https://www.iana.org/domains/root/db/red.html
 red
 
-// redstone : 2014-10-31 Redstone Haute Couture Co., Ltd.
+// redstone : Redstone Haute Couture Co., Ltd.
+// https://www.iana.org/domains/root/db/redstone.html
 redstone
 
-// redumbrella : 2015-03-26 Travelers TLD, LLC
+// redumbrella : Travelers TLD, LLC
+// https://www.iana.org/domains/root/db/redumbrella.html
 redumbrella
 
-// rehab : 2014-03-06 Dog Beach, LLC
+// rehab : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/rehab.html
 rehab
 
-// reise : 2014-03-13 Binky Moon, LLC
+// reise : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/reise.html
 reise
 
-// reisen : 2014-03-06 Binky Moon, LLC
+// reisen : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/reisen.html
 reisen
 
-// reit : 2014-09-04 National Association of Real Estate Investment Trusts, Inc.
+// reit : National Association of Real Estate Investment Trusts, Inc.
+// https://www.iana.org/domains/root/db/reit.html
 reit
 
-// reliance : 2015-04-02 Reliance Industries Limited
+// reliance : Reliance Industries Limited
+// https://www.iana.org/domains/root/db/reliance.html
 reliance
 
-// ren : 2013-12-12 ZDNS International Limited
+// ren : ZDNS International Limited
+// https://www.iana.org/domains/root/db/ren.html
 ren
 
-// rent : 2014-12-04 XYZ.COM LLC
+// rent : XYZ.COM LLC
+// https://www.iana.org/domains/root/db/rent.html
 rent
 
-// rentals : 2013-12-05 Binky Moon, LLC
+// rentals : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/rentals.html
 rentals
 
-// repair : 2013-11-07 Binky Moon, LLC
+// repair : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/repair.html
 repair
 
-// report : 2013-12-05 Binky Moon, LLC
+// report : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/report.html
 report
 
-// republican : 2014-03-20 Dog Beach, LLC
+// republican : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/republican.html
 republican
 
-// rest : 2013-12-19 Punto 2012 Sociedad Anonima Promotora de Inversion de Capital Variable
+// rest : Punto 2012 Sociedad Anonima Promotora de Inversion de Capital Variable
+// https://www.iana.org/domains/root/db/rest.html
 rest
 
-// restaurant : 2014-07-03 Binky Moon, LLC
+// restaurant : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/restaurant.html
 restaurant
 
-// review : 2014-11-20 dot Review Limited
+// review : dot Review Limited
+// https://www.iana.org/domains/root/db/review.html
 review
 
-// reviews : 2013-09-13 Dog Beach, LLC
+// reviews : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/reviews.html
 reviews
 
-// rexroth : 2015-06-18 Robert Bosch GMBH
+// rexroth : Robert Bosch GMBH
+// https://www.iana.org/domains/root/db/rexroth.html
 rexroth
 
-// rich : 2013-11-21 iRegistry GmbH
+// rich : iRegistry GmbH
+// https://www.iana.org/domains/root/db/rich.html
 rich
 
-// richardli : 2015-05-14 Pacific Century Asset Management (HK) Limited
+// richardli : Pacific Century Asset Management (HK) Limited
+// https://www.iana.org/domains/root/db/richardli.html
 richardli
 
-// ricoh : 2014-11-20 Ricoh Company, Ltd.
+// ricoh : Ricoh Company, Ltd.
+// https://www.iana.org/domains/root/db/ricoh.html
 ricoh
 
-// ril : 2015-04-02 Reliance Industries Limited
+// ril : Reliance Industries Limited
+// https://www.iana.org/domains/root/db/ril.html
 ril
 
-// rio : 2014-02-27 Empresa Municipal de Informática SA - IPLANRIO
+// rio : Empresa Municipal de Informática SA - IPLANRIO
+// https://www.iana.org/domains/root/db/rio.html
 rio
 
-// rip : 2014-07-10 Dog Beach, LLC
+// rip : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/rip.html
 rip
 
-// rocher : 2014-12-18 Ferrero Trading Lux S.A.
-rocher
-
-// rocks : 2013-11-14 Dog Beach, LLC
+// rocks : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/rocks.html
 rocks
 
-// rodeo : 2013-12-19 Registry Services, LLC
+// rodeo : Registry Services, LLC
+// https://www.iana.org/domains/root/db/rodeo.html
 rodeo
 
-// rogers : 2015-08-06 Rogers Communications Canada Inc.
+// rogers : Rogers Communications Canada Inc.
+// https://www.iana.org/domains/root/db/rogers.html
 rogers
 
-// room : 2014-12-18 Amazon Registry Services, Inc.
+// room : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/room.html
 room
 
-// rsvp : 2014-05-08 Charleston Road Registry Inc.
+// rsvp : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/rsvp.html
 rsvp
 
-// rugby : 2016-12-15 World Rugby Strategic Developments Limited
+// rugby : World Rugby Strategic Developments Limited
+// https://www.iana.org/domains/root/db/rugby.html
 rugby
 
-// ruhr : 2013-10-02 dotSaarland GmbH
+// ruhr : dotSaarland GmbH
+// https://www.iana.org/domains/root/db/ruhr.html
 ruhr
 
-// run : 2015-03-19 Binky Moon, LLC
+// run : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/run.html
 run
 
-// rwe : 2015-04-02 RWE AG
+// rwe : RWE AG
+// https://www.iana.org/domains/root/db/rwe.html
 rwe
 
-// ryukyu : 2014-01-09 BRregistry, Inc.
+// ryukyu : BRregistry, Inc.
+// https://www.iana.org/domains/root/db/ryukyu.html
 ryukyu
 
-// saarland : 2013-12-12 dotSaarland GmbH
+// saarland : dotSaarland GmbH
+// https://www.iana.org/domains/root/db/saarland.html
 saarland
 
-// safe : 2014-12-18 Amazon Registry Services, Inc.
+// safe : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/safe.html
 safe
 
-// safety : 2015-01-08 Safety Registry Services, LLC.
+// safety : Safety Registry Services, LLC.
+// https://www.iana.org/domains/root/db/safety.html
 safety
 
-// sakura : 2014-12-18 SAKURA Internet Inc.
+// sakura : SAKURA Internet Inc.
+// https://www.iana.org/domains/root/db/sakura.html
 sakura
 
-// sale : 2014-10-16 Dog Beach, LLC
+// sale : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/sale.html
 sale
 
-// salon : 2014-12-11 Binky Moon, LLC
+// salon : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/salon.html
 salon
 
-// samsclub : 2015-07-31 Wal-Mart Stores, Inc.
+// samsclub : Wal-Mart Stores, Inc.
+// https://www.iana.org/domains/root/db/samsclub.html
 samsclub
 
-// samsung : 2014-04-03 SAMSUNG SDS CO., LTD
+// samsung : SAMSUNG SDS CO., LTD
+// https://www.iana.org/domains/root/db/samsung.html
 samsung
 
-// sandvik : 2014-11-13 Sandvik AB
+// sandvik : Sandvik AB
+// https://www.iana.org/domains/root/db/sandvik.html
 sandvik
 
-// sandvikcoromant : 2014-11-07 Sandvik AB
+// sandvikcoromant : Sandvik AB
+// https://www.iana.org/domains/root/db/sandvikcoromant.html
 sandvikcoromant
 
-// sanofi : 2014-10-09 Sanofi
+// sanofi : Sanofi
+// https://www.iana.org/domains/root/db/sanofi.html
 sanofi
 
-// sap : 2014-03-27 SAP AG
+// sap : SAP AG
+// https://www.iana.org/domains/root/db/sap.html
 sap
 
-// sarl : 2014-07-03 Binky Moon, LLC
+// sarl : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/sarl.html
 sarl
 
-// sas : 2015-04-02 Research IP LLC
+// sas : Research IP LLC
+// https://www.iana.org/domains/root/db/sas.html
 sas
 
-// save : 2015-06-25 Amazon Registry Services, Inc.
+// save : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/save.html
 save
 
-// saxo : 2014-10-31 Saxo Bank A/S
+// saxo : Saxo Bank A/S
+// https://www.iana.org/domains/root/db/saxo.html
 saxo
 
-// sbi : 2015-03-12 STATE BANK OF INDIA
+// sbi : STATE BANK OF INDIA
+// https://www.iana.org/domains/root/db/sbi.html
 sbi
 
-// sbs : 2014-11-07 ShortDot SA
+// sbs : ShortDot SA
+// https://www.iana.org/domains/root/db/sbs.html
 sbs
 
-// sca : 2014-03-13 SVENSKA CELLULOSA AKTIEBOLAGET SCA (publ)
+// sca : SVENSKA CELLULOSA AKTIEBOLAGET SCA (publ)
+// https://www.iana.org/domains/root/db/sca.html
 sca
 
-// scb : 2014-02-20 The Siam Commercial Bank Public Company Limited ("SCB")
+// scb : The Siam Commercial Bank Public Company Limited ("SCB")
+// https://www.iana.org/domains/root/db/scb.html
 scb
 
-// schaeffler : 2015-08-06 Schaeffler Technologies AG & Co. KG
+// schaeffler : Schaeffler Technologies AG & Co. KG
+// https://www.iana.org/domains/root/db/schaeffler.html
 schaeffler
 
-// schmidt : 2014-04-03 SCHMIDT GROUPE S.A.S.
+// schmidt : SCHMIDT GROUPE S.A.S.
+// https://www.iana.org/domains/root/db/schmidt.html
 schmidt
 
-// scholarships : 2014-04-24 Scholarships.com, LLC
+// scholarships : Scholarships.com, LLC
+// https://www.iana.org/domains/root/db/scholarships.html
 scholarships
 
-// school : 2014-12-18 Binky Moon, LLC
+// school : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/school.html
 school
 
-// schule : 2014-03-06 Binky Moon, LLC
+// schule : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/schule.html
 schule
 
-// schwarz : 2014-09-18 Schwarz Domains und Services GmbH & Co. KG
+// schwarz : Schwarz Domains und Services GmbH & Co. KG
+// https://www.iana.org/domains/root/db/schwarz.html
 schwarz
 
-// science : 2014-09-11 dot Science Limited
+// science : dot Science Limited
+// https://www.iana.org/domains/root/db/science.html
 science
 
-// scot : 2014-01-23 Dot Scot Registry Limited
+// scot : Dot Scot Registry Limited
+// https://www.iana.org/domains/root/db/scot.html
 scot
 
-// search : 2016-06-09 Charleston Road Registry Inc.
+// search : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/search.html
 search
 
-// seat : 2014-05-22 SEAT, S.A. (Sociedad Unipersonal)
+// seat : SEAT, S.A. (Sociedad Unipersonal)
+// https://www.iana.org/domains/root/db/seat.html
 seat
 
-// secure : 2015-08-27 Amazon Registry Services, Inc.
+// secure : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/secure.html
 secure
 
-// security : 2015-05-14 XYZ.COM LLC
+// security : XYZ.COM LLC
+// https://www.iana.org/domains/root/db/security.html
 security
 
-// seek : 2014-12-04 Seek Limited
+// seek : Seek Limited
+// https://www.iana.org/domains/root/db/seek.html
 seek
 
-// select : 2015-10-08 Registry Services, LLC
+// select : Registry Services, LLC
+// https://www.iana.org/domains/root/db/select.html
 select
 
-// sener : 2014-10-24 Sener Ingeniería y Sistemas, S.A.
+// sener : Sener Ingeniería y Sistemas, S.A.
+// https://www.iana.org/domains/root/db/sener.html
 sener
 
-// services : 2014-02-27 Binky Moon, LLC
+// services : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/services.html
 services
 
-// seven : 2015-08-06 Seven West Media Ltd
+// seven : Seven West Media Ltd
+// https://www.iana.org/domains/root/db/seven.html
 seven
 
-// sew : 2014-07-17 SEW-EURODRIVE GmbH & Co KG
+// sew : SEW-EURODRIVE GmbH & Co KG
+// https://www.iana.org/domains/root/db/sew.html
 sew
 
-// sex : 2014-11-13 ICM Registry SX LLC
+// sex : ICM Registry SX LLC
+// https://www.iana.org/domains/root/db/sex.html
 sex
 
-// sexy : 2013-09-11 Internet Naming Company LLC
+// sexy : Internet Naming Company LLC
+// https://www.iana.org/domains/root/db/sexy.html
 sexy
 
-// sfr : 2015-08-13 Societe Francaise du Radiotelephone - SFR
+// sfr : Societe Francaise du Radiotelephone - SFR
+// https://www.iana.org/domains/root/db/sfr.html
 sfr
 
-// shangrila : 2015-09-03 Shangri‐La International Hotel Management Limited
+// shangrila : Shangri‐La International Hotel Management Limited
+// https://www.iana.org/domains/root/db/shangrila.html
 shangrila
 
-// sharp : 2014-05-01 Sharp Corporation
+// sharp : Sharp Corporation
+// https://www.iana.org/domains/root/db/sharp.html
 sharp
 
-// shaw : 2015-04-23 Shaw Cablesystems G.P.
+// shaw : Shaw Cablesystems G.P.
+// https://www.iana.org/domains/root/db/shaw.html
 shaw
 
-// shell : 2015-07-30 Shell Information Technology International Inc
+// shell : Shell Information Technology International Inc
+// https://www.iana.org/domains/root/db/shell.html
 shell
 
-// shia : 2014-09-04 Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti.
+// shia : Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti.
+// https://www.iana.org/domains/root/db/shia.html
 shia
 
-// shiksha : 2013-11-14 Identity Digital Limited
+// shiksha : Identity Digital Limited
+// https://www.iana.org/domains/root/db/shiksha.html
 shiksha
 
-// shoes : 2013-10-02 Binky Moon, LLC
+// shoes : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/shoes.html
 shoes
 
-// shop : 2016-04-08 GMO Registry, Inc.
+// shop : GMO Registry, Inc.
+// https://www.iana.org/domains/root/db/shop.html
 shop
 
-// shopping : 2016-03-31 Binky Moon, LLC
+// shopping : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/shopping.html
 shopping
 
-// shouji : 2015-01-08 Beijing Qihu Keji Co., Ltd.
+// shouji : Beijing Qihu Keji Co., Ltd.
+// https://www.iana.org/domains/root/db/shouji.html
 shouji
 
-// show : 2015-03-05 Binky Moon, LLC
+// show : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/show.html
 show
 
-// showtime : 2015-08-06 CBS Domains Inc.
-showtime
-
-// silk : 2015-06-25 Amazon Registry Services, Inc.
+// silk : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/silk.html
 silk
 
-// sina : 2015-03-12 Sina Corporation
+// sina : Sina Corporation
+// https://www.iana.org/domains/root/db/sina.html
 sina
 
-// singles : 2013-08-27 Binky Moon, LLC
+// singles : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/singles.html
 singles
 
-// site : 2015-01-15 Radix FZC
+// site : Radix FZC DMCC
+// https://www.iana.org/domains/root/db/site.html
 site
 
-// ski : 2015-04-09 Identity Digital Limited
+// ski : Identity Digital Limited
+// https://www.iana.org/domains/root/db/ski.html
 ski
 
-// skin : 2015-01-15 XYZ.COM LLC
+// skin : XYZ.COM LLC
+// https://www.iana.org/domains/root/db/skin.html
 skin
 
-// sky : 2014-06-19 Sky International AG
+// sky : Sky International AG
+// https://www.iana.org/domains/root/db/sky.html
 sky
 
-// skype : 2014-12-18 Microsoft Corporation
+// skype : Microsoft Corporation
+// https://www.iana.org/domains/root/db/skype.html
 skype
 
-// sling : 2015-07-30 DISH Technologies L.L.C.
+// sling : DISH Technologies L.L.C.
+// https://www.iana.org/domains/root/db/sling.html
 sling
 
-// smart : 2015-07-09 Smart Communications, Inc. (SMART)
+// smart : Smart Communications, Inc. (SMART)
+// https://www.iana.org/domains/root/db/smart.html
 smart
 
-// smile : 2014-12-18 Amazon Registry Services, Inc.
+// smile : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/smile.html
 smile
 
-// sncf : 2015-02-19 Société Nationale SNCF
+// sncf : Société Nationale SNCF
+// https://www.iana.org/domains/root/db/sncf.html
 sncf
 
-// soccer : 2015-03-26 Binky Moon, LLC
+// soccer : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/soccer.html
 soccer
 
-// social : 2013-11-07 Dog Beach, LLC
+// social : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/social.html
 social
 
-// softbank : 2015-07-02 SoftBank Group Corp.
+// softbank : SoftBank Group Corp.
+// https://www.iana.org/domains/root/db/softbank.html
 softbank
 
-// software : 2014-03-20 Dog Beach, LLC
+// software : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/software.html
 software
 
-// sohu : 2013-12-19 Sohu.com Limited
+// sohu : Sohu.com Limited
+// https://www.iana.org/domains/root/db/sohu.html
 sohu
 
-// solar : 2013-11-07 Binky Moon, LLC
+// solar : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/solar.html
 solar
 
-// solutions : 2013-11-07 Binky Moon, LLC
+// solutions : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/solutions.html
 solutions
 
-// song : 2015-02-26 Amazon Registry Services, Inc.
+// song : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/song.html
 song
 
-// sony : 2015-01-08 Sony Corporation
+// sony : Sony Corporation
+// https://www.iana.org/domains/root/db/sony.html
 sony
 
-// soy : 2014-01-23 Charleston Road Registry Inc.
+// soy : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/soy.html
 soy
 
-// spa : 2019-09-19 Asia Spa and Wellness Promotion Council Limited
+// spa : Asia Spa and Wellness Promotion Council Limited
+// https://www.iana.org/domains/root/db/spa.html
 spa
 
-// space : 2014-04-03 Radix FZC
+// space : Radix FZC DMCC
+// https://www.iana.org/domains/root/db/space.html
 space
 
-// sport : 2017-11-16 Global Association of International Sports Federations (GAISF)
+// sport : SportAccord
+// https://www.iana.org/domains/root/db/sport.html
 sport
 
-// spot : 2015-02-26 Amazon Registry Services, Inc.
+// spot : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/spot.html
 spot
 
-// srl : 2015-05-07 InterNetX, Corp
+// srl : InterNetX, Corp
+// https://www.iana.org/domains/root/db/srl.html
 srl
 
-// stada : 2014-11-13 STADA Arzneimittel AG
+// stada : STADA Arzneimittel AG
+// https://www.iana.org/domains/root/db/stada.html
 stada
 
-// staples : 2015-07-30 Staples, Inc.
+// staples : Staples, Inc.
+// https://www.iana.org/domains/root/db/staples.html
 staples
 
-// star : 2015-01-08 Star India Private Limited
+// star : Star India Private Limited
+// https://www.iana.org/domains/root/db/star.html
 star
 
-// statebank : 2015-03-12 STATE BANK OF INDIA
+// statebank : STATE BANK OF INDIA
+// https://www.iana.org/domains/root/db/statebank.html
 statebank
 
-// statefarm : 2015-07-30 State Farm Mutual Automobile Insurance Company
+// statefarm : State Farm Mutual Automobile Insurance Company
+// https://www.iana.org/domains/root/db/statefarm.html
 statefarm
 
-// stc : 2014-10-09 Saudi Telecom Company
+// stc : Saudi Telecom Company
+// https://www.iana.org/domains/root/db/stc.html
 stc
 
-// stcgroup : 2014-10-09 Saudi Telecom Company
+// stcgroup : Saudi Telecom Company
+// https://www.iana.org/domains/root/db/stcgroup.html
 stcgroup
 
-// stockholm : 2014-12-18 Stockholms kommun
+// stockholm : Stockholms kommun
+// https://www.iana.org/domains/root/db/stockholm.html
 stockholm
 
-// storage : 2014-12-22 XYZ.COM LLC
+// storage : XYZ.COM LLC
+// https://www.iana.org/domains/root/db/storage.html
 storage
 
-// store : 2015-04-09 Radix FZC
+// store : Radix FZC DMCC
+// https://www.iana.org/domains/root/db/store.html
 store
 
-// stream : 2016-01-08 dot Stream Limited
+// stream : dot Stream Limited
+// https://www.iana.org/domains/root/db/stream.html
 stream
 
-// studio : 2015-02-11 Dog Beach, LLC
+// studio : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/studio.html
 studio
 
-// study : 2014-12-11 Registry Services, LLC
+// study : Registry Services, LLC
+// https://www.iana.org/domains/root/db/study.html
 study
 
-// style : 2014-12-04 Binky Moon, LLC
+// style : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/style.html
 style
 
-// sucks : 2014-12-22 Vox Populi Registry Ltd.
+// sucks : Vox Populi Registry Ltd.
+// https://www.iana.org/domains/root/db/sucks.html
 sucks
 
-// supplies : 2013-12-19 Binky Moon, LLC
+// supplies : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/supplies.html
 supplies
 
-// supply : 2013-12-19 Binky Moon, LLC
+// supply : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/supply.html
 supply
 
-// support : 2013-10-24 Binky Moon, LLC
+// support : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/support.html
 support
 
-// surf : 2014-01-09 Registry Services, LLC
+// surf : Registry Services, LLC
+// https://www.iana.org/domains/root/db/surf.html
 surf
 
-// surgery : 2014-03-20 Binky Moon, LLC
+// surgery : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/surgery.html
 surgery
 
-// suzuki : 2014-02-20 SUZUKI MOTOR CORPORATION
+// suzuki : SUZUKI MOTOR CORPORATION
+// https://www.iana.org/domains/root/db/suzuki.html
 suzuki
 
-// swatch : 2015-01-08 The Swatch Group Ltd
+// swatch : The Swatch Group Ltd
+// https://www.iana.org/domains/root/db/swatch.html
 swatch
 
-// swiss : 2014-10-16 Swiss Confederation
+// swiss : Swiss Confederation
+// https://www.iana.org/domains/root/db/swiss.html
 swiss
 
-// sydney : 2014-09-18 State of New South Wales, Department of Premier and Cabinet
+// sydney : State of New South Wales, Department of Premier and Cabinet
+// https://www.iana.org/domains/root/db/sydney.html
 sydney
 
-// systems : 2013-11-07 Binky Moon, LLC
+// systems : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/systems.html
 systems
 
-// tab : 2014-12-04 Tabcorp Holdings Limited
+// tab : Tabcorp Holdings Limited
+// https://www.iana.org/domains/root/db/tab.html
 tab
 
-// taipei : 2014-07-10 Taipei City Government
+// taipei : Taipei City Government
+// https://www.iana.org/domains/root/db/taipei.html
 taipei
 
-// talk : 2015-04-09 Amazon Registry Services, Inc.
+// talk : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/talk.html
 talk
 
-// taobao : 2015-01-15 Alibaba Group Holding Limited
+// taobao : Alibaba Group Holding Limited
+// https://www.iana.org/domains/root/db/taobao.html
 taobao
 
-// target : 2015-07-31 Target Domain Holdings, LLC
+// target : Target Domain Holdings, LLC
+// https://www.iana.org/domains/root/db/target.html
 target
 
-// tatamotors : 2015-03-12 Tata Motors Ltd
+// tatamotors : Tata Motors Ltd
+// https://www.iana.org/domains/root/db/tatamotors.html
 tatamotors
 
-// tatar : 2014-04-24 Limited Liability Company "Coordination Center of Regional Domain of Tatarstan Republic"
+// tatar : Limited Liability Company "Coordination Center of Regional Domain of Tatarstan Republic"
+// https://www.iana.org/domains/root/db/tatar.html
 tatar
 
-// tattoo : 2013-08-30 Top Level Design, LLC
+// tattoo : Registry Services, LLC
+// https://www.iana.org/domains/root/db/tattoo.html
 tattoo
 
-// tax : 2014-03-20 Binky Moon, LLC
+// tax : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/tax.html
 tax
 
-// taxi : 2015-03-19 Binky Moon, LLC
+// taxi : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/taxi.html
 taxi
 
-// tci : 2014-09-12 Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti.
+// tci : Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti.
+// https://www.iana.org/domains/root/db/tci.html
 tci
 
-// tdk : 2015-06-11 TDK Corporation
+// tdk : TDK Corporation
+// https://www.iana.org/domains/root/db/tdk.html
 tdk
 
-// team : 2015-03-05 Binky Moon, LLC
+// team : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/team.html
 team
 
-// tech : 2015-01-30 Radix FZC
+// tech : Radix FZC DMCC
+// https://www.iana.org/domains/root/db/tech.html
 tech
 
-// technology : 2013-09-13 Binky Moon, LLC
+// technology : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/technology.html
 technology
 
-// temasek : 2014-08-07 Temasek Holdings (Private) Limited
+// temasek : Temasek Holdings (Private) Limited
+// https://www.iana.org/domains/root/db/temasek.html
 temasek
 
-// tennis : 2014-12-04 Binky Moon, LLC
+// tennis : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/tennis.html
 tennis
 
-// teva : 2015-07-02 Teva Pharmaceutical Industries Limited
+// teva : Teva Pharmaceutical Industries Limited
+// https://www.iana.org/domains/root/db/teva.html
 teva
 
-// thd : 2015-04-02 Home Depot Product Authority, LLC
+// thd : Home Depot Product Authority, LLC
+// https://www.iana.org/domains/root/db/thd.html
 thd
 
-// theater : 2015-03-19 Binky Moon, LLC
+// theater : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/theater.html
 theater
 
-// theatre : 2015-05-07 XYZ.COM LLC
+// theatre : XYZ.COM LLC
+// https://www.iana.org/domains/root/db/theatre.html
 theatre
 
-// tiaa : 2015-07-23 Teachers Insurance and Annuity Association of America
+// tiaa : Teachers Insurance and Annuity Association of America
+// https://www.iana.org/domains/root/db/tiaa.html
 tiaa
 
-// tickets : 2015-02-05 XYZ.COM LLC
+// tickets : XYZ.COM LLC
+// https://www.iana.org/domains/root/db/tickets.html
 tickets
 
-// tienda : 2013-11-14 Binky Moon, LLC
+// tienda : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/tienda.html
 tienda
 
-// tiffany : 2015-01-30 Tiffany and Company
-tiffany
-
-// tips : 2013-09-20 Binky Moon, LLC
+// tips : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/tips.html
 tips
 
-// tires : 2014-11-07 Binky Moon, LLC
+// tires : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/tires.html
 tires
 
-// tirol : 2014-04-24 punkt Tirol GmbH
+// tirol : punkt Tirol GmbH
+// https://www.iana.org/domains/root/db/tirol.html
 tirol
 
-// tjmaxx : 2015-07-16 The TJX Companies, Inc.
+// tjmaxx : The TJX Companies, Inc.
+// https://www.iana.org/domains/root/db/tjmaxx.html
 tjmaxx
 
-// tjx : 2015-07-16 The TJX Companies, Inc.
+// tjx : The TJX Companies, Inc.
+// https://www.iana.org/domains/root/db/tjx.html
 tjx
 
-// tkmaxx : 2015-07-16 The TJX Companies, Inc.
+// tkmaxx : The TJX Companies, Inc.
+// https://www.iana.org/domains/root/db/tkmaxx.html
 tkmaxx
 
-// tmall : 2015-01-15 Alibaba Group Holding Limited
+// tmall : Alibaba Group Holding Limited
+// https://www.iana.org/domains/root/db/tmall.html
 tmall
 
-// today : 2013-09-20 Binky Moon, LLC
+// today : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/today.html
 today
 
-// tokyo : 2013-11-13 GMO Registry, Inc.
+// tokyo : GMO Registry, Inc.
+// https://www.iana.org/domains/root/db/tokyo.html
 tokyo
 
-// tools : 2013-11-21 Binky Moon, LLC
+// tools : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/tools.html
 tools
 
-// top : 2014-03-20 .TOP Registry
+// top : .TOP Registry
+// https://www.iana.org/domains/root/db/top.html
 top
 
-// toray : 2014-12-18 Toray Industries, Inc.
+// toray : Toray Industries, Inc.
+// https://www.iana.org/domains/root/db/toray.html
 toray
 
-// toshiba : 2014-04-10 TOSHIBA Corporation
+// toshiba : TOSHIBA Corporation
+// https://www.iana.org/domains/root/db/toshiba.html
 toshiba
 
-// total : 2015-08-06 TotalEnergies SE
+// total : TotalEnergies SE
+// https://www.iana.org/domains/root/db/total.html
 total
 
-// tours : 2015-01-22 Binky Moon, LLC
+// tours : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/tours.html
 tours
 
-// town : 2014-03-06 Binky Moon, LLC
+// town : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/town.html
 town
 
-// toyota : 2015-04-23 TOYOTA MOTOR CORPORATION
+// toyota : TOYOTA MOTOR CORPORATION
+// https://www.iana.org/domains/root/db/toyota.html
 toyota
 
-// toys : 2014-03-06 Binky Moon, LLC
+// toys : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/toys.html
 toys
 
-// trade : 2014-01-23 Elite Registry Limited
+// trade : Elite Registry Limited
+// https://www.iana.org/domains/root/db/trade.html
 trade
 
-// trading : 2014-12-11 Dog Beach, LLC
+// trading : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/trading.html
 trading
 
-// training : 2013-11-07 Binky Moon, LLC
+// training : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/training.html
 training
 
-// travel : 2015-10-09 Dog Beach, LLC
+// travel : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/travel.html
 travel
 
-// travelchannel : 2015-07-02 Lifestyle Domain Holdings, Inc.
-travelchannel
-
-// travelers : 2015-03-26 Travelers TLD, LLC
+// travelers : Travelers TLD, LLC
+// https://www.iana.org/domains/root/db/travelers.html
 travelers
 
-// travelersinsurance : 2015-03-26 Travelers TLD, LLC
+// travelersinsurance : Travelers TLD, LLC
+// https://www.iana.org/domains/root/db/travelersinsurance.html
 travelersinsurance
 
-// trust : 2014-10-16 Internet Naming Company LLC
+// trust : Internet Naming Company LLC
+// https://www.iana.org/domains/root/db/trust.html
 trust
 
-// trv : 2015-03-26 Travelers TLD, LLC
+// trv : Travelers TLD, LLC
+// https://www.iana.org/domains/root/db/trv.html
 trv
 
-// tube : 2015-06-11 Latin American Telecom LLC
+// tube : Latin American Telecom LLC
+// https://www.iana.org/domains/root/db/tube.html
 tube
 
-// tui : 2014-07-03 TUI AG
+// tui : TUI AG
+// https://www.iana.org/domains/root/db/tui.html
 tui
 
-// tunes : 2015-02-26 Amazon Registry Services, Inc.
+// tunes : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/tunes.html
 tunes
 
-// tushu : 2014-12-18 Amazon Registry Services, Inc.
+// tushu : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/tushu.html
 tushu
 
-// tvs : 2015-02-19 T V SUNDRAM IYENGAR  & SONS LIMITED
+// tvs : T V SUNDRAM IYENGAR  & SONS LIMITED
+// https://www.iana.org/domains/root/db/tvs.html
 tvs
 
-// ubank : 2015-08-20 National Australia Bank Limited
+// ubank : National Australia Bank Limited
+// https://www.iana.org/domains/root/db/ubank.html
 ubank
 
-// ubs : 2014-12-11 UBS AG
+// ubs : UBS AG
+// https://www.iana.org/domains/root/db/ubs.html
 ubs
 
-// unicom : 2015-10-15 China United Network Communications Corporation Limited
+// unicom : China United Network Communications Corporation Limited
+// https://www.iana.org/domains/root/db/unicom.html
 unicom
 
-// university : 2014-03-06 Binky Moon, LLC
+// university : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/university.html
 university
 
-// uno : 2013-09-11 Radix FZC
+// uno : Radix FZC DMCC
+// https://www.iana.org/domains/root/db/uno.html
 uno
 
-// uol : 2014-05-01 UBN INTERNET LTDA.
+// uol : UBN INTERNET LTDA.
+// https://www.iana.org/domains/root/db/uol.html
 uol
 
-// ups : 2015-06-25 UPS Market Driver, Inc.
+// ups : UPS Market Driver, Inc.
+// https://www.iana.org/domains/root/db/ups.html
 ups
 
-// vacations : 2013-12-05 Binky Moon, LLC
+// vacations : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/vacations.html
 vacations
 
-// vana : 2014-12-11 Lifestyle Domain Holdings, Inc.
+// vana : Lifestyle Domain Holdings, Inc.
+// https://www.iana.org/domains/root/db/vana.html
 vana
 
-// vanguard : 2015-09-03 The Vanguard Group, Inc.
+// vanguard : The Vanguard Group, Inc.
+// https://www.iana.org/domains/root/db/vanguard.html
 vanguard
 
-// vegas : 2014-01-16 Dot Vegas, Inc.
+// vegas : Dot Vegas, Inc.
+// https://www.iana.org/domains/root/db/vegas.html
 vegas
 
-// ventures : 2013-08-27 Binky Moon, LLC
+// ventures : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/ventures.html
 ventures
 
-// verisign : 2015-08-13 VeriSign, Inc.
+// verisign : VeriSign, Inc.
+// https://www.iana.org/domains/root/db/verisign.html
 verisign
 
-// versicherung : 2014-03-20 tldbox GmbH
+// versicherung : tldbox GmbH
+// https://www.iana.org/domains/root/db/versicherung.html
 versicherung
 
-// vet : 2014-03-06 Dog Beach, LLC
+// vet : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/vet.html
 vet
 
-// viajes : 2013-10-17 Binky Moon, LLC
+// viajes : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/viajes.html
 viajes
 
-// video : 2014-10-16 Dog Beach, LLC
+// video : Dog Beach, LLC
+// https://www.iana.org/domains/root/db/video.html
 video
 
-// vig : 2015-05-14 VIENNA INSURANCE GROUP AG Wiener Versicherung Gruppe
+// vig : VIENNA INSURANCE GROUP AG Wiener Versicherung Gruppe
+// https://www.iana.org/domains/root/db/vig.html
 vig
 
-// viking : 2015-04-02 Viking River Cruises (Bermuda) Ltd.
+// viking : Viking River Cruises (Bermuda) Ltd.
+// https://www.iana.org/domains/root/db/viking.html
 viking
 
-// villas : 2013-12-05 Binky Moon, LLC
+// villas : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/villas.html
 villas
 
-// vin : 2015-06-18 Binky Moon, LLC
+// vin : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/vin.html
 vin
 
-// vip : 2015-01-22 Registry Services, LLC
+// vip : Registry Services, LLC
+// https://www.iana.org/domains/root/db/vip.html
 vip
 
-// virgin : 2014-09-25 Virgin Enterprises Limited
+// virgin : Virgin Enterprises Limited
+// https://www.iana.org/domains/root/db/virgin.html
 virgin
 
-// visa : 2015-07-30 Visa Worldwide Pte. Limited
+// visa : Visa Worldwide Pte. Limited
+// https://www.iana.org/domains/root/db/visa.html
 visa
 
-// vision : 2013-12-05 Binky Moon, LLC
+// vision : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/vision.html
 vision
 
-// viva : 2014-11-07 Saudi Telecom Company
+// viva : Saudi Telecom Company
+// https://www.iana.org/domains/root/db/viva.html
 viva
 
-// vivo : 2015-07-31 Telefonica Brasil S.A.
+// vivo : Telefonica Brasil S.A.
+// https://www.iana.org/domains/root/db/vivo.html
 vivo
 
-// vlaanderen : 2014-02-06 DNS.be vzw
+// vlaanderen : DNS.be vzw
+// https://www.iana.org/domains/root/db/vlaanderen.html
 vlaanderen
 
-// vodka : 2013-12-19 Registry Services, LLC
+// vodka : Registry Services, LLC
+// https://www.iana.org/domains/root/db/vodka.html
 vodka
 
-// volkswagen : 2015-05-14 Volkswagen Group of America Inc.
+// volkswagen : Volkswagen Group of America Inc.
+// https://www.iana.org/domains/root/db/volkswagen.html
 volkswagen
 
-// volvo : 2015-11-12 Volvo Holding Sverige Aktiebolag
+// volvo : Volvo Holding Sverige Aktiebolag
+// https://www.iana.org/domains/root/db/volvo.html
 volvo
 
-// vote : 2013-11-21 Monolith Registry LLC
+// vote : Monolith Registry LLC
+// https://www.iana.org/domains/root/db/vote.html
 vote
 
-// voting : 2013-11-13 Valuetainment Corp.
+// voting : Valuetainment Corp.
+// https://www.iana.org/domains/root/db/voting.html
 voting
 
-// voto : 2013-11-21 Monolith Registry LLC
+// voto : Monolith Registry LLC
+// https://www.iana.org/domains/root/db/voto.html
 voto
 
-// voyage : 2013-08-27 Binky Moon, LLC
+// voyage : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/voyage.html
 voyage
 
-// vuelos : 2015-03-05 Travel Reservations SRL
-vuelos
-
-// wales : 2014-05-08 Nominet UK
+// wales : Nominet UK
+// https://www.iana.org/domains/root/db/wales.html
 wales
 
-// walmart : 2015-07-31 Wal-Mart Stores, Inc.
+// walmart : Wal-Mart Stores, Inc.
+// https://www.iana.org/domains/root/db/walmart.html
 walmart
 
-// walter : 2014-11-13 Sandvik AB
+// walter : Sandvik AB
+// https://www.iana.org/domains/root/db/walter.html
 walter
 
-// wang : 2013-10-24 Zodiac Wang Limited
+// wang : Zodiac Wang Limited
+// https://www.iana.org/domains/root/db/wang.html
 wang
 
-// wanggou : 2014-12-18 Amazon Registry Services, Inc.
+// wanggou : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/wanggou.html
 wanggou
 
-// watch : 2013-11-14 Binky Moon, LLC
+// watch : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/watch.html
 watch
 
-// watches : 2014-12-22 Identity Digital Limited
+// watches : Identity Digital Limited
+// https://www.iana.org/domains/root/db/watches.html
 watches
 
-// weather : 2015-01-08 International Business Machines Corporation
+// weather : International Business Machines Corporation
+// https://www.iana.org/domains/root/db/weather.html
 weather
 
-// weatherchannel : 2015-03-12 International Business Machines Corporation
+// weatherchannel : International Business Machines Corporation
+// https://www.iana.org/domains/root/db/weatherchannel.html
 weatherchannel
 
-// webcam : 2014-01-23 dot Webcam Limited
+// webcam : dot Webcam Limited
+// https://www.iana.org/domains/root/db/webcam.html
 webcam
 
-// weber : 2015-06-04 Saint-Gobain Weber SA
+// weber : Saint-Gobain Weber SA
+// https://www.iana.org/domains/root/db/weber.html
 weber
 
-// website : 2014-04-03 Radix FZC
+// website : Radix FZC DMCC
+// https://www.iana.org/domains/root/db/website.html
 website
 
-// wedding : 2014-04-24 Registry Services, LLC
+// wedding : Registry Services, LLC
+// https://www.iana.org/domains/root/db/wedding.html
 wedding
 
-// weibo : 2015-03-05 Sina Corporation
+// weibo : Sina Corporation
+// https://www.iana.org/domains/root/db/weibo.html
 weibo
 
-// weir : 2015-01-29 Weir Group IP Limited
+// weir : Weir Group IP Limited
+// https://www.iana.org/domains/root/db/weir.html
 weir
 
-// whoswho : 2014-02-20 Who's Who Registry
+// whoswho : Who's Who Registry
+// https://www.iana.org/domains/root/db/whoswho.html
 whoswho
 
-// wien : 2013-10-28 punkt.wien GmbH
+// wien : punkt.wien GmbH
+// https://www.iana.org/domains/root/db/wien.html
 wien
 
-// wiki : 2013-11-07 Top Level Design, LLC
+// wiki : Registry Services, LLC
+// https://www.iana.org/domains/root/db/wiki.html
 wiki
 
-// williamhill : 2014-03-13 William Hill Organization Limited
+// williamhill : William Hill Organization Limited
+// https://www.iana.org/domains/root/db/williamhill.html
 williamhill
 
-// win : 2014-11-20 First Registry Limited
+// win : First Registry Limited
+// https://www.iana.org/domains/root/db/win.html
 win
 
-// windows : 2014-12-18 Microsoft Corporation
+// windows : Microsoft Corporation
+// https://www.iana.org/domains/root/db/windows.html
 windows
 
-// wine : 2015-06-18 Binky Moon, LLC
+// wine : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/wine.html
 wine
 
-// winners : 2015-07-16 The TJX Companies, Inc.
+// winners : The TJX Companies, Inc.
+// https://www.iana.org/domains/root/db/winners.html
 winners
 
-// wme : 2014-02-13 William Morris Endeavor Entertainment, LLC
+// wme : William Morris Endeavor Entertainment, LLC
+// https://www.iana.org/domains/root/db/wme.html
 wme
 
-// wolterskluwer : 2015-08-06 Wolters Kluwer N.V.
+// wolterskluwer : Wolters Kluwer N.V.
+// https://www.iana.org/domains/root/db/wolterskluwer.html
 wolterskluwer
 
-// woodside : 2015-07-09 Woodside Petroleum Limited
+// woodside : Woodside Petroleum Limited
+// https://www.iana.org/domains/root/db/woodside.html
 woodside
 
-// work : 2013-12-19 Registry Services, LLC
+// work : Registry Services, LLC
+// https://www.iana.org/domains/root/db/work.html
 work
 
-// works : 2013-11-14 Binky Moon, LLC
+// works : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/works.html
 works
 
-// world : 2014-06-12 Binky Moon, LLC
+// world : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/world.html
 world
 
-// wow : 2015-10-08 Amazon Registry Services, Inc.
+// wow : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/wow.html
 wow
 
-// wtc : 2013-12-19 World Trade Centers Association, Inc.
+// wtc : World Trade Centers Association, Inc.
+// https://www.iana.org/domains/root/db/wtc.html
 wtc
 
-// wtf : 2014-03-06 Binky Moon, LLC
+// wtf : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/wtf.html
 wtf
 
-// xbox : 2014-12-18 Microsoft Corporation
+// xbox : Microsoft Corporation
+// https://www.iana.org/domains/root/db/xbox.html
 xbox
 
-// xerox : 2014-10-24 Xerox DNHC LLC
+// xerox : Xerox DNHC LLC
+// https://www.iana.org/domains/root/db/xerox.html
 xerox
 
-// xfinity : 2015-07-09 Comcast IP Holdings I, LLC
+// xfinity : Comcast IP Holdings I, LLC
+// https://www.iana.org/domains/root/db/xfinity.html
 xfinity
 
-// xihuan : 2015-01-08 Beijing Qihu Keji Co., Ltd.
+// xihuan : Beijing Qihu Keji Co., Ltd.
+// https://www.iana.org/domains/root/db/xihuan.html
 xihuan
 
-// xin : 2014-12-11 Elegant Leader Limited
+// xin : Elegant Leader Limited
+// https://www.iana.org/domains/root/db/xin.html
 xin
 
-// xn--11b4c3d : 2015-01-15 VeriSign Sarl
+// xn--11b4c3d : VeriSign Sarl
+// https://www.iana.org/domains/root/db/xn--11b4c3d.html
 कॉम
 
-// xn--1ck2e1b : 2015-02-26 Amazon Registry Services, Inc.
+// xn--1ck2e1b : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/xn--1ck2e1b.html
 セール
 
-// xn--1qqw23a : 2014-01-09 Guangzhou YU Wei Information Technology Co., Ltd.
+// xn--1qqw23a : Guangzhou YU Wei Information Technology Co., Ltd.
+// https://www.iana.org/domains/root/db/xn--1qqw23a.html
 佛山
 
-// xn--30rr7y : 2014-06-12 Excellent First Limited
+// xn--30rr7y : Excellent First Limited
+// https://www.iana.org/domains/root/db/xn--30rr7y.html
 慈善
 
-// xn--3bst00m : 2013-09-13 Eagle Horizon Limited
+// xn--3bst00m : Eagle Horizon Limited
+// https://www.iana.org/domains/root/db/xn--3bst00m.html
 集团
 
-// xn--3ds443g : 2013-09-08 TLD REGISTRY LIMITED OY
+// xn--3ds443g : TLD REGISTRY LIMITED OY
+// https://www.iana.org/domains/root/db/xn--3ds443g.html
 在线
 
-// xn--3pxu8k : 2015-01-15 VeriSign Sarl
+// xn--3pxu8k : VeriSign Sarl
+// https://www.iana.org/domains/root/db/xn--3pxu8k.html
 点看
 
-// xn--42c2d9a : 2015-01-15 VeriSign Sarl
+// xn--42c2d9a : VeriSign Sarl
+// https://www.iana.org/domains/root/db/xn--42c2d9a.html
 คอม
 
-// xn--45q11c : 2013-11-21 Zodiac Gemini Ltd
+// xn--45q11c : Zodiac Gemini Ltd
+// https://www.iana.org/domains/root/db/xn--45q11c.html
 八卦
 
-// xn--4gbrim : 2013-10-04 Helium TLDs Ltd
+// xn--4gbrim : Helium TLDs Ltd
+// https://www.iana.org/domains/root/db/xn--4gbrim.html
 موقع
 
-// xn--55qw42g : 2013-11-08 China Organizational Name Administration Center
+// xn--55qw42g : China Organizational Name Administration Center
+// https://www.iana.org/domains/root/db/xn--55qw42g.html
 公益
 
-// xn--55qx5d : 2013-11-14 China Internet Network Information Center (CNNIC)
+// xn--55qx5d : China Internet Network Information Center (CNNIC)
+// https://www.iana.org/domains/root/db/xn--55qx5d.html
 公司
 
-// xn--5su34j936bgsg : 2015-09-03 Shangri‐La International Hotel Management Limited
+// xn--5su34j936bgsg : Shangri‐La International Hotel Management Limited
+// https://www.iana.org/domains/root/db/xn--5su34j936bgsg.html
 香格里拉
 
-// xn--5tzm5g : 2014-12-22 Global Website TLD Asia Limited
+// xn--5tzm5g : Global Website TLD Asia Limited
+// https://www.iana.org/domains/root/db/xn--5tzm5g.html
 网站
 
-// xn--6frz82g : 2013-09-23 Identity Digital Limited
+// xn--6frz82g : Identity Digital Limited
+// https://www.iana.org/domains/root/db/xn--6frz82g.html
 移动
 
-// xn--6qq986b3xl : 2013-09-13 Tycoon Treasure Limited
+// xn--6qq986b3xl : Tycoon Treasure Limited
+// https://www.iana.org/domains/root/db/xn--6qq986b3xl.html
 我爱你
 
-// xn--80adxhks : 2013-12-19 Foundation for Assistance for Internet Technologies and Infrastructure Development (FAITID)
+// xn--80adxhks : Foundation for Assistance for Internet Technologies and Infrastructure Development (FAITID)
+// https://www.iana.org/domains/root/db/xn--80adxhks.html
 москва
 
-// xn--80aqecdr1a : 2015-10-21 Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication)
+// xn--80aqecdr1a : Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication)
+// https://www.iana.org/domains/root/db/xn--80aqecdr1a.html
 католик
 
-// xn--80asehdb : 2013-07-14 CORE Association
+// xn--80asehdb : CORE Association
+// https://www.iana.org/domains/root/db/xn--80asehdb.html
 онлайн
 
-// xn--80aswg : 2013-07-14 CORE Association
+// xn--80aswg : CORE Association
+// https://www.iana.org/domains/root/db/xn--80aswg.html
 сайт
 
-// xn--8y0a063a : 2015-03-26 China United Network Communications Corporation Limited
+// xn--8y0a063a : China United Network Communications Corporation Limited
+// https://www.iana.org/domains/root/db/xn--8y0a063a.html
 联通
 
-// xn--9dbq2a : 2015-01-15 VeriSign Sarl
+// xn--9dbq2a : VeriSign Sarl
+// https://www.iana.org/domains/root/db/xn--9dbq2a.html
 קום
 
-// xn--9et52u : 2014-06-12 RISE VICTORY LIMITED
+// xn--9et52u : RISE VICTORY LIMITED
+// https://www.iana.org/domains/root/db/xn--9et52u.html
 时尚
 
-// xn--9krt00a : 2015-03-12 Sina Corporation
+// xn--9krt00a : Sina Corporation
+// https://www.iana.org/domains/root/db/xn--9krt00a.html
 微博
 
-// xn--b4w605ferd : 2014-08-07 Temasek Holdings (Private) Limited
+// xn--b4w605ferd : Temasek Holdings (Private) Limited
+// https://www.iana.org/domains/root/db/xn--b4w605ferd.html
 淡马锡
 
-// xn--bck1b9a5dre4c : 2015-02-26 Amazon Registry Services, Inc.
+// xn--bck1b9a5dre4c : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/xn--bck1b9a5dre4c.html
 ファッション
 
-// xn--c1avg : 2013-11-14 Public Interest Registry
+// xn--c1avg : Public Interest Registry
+// https://www.iana.org/domains/root/db/xn--c1avg.html
 орг
 
-// xn--c2br7g : 2015-01-15 VeriSign Sarl
+// xn--c2br7g : VeriSign Sarl
+// https://www.iana.org/domains/root/db/xn--c2br7g.html
 नेट
 
-// xn--cck2b3b : 2015-02-26 Amazon Registry Services, Inc.
+// xn--cck2b3b : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/xn--cck2b3b.html
 ストア
 
-// xn--cckwcxetd : 2019-12-19 Amazon Registry Services, Inc.
+// xn--cckwcxetd : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/xn--cckwcxetd.html
 アマゾン
 
-// xn--cg4bki : 2013-09-27 SAMSUNG SDS CO., LTD
+// xn--cg4bki : SAMSUNG SDS CO., LTD
+// https://www.iana.org/domains/root/db/xn--cg4bki.html
 삼성
 
-// xn--czr694b : 2014-01-16 Internet DotTrademark Organisation Limited
+// xn--czr694b : Internet DotTrademark Organisation Limited
+// https://www.iana.org/domains/root/db/xn--czr694b.html
 商标
 
-// xn--czrs0t : 2013-12-19 Binky Moon, LLC
+// xn--czrs0t : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/xn--czrs0t.html
 商店
 
-// xn--czru2d : 2013-11-21 Zodiac Aquarius Limited
+// xn--czru2d : Zodiac Aquarius Limited
+// https://www.iana.org/domains/root/db/xn--czru2d.html
 商城
 
-// xn--d1acj3b : 2013-11-20 The Foundation for Network Initiatives “The Smart Internet”
+// xn--d1acj3b : The Foundation for Network Initiatives “The Smart Internet”
+// https://www.iana.org/domains/root/db/xn--d1acj3b.html
 дети
 
-// xn--eckvdtc9d : 2014-12-18 Amazon Registry Services, Inc.
+// xn--eckvdtc9d : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/xn--eckvdtc9d.html
 ポイント
 
-// xn--efvy88h : 2014-08-22 Guangzhou YU Wei Information Technology Co., Ltd.
+// xn--efvy88h : Guangzhou YU Wei Information Technology Co., Ltd.
+// https://www.iana.org/domains/root/db/xn--efvy88h.html
 新闻
 
-// xn--fct429k : 2015-04-09 Amazon Registry Services, Inc.
+// xn--fct429k : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/xn--fct429k.html
 家電
 
-// xn--fhbei : 2015-01-15 VeriSign Sarl
+// xn--fhbei : VeriSign Sarl
+// https://www.iana.org/domains/root/db/xn--fhbei.html
 كوم
 
-// xn--fiq228c5hs : 2013-09-08 TLD REGISTRY LIMITED OY
+// xn--fiq228c5hs : TLD REGISTRY LIMITED OY
+// https://www.iana.org/domains/root/db/xn--fiq228c5hs.html
 中文网
 
-// xn--fiq64b : 2013-10-14 CITIC Group Corporation
+// xn--fiq64b : CITIC Group Corporation
+// https://www.iana.org/domains/root/db/xn--fiq64b.html
 中信
 
-// xn--fjq720a : 2014-05-22 Binky Moon, LLC
+// xn--fjq720a : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/xn--fjq720a.html
 娱乐
 
-// xn--flw351e : 2014-07-31 Charleston Road Registry Inc.
+// xn--flw351e : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/xn--flw351e.html
 谷歌
 
-// xn--fzys8d69uvgm : 2015-05-14 PCCW Enterprises Limited
+// xn--fzys8d69uvgm : PCCW Enterprises Limited
+// https://www.iana.org/domains/root/db/xn--fzys8d69uvgm.html
 電訊盈科
 
-// xn--g2xx48c : 2015-01-30 Nawang Heli(Xiamen) Network Service Co., LTD.
+// xn--g2xx48c : Nawang Heli(Xiamen) Network Service Co., LTD.
+// https://www.iana.org/domains/root/db/xn--g2xx48c.html
 购物
 
-// xn--gckr3f0f : 2015-02-26 Amazon Registry Services, Inc.
+// xn--gckr3f0f : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/xn--gckr3f0f.html
 クラウド
 
-// xn--gk3at1e : 2015-10-08 Amazon Registry Services, Inc.
+// xn--gk3at1e : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/xn--gk3at1e.html
 通販
 
-// xn--hxt814e : 2014-05-15 Zodiac Taurus Limited
+// xn--hxt814e : Zodiac Taurus Limited
+// https://www.iana.org/domains/root/db/xn--hxt814e.html
 网店
 
-// xn--i1b6b1a6a2e : 2013-11-14 Public Interest Registry
+// xn--i1b6b1a6a2e : Public Interest Registry
+// https://www.iana.org/domains/root/db/xn--i1b6b1a6a2e.html
 संगठन
 
-// xn--imr513n : 2014-12-11 Internet DotTrademark Organisation Limited
+// xn--imr513n : Internet DotTrademark Organisation Limited
+// https://www.iana.org/domains/root/db/xn--imr513n.html
 餐厅
 
-// xn--io0a7i : 2013-11-14 China Internet Network Information Center (CNNIC)
+// xn--io0a7i : China Internet Network Information Center (CNNIC)
+// https://www.iana.org/domains/root/db/xn--io0a7i.html
 网络
 
-// xn--j1aef : 2015-01-15 VeriSign Sarl
+// xn--j1aef : VeriSign Sarl
+// https://www.iana.org/domains/root/db/xn--j1aef.html
 ком
 
-// xn--jlq480n2rg : 2019-12-19 Amazon Registry Services, Inc.
+// xn--jlq480n2rg : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/xn--jlq480n2rg.html
 亚马逊
 
-// xn--jvr189m : 2015-02-26 Amazon Registry Services, Inc.
+// xn--jvr189m : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/xn--jvr189m.html
 食品
 
-// xn--kcrx77d1x4a : 2014-11-07 Koninklijke Philips N.V.
+// xn--kcrx77d1x4a : Koninklijke Philips N.V.
+// https://www.iana.org/domains/root/db/xn--kcrx77d1x4a.html
 飞利浦
 
-// xn--kput3i : 2014-02-13 Beijing RITT-Net Technology Development Co., Ltd
+// xn--kput3i : Beijing RITT-Net Technology Development Co., Ltd
+// https://www.iana.org/domains/root/db/xn--kput3i.html
 手机
 
-// xn--mgba3a3ejt : 2014-11-20 Aramco Services Company
+// xn--mgba3a3ejt : Aramco Services Company
+// https://www.iana.org/domains/root/db/xn--mgba3a3ejt.html
 ارامكو
 
-// xn--mgba7c0bbn0a : 2015-05-14 Crescent Holding GmbH
+// xn--mgba7c0bbn0a : Competrol (Luxembourg) Sarl
+// https://www.iana.org/domains/root/db/xn--mgba7c0bbn0a.html
 العليان
 
-// xn--mgbaakc7dvf : 2015-09-03 Emirates Telecommunications Corporation (trading as Etisalat)
+// xn--mgbaakc7dvf : Emirates Telecommunications Corporation (trading as Etisalat)
+// https://www.iana.org/domains/root/db/xn--mgbaakc7dvf.html
 اتصالات
 
-// xn--mgbab2bd : 2013-10-31 CORE Association
+// xn--mgbab2bd : CORE Association
+// https://www.iana.org/domains/root/db/xn--mgbab2bd.html
 بازار
 
-// xn--mgbca7dzdo : 2015-07-30 Abu Dhabi Systems and Information Centre
+// xn--mgbca7dzdo : Abu Dhabi Systems and Information Centre
+// https://www.iana.org/domains/root/db/xn--mgbca7dzdo.html
 ابوظبي
 
-// xn--mgbi4ecexp : 2015-10-21 Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication)
+// xn--mgbi4ecexp : Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication)
+// https://www.iana.org/domains/root/db/xn--mgbi4ecexp.html
 كاثوليك
 
-// xn--mgbt3dhd : 2014-09-04 Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti.
+// xn--mgbt3dhd : Asia Green IT System Bilgisayar San. ve Tic. Ltd. Sti.
+// https://www.iana.org/domains/root/db/xn--mgbt3dhd.html
 همراه
 
-// xn--mk1bu44c : 2015-01-15 VeriSign Sarl
+// xn--mk1bu44c : VeriSign Sarl
+// https://www.iana.org/domains/root/db/xn--mk1bu44c.html
 닷컴
 
-// xn--mxtq1m : 2014-03-06 Net-Chinese Co., Ltd.
+// xn--mxtq1m : Net-Chinese Co., Ltd.
+// https://www.iana.org/domains/root/db/xn--mxtq1m.html
 政府
 
-// xn--ngbc5azd : 2013-07-13 International Domain Registry Pty. Ltd.
+// xn--ngbc5azd : International Domain Registry Pty. Ltd.
+// https://www.iana.org/domains/root/db/xn--ngbc5azd.html
 شبكة
 
-// xn--ngbe9e0a : 2014-12-04 Kuwait Finance House
+// xn--ngbe9e0a : Kuwait Finance House
+// https://www.iana.org/domains/root/db/xn--ngbe9e0a.html
 بيتك
 
-// xn--ngbrx : 2015-11-12 League of Arab States
+// xn--ngbrx : League of Arab States
+// https://www.iana.org/domains/root/db/xn--ngbrx.html
 عرب
 
-// xn--nqv7f : 2013-11-14 Public Interest Registry
+// xn--nqv7f : Public Interest Registry
+// https://www.iana.org/domains/root/db/xn--nqv7f.html
 机构
 
-// xn--nqv7fs00ema : 2013-11-14 Public Interest Registry
+// xn--nqv7fs00ema : Public Interest Registry
+// https://www.iana.org/domains/root/db/xn--nqv7fs00ema.html
 组织机构
 
-// xn--nyqy26a : 2014-11-07 Stable Tone Limited
+// xn--nyqy26a : Stable Tone Limited
+// https://www.iana.org/domains/root/db/xn--nyqy26a.html
 健康
 
-// xn--otu796d : 2017-08-06 Jiang Yu Liang Cai Technology Company Limited
+// xn--otu796d : Jiang Yu Liang Cai Technology Company Limited
+// https://www.iana.org/domains/root/db/xn--otu796d.html
 招聘
 
-// xn--p1acf : 2013-12-12 Rusnames Limited
+// xn--p1acf : Rusnames Limited
+// https://www.iana.org/domains/root/db/xn--p1acf.html
 рус
 
-// xn--pssy2u : 2015-01-15 VeriSign Sarl
+// xn--pssy2u : VeriSign Sarl
+// https://www.iana.org/domains/root/db/xn--pssy2u.html
 大拿
 
-// xn--q9jyb4c : 2013-09-17 Charleston Road Registry Inc.
+// xn--q9jyb4c : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/xn--q9jyb4c.html
 みんな
 
-// xn--qcka1pmc : 2014-07-31 Charleston Road Registry Inc.
+// xn--qcka1pmc : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/xn--qcka1pmc.html
 グーグル
 
-// xn--rhqv96g : 2013-09-11 Stable Tone Limited
+// xn--rhqv96g : Stable Tone Limited
+// https://www.iana.org/domains/root/db/xn--rhqv96g.html
 世界
 
-// xn--rovu88b : 2015-02-26 Amazon Registry Services, Inc.
+// xn--rovu88b : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/xn--rovu88b.html
 書籍
 
-// xn--ses554g : 2014-01-16 KNET Co., Ltd.
+// xn--ses554g : KNET Co., Ltd.
+// https://www.iana.org/domains/root/db/xn--ses554g.html
 网址
 
-// xn--t60b56a : 2015-01-15 VeriSign Sarl
+// xn--t60b56a : VeriSign Sarl
+// https://www.iana.org/domains/root/db/xn--t60b56a.html
 닷넷
 
-// xn--tckwe : 2015-01-15 VeriSign Sarl
+// xn--tckwe : VeriSign Sarl
+// https://www.iana.org/domains/root/db/xn--tckwe.html
 コム
 
-// xn--tiq49xqyj : 2015-10-21 Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication)
+// xn--tiq49xqyj : Pontificium Consilium de Comunicationibus Socialibus (PCCS) (Pontifical Council for Social Communication)
+// https://www.iana.org/domains/root/db/xn--tiq49xqyj.html
 天主教
 
-// xn--unup4y : 2013-07-14 Binky Moon, LLC
+// xn--unup4y : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/xn--unup4y.html
 游戏
 
-// xn--vermgensberater-ctb : 2014-06-23 Deutsche Vermögensberatung Aktiengesellschaft DVAG
+// xn--vermgensberater-ctb : Deutsche Vermögensberatung Aktiengesellschaft DVAG
+// https://www.iana.org/domains/root/db/xn--vermgensberater-ctb.html
 vermögensberater
 
-// xn--vermgensberatung-pwb : 2014-06-23 Deutsche Vermögensberatung Aktiengesellschaft DVAG
+// xn--vermgensberatung-pwb : Deutsche Vermögensberatung Aktiengesellschaft DVAG
+// https://www.iana.org/domains/root/db/xn--vermgensberatung-pwb.html
 vermögensberatung
 
-// xn--vhquv : 2013-08-27 Binky Moon, LLC
+// xn--vhquv : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/xn--vhquv.html
 企业
 
-// xn--vuq861b : 2014-10-16 Beijing Tele-info Network Technology Co., Ltd.
+// xn--vuq861b : Beijing Tele-info Technology Co., Ltd.
+// https://www.iana.org/domains/root/db/xn--vuq861b.html
 信息
 
-// xn--w4r85el8fhu5dnra : 2015-04-30 Kerry Trading Co. Limited
+// xn--w4r85el8fhu5dnra : Kerry Trading Co. Limited
+// https://www.iana.org/domains/root/db/xn--w4r85el8fhu5dnra.html
 嘉里大酒店
 
-// xn--w4rs40l : 2015-07-30 Kerry Trading Co. Limited
+// xn--w4rs40l : Kerry Trading Co. Limited
+// https://www.iana.org/domains/root/db/xn--w4rs40l.html
 嘉里
 
-// xn--xhq521b : 2013-11-14 Guangzhou YU Wei Information Technology Co., Ltd.
+// xn--xhq521b : Guangzhou YU Wei Information Technology Co., Ltd.
+// https://www.iana.org/domains/root/db/xn--xhq521b.html
 广东
 
-// xn--zfr164b : 2013-11-08 China Organizational Name Administration Center
+// xn--zfr164b : China Organizational Name Administration Center
+// https://www.iana.org/domains/root/db/xn--zfr164b.html
 政务
 
-// xyz : 2013-12-05 XYZ.COM LLC
+// xyz : XYZ.COM LLC
+// https://www.iana.org/domains/root/db/xyz.html
 xyz
 
-// yachts : 2014-01-09 XYZ.COM LLC
+// yachts : XYZ.COM LLC
+// https://www.iana.org/domains/root/db/yachts.html
 yachts
 
-// yahoo : 2015-04-02 Oath Inc.
+// yahoo : Oath Inc.
+// https://www.iana.org/domains/root/db/yahoo.html
 yahoo
 
-// yamaxun : 2014-12-18 Amazon Registry Services, Inc.
+// yamaxun : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/yamaxun.html
 yamaxun
 
-// yandex : 2014-04-10 Yandex Europe B.V.
+// yandex : Yandex Europe B.V.
+// https://www.iana.org/domains/root/db/yandex.html
 yandex
 
-// yodobashi : 2014-11-20 YODOBASHI CAMERA CO.,LTD.
+// yodobashi : YODOBASHI CAMERA CO.,LTD.
+// https://www.iana.org/domains/root/db/yodobashi.html
 yodobashi
 
-// yoga : 2014-05-29 Registry Services, LLC
+// yoga : Registry Services, LLC
+// https://www.iana.org/domains/root/db/yoga.html
 yoga
 
-// yokohama : 2013-12-12 GMO Registry, Inc.
+// yokohama : GMO Registry, Inc.
+// https://www.iana.org/domains/root/db/yokohama.html
 yokohama
 
-// you : 2015-04-09 Amazon Registry Services, Inc.
+// you : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/you.html
 you
 
-// youtube : 2014-05-01 Charleston Road Registry Inc.
+// youtube : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/youtube.html
 youtube
 
-// yun : 2015-01-08 Beijing Qihu Keji Co., Ltd.
+// yun : Beijing Qihu Keji Co., Ltd.
+// https://www.iana.org/domains/root/db/yun.html
 yun
 
-// zappos : 2015-06-25 Amazon Registry Services, Inc.
+// zappos : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/zappos.html
 zappos
 
-// zara : 2014-11-07 Industria de Diseño Textil, S.A. (INDITEX, S.A.)
+// zara : Industria de Diseño Textil, S.A. (INDITEX, S.A.)
+// https://www.iana.org/domains/root/db/zara.html
 zara
 
-// zero : 2014-12-18 Amazon Registry Services, Inc.
+// zero : Amazon Registry Services, Inc.
+// https://www.iana.org/domains/root/db/zero.html
 zero
 
-// zip : 2014-05-08 Charleston Road Registry Inc.
+// zip : Charleston Road Registry Inc.
+// https://www.iana.org/domains/root/db/zip.html
 zip
 
-// zone : 2013-11-14 Binky Moon, LLC
+// zone : Binky Moon, LLC
+// https://www.iana.org/domains/root/db/zone.html
 zone
 
-// zuerich : 2014-11-07 Kanton Zürich (Canton of Zurich)
+// zuerich : Kanton Zürich (Canton of Zurich)
+// https://www.iana.org/domains/root/db/zuerich.html
 zuerich
 
 
@@ -10189,11 +11317,78 @@
 // Submitted by AWS Security <psl-maintainers@amazon.com>
 // Subsections of Amazon/subsidiaries will appear until "concludes" tag
 
+// Amazon API Gateway
+// Submitted by AWS Security <psl-maintainers@amazon.com>
+// Reference: 4d863337-ff98-4501-a6f2-361eba8445d6
+execute-api.cn-north-1.amazonaws.com.cn
+execute-api.cn-northwest-1.amazonaws.com.cn
+execute-api.af-south-1.amazonaws.com
+execute-api.ap-east-1.amazonaws.com
+execute-api.ap-northeast-1.amazonaws.com
+execute-api.ap-northeast-2.amazonaws.com
+execute-api.ap-northeast-3.amazonaws.com
+execute-api.ap-south-1.amazonaws.com
+execute-api.ap-south-2.amazonaws.com
+execute-api.ap-southeast-1.amazonaws.com
+execute-api.ap-southeast-2.amazonaws.com
+execute-api.ap-southeast-3.amazonaws.com
+execute-api.ap-southeast-4.amazonaws.com
+execute-api.ca-central-1.amazonaws.com
+execute-api.eu-central-1.amazonaws.com
+execute-api.eu-central-2.amazonaws.com
+execute-api.eu-north-1.amazonaws.com
+execute-api.eu-south-1.amazonaws.com
+execute-api.eu-south-2.amazonaws.com
+execute-api.eu-west-1.amazonaws.com
+execute-api.eu-west-2.amazonaws.com
+execute-api.eu-west-3.amazonaws.com
+execute-api.il-central-1.amazonaws.com
+execute-api.me-central-1.amazonaws.com
+execute-api.me-south-1.amazonaws.com
+execute-api.sa-east-1.amazonaws.com
+execute-api.us-east-1.amazonaws.com
+execute-api.us-east-2.amazonaws.com
+execute-api.us-gov-east-1.amazonaws.com
+execute-api.us-gov-west-1.amazonaws.com
+execute-api.us-west-1.amazonaws.com
+execute-api.us-west-2.amazonaws.com
+
 // Amazon CloudFront
 // Submitted by Donavan Miller <donavanm@amazon.com>
 // Reference: 54144616-fd49-4435-8535-19c6a601bdb3
 cloudfront.net
 
+// Amazon Cognito
+// Submitted by AWS Security <psl-maintainers@amazon.com>
+// Reference: 7bee1013-f456-47df-bfe8-03c78d946d61
+auth.af-south-1.amazoncognito.com
+auth.ap-northeast-1.amazoncognito.com
+auth.ap-northeast-2.amazoncognito.com
+auth.ap-northeast-3.amazoncognito.com
+auth.ap-south-1.amazoncognito.com
+auth.ap-southeast-1.amazoncognito.com
+auth.ap-southeast-2.amazoncognito.com
+auth.ap-southeast-3.amazoncognito.com
+auth.ca-central-1.amazoncognito.com
+auth.eu-central-1.amazoncognito.com
+auth.eu-north-1.amazoncognito.com
+auth.eu-south-1.amazoncognito.com
+auth.eu-west-1.amazoncognito.com
+auth.eu-west-2.amazoncognito.com
+auth.eu-west-3.amazoncognito.com
+auth.il-central-1.amazoncognito.com
+auth.me-south-1.amazoncognito.com
+auth.sa-east-1.amazoncognito.com
+auth.us-east-1.amazoncognito.com
+auth-fips.us-east-1.amazoncognito.com
+auth.us-east-2.amazoncognito.com
+auth-fips.us-east-2.amazoncognito.com
+auth-fips.us-gov-west-1.amazoncognito.com
+auth.us-west-1.amazoncognito.com
+auth-fips.us-west-1.amazoncognito.com
+auth.us-west-2.amazoncognito.com
+auth-fips.us-west-2.amazoncognito.com
+
 // Amazon EC2
 // Submitted by Luke Wells <psl-maintainers@amazon.com>
 // Reference: 4c38fa71-58ac-4768-99e5-689c1767e537
@@ -10202,47 +11397,307 @@
 *.compute.amazonaws.com.cn
 us-east-1.amazonaws.com
 
+// Amazon EMR
+// Submitted by AWS Security <psl-maintainers@amazon.com>
+// Reference: 597f3f8e-9283-4e48-8e32-7ee25a1ff6ab
+emrappui-prod.cn-north-1.amazonaws.com.cn
+emrnotebooks-prod.cn-north-1.amazonaws.com.cn
+emrstudio-prod.cn-north-1.amazonaws.com.cn
+emrappui-prod.cn-northwest-1.amazonaws.com.cn
+emrnotebooks-prod.cn-northwest-1.amazonaws.com.cn
+emrstudio-prod.cn-northwest-1.amazonaws.com.cn
+emrappui-prod.af-south-1.amazonaws.com
+emrnotebooks-prod.af-south-1.amazonaws.com
+emrstudio-prod.af-south-1.amazonaws.com
+emrappui-prod.ap-east-1.amazonaws.com
+emrnotebooks-prod.ap-east-1.amazonaws.com
+emrstudio-prod.ap-east-1.amazonaws.com
+emrappui-prod.ap-northeast-1.amazonaws.com
+emrnotebooks-prod.ap-northeast-1.amazonaws.com
+emrstudio-prod.ap-northeast-1.amazonaws.com
+emrappui-prod.ap-northeast-2.amazonaws.com
+emrnotebooks-prod.ap-northeast-2.amazonaws.com
+emrstudio-prod.ap-northeast-2.amazonaws.com
+emrappui-prod.ap-northeast-3.amazonaws.com
+emrnotebooks-prod.ap-northeast-3.amazonaws.com
+emrstudio-prod.ap-northeast-3.amazonaws.com
+emrappui-prod.ap-south-1.amazonaws.com
+emrnotebooks-prod.ap-south-1.amazonaws.com
+emrstudio-prod.ap-south-1.amazonaws.com
+emrappui-prod.ap-southeast-1.amazonaws.com
+emrnotebooks-prod.ap-southeast-1.amazonaws.com
+emrstudio-prod.ap-southeast-1.amazonaws.com
+emrappui-prod.ap-southeast-2.amazonaws.com
+emrnotebooks-prod.ap-southeast-2.amazonaws.com
+emrstudio-prod.ap-southeast-2.amazonaws.com
+emrappui-prod.ap-southeast-3.amazonaws.com
+emrnotebooks-prod.ap-southeast-3.amazonaws.com
+emrstudio-prod.ap-southeast-3.amazonaws.com
+emrappui-prod.ca-central-1.amazonaws.com
+emrnotebooks-prod.ca-central-1.amazonaws.com
+emrstudio-prod.ca-central-1.amazonaws.com
+emrappui-prod.eu-central-1.amazonaws.com
+emrnotebooks-prod.eu-central-1.amazonaws.com
+emrstudio-prod.eu-central-1.amazonaws.com
+emrappui-prod.eu-north-1.amazonaws.com
+emrnotebooks-prod.eu-north-1.amazonaws.com
+emrstudio-prod.eu-north-1.amazonaws.com
+emrappui-prod.eu-south-1.amazonaws.com
+emrnotebooks-prod.eu-south-1.amazonaws.com
+emrstudio-prod.eu-south-1.amazonaws.com
+emrappui-prod.eu-west-1.amazonaws.com
+emrnotebooks-prod.eu-west-1.amazonaws.com
+emrstudio-prod.eu-west-1.amazonaws.com
+emrappui-prod.eu-west-2.amazonaws.com
+emrnotebooks-prod.eu-west-2.amazonaws.com
+emrstudio-prod.eu-west-2.amazonaws.com
+emrappui-prod.eu-west-3.amazonaws.com
+emrnotebooks-prod.eu-west-3.amazonaws.com
+emrstudio-prod.eu-west-3.amazonaws.com
+emrappui-prod.me-central-1.amazonaws.com
+emrnotebooks-prod.me-central-1.amazonaws.com
+emrstudio-prod.me-central-1.amazonaws.com
+emrappui-prod.me-south-1.amazonaws.com
+emrnotebooks-prod.me-south-1.amazonaws.com
+emrstudio-prod.me-south-1.amazonaws.com
+emrappui-prod.sa-east-1.amazonaws.com
+emrnotebooks-prod.sa-east-1.amazonaws.com
+emrstudio-prod.sa-east-1.amazonaws.com
+emrappui-prod.us-east-1.amazonaws.com
+emrnotebooks-prod.us-east-1.amazonaws.com
+emrstudio-prod.us-east-1.amazonaws.com
+emrappui-prod.us-east-2.amazonaws.com
+emrnotebooks-prod.us-east-2.amazonaws.com
+emrstudio-prod.us-east-2.amazonaws.com
+emrappui-prod.us-gov-east-1.amazonaws.com
+emrnotebooks-prod.us-gov-east-1.amazonaws.com
+emrstudio-prod.us-gov-east-1.amazonaws.com
+emrappui-prod.us-gov-west-1.amazonaws.com
+emrnotebooks-prod.us-gov-west-1.amazonaws.com
+emrstudio-prod.us-gov-west-1.amazonaws.com
+emrappui-prod.us-west-1.amazonaws.com
+emrnotebooks-prod.us-west-1.amazonaws.com
+emrstudio-prod.us-west-1.amazonaws.com
+emrappui-prod.us-west-2.amazonaws.com
+emrnotebooks-prod.us-west-2.amazonaws.com
+emrstudio-prod.us-west-2.amazonaws.com
+
+// Amazon Managed Workflows for Apache Airflow
+// Submitted by AWS Security <psl-maintainers@amazon.com>
+// Reference: 4ab55e6f-90c0-4a8d-b6a0-52ca5dbb1c2e
+*.cn-north-1.airflow.amazonaws.com.cn
+*.cn-northwest-1.airflow.amazonaws.com.cn
+*.ap-northeast-1.airflow.amazonaws.com
+*.ap-northeast-2.airflow.amazonaws.com
+*.ap-south-1.airflow.amazonaws.com
+*.ap-southeast-1.airflow.amazonaws.com
+*.ap-southeast-2.airflow.amazonaws.com
+*.ca-central-1.airflow.amazonaws.com
+*.eu-central-1.airflow.amazonaws.com
+*.eu-north-1.airflow.amazonaws.com
+*.eu-west-1.airflow.amazonaws.com
+*.eu-west-2.airflow.amazonaws.com
+*.eu-west-3.airflow.amazonaws.com
+*.sa-east-1.airflow.amazonaws.com
+*.us-east-1.airflow.amazonaws.com
+*.us-east-2.airflow.amazonaws.com
+*.us-west-2.airflow.amazonaws.com
+
 // Amazon S3
-// Submitted by Luke Wells <psl-maintainers@amazon.com>
-// Reference: d068bd97-f0a9-4838-a6d8-954b622ef4ae
+// Submitted by AWS Security <psl-maintainers@amazon.com>
+// Reference: 0e801048-08f2-4064-9cb8-e7373e0b57f4
+s3.dualstack.cn-north-1.amazonaws.com.cn
+s3-accesspoint.dualstack.cn-north-1.amazonaws.com.cn
+s3-website.dualstack.cn-north-1.amazonaws.com.cn
 s3.cn-north-1.amazonaws.com.cn
+s3-accesspoint.cn-north-1.amazonaws.com.cn
+s3-deprecated.cn-north-1.amazonaws.com.cn
+s3-object-lambda.cn-north-1.amazonaws.com.cn
+s3-website.cn-north-1.amazonaws.com.cn
+s3.dualstack.cn-northwest-1.amazonaws.com.cn
+s3-accesspoint.dualstack.cn-northwest-1.amazonaws.com.cn
+s3.cn-northwest-1.amazonaws.com.cn
+s3-accesspoint.cn-northwest-1.amazonaws.com.cn
+s3-object-lambda.cn-northwest-1.amazonaws.com.cn
+s3-website.cn-northwest-1.amazonaws.com.cn
+s3.dualstack.af-south-1.amazonaws.com
+s3-accesspoint.dualstack.af-south-1.amazonaws.com
+s3-website.dualstack.af-south-1.amazonaws.com
+s3.af-south-1.amazonaws.com
+s3-accesspoint.af-south-1.amazonaws.com
+s3-object-lambda.af-south-1.amazonaws.com
+s3-website.af-south-1.amazonaws.com
+s3.dualstack.ap-east-1.amazonaws.com
+s3-accesspoint.dualstack.ap-east-1.amazonaws.com
+s3.ap-east-1.amazonaws.com
+s3-accesspoint.ap-east-1.amazonaws.com
+s3-object-lambda.ap-east-1.amazonaws.com
+s3-website.ap-east-1.amazonaws.com
 s3.dualstack.ap-northeast-1.amazonaws.com
+s3-accesspoint.dualstack.ap-northeast-1.amazonaws.com
+s3-website.dualstack.ap-northeast-1.amazonaws.com
+s3.ap-northeast-1.amazonaws.com
+s3-accesspoint.ap-northeast-1.amazonaws.com
+s3-object-lambda.ap-northeast-1.amazonaws.com
+s3-website.ap-northeast-1.amazonaws.com
 s3.dualstack.ap-northeast-2.amazonaws.com
+s3-accesspoint.dualstack.ap-northeast-2.amazonaws.com
+s3-website.dualstack.ap-northeast-2.amazonaws.com
 s3.ap-northeast-2.amazonaws.com
+s3-accesspoint.ap-northeast-2.amazonaws.com
+s3-object-lambda.ap-northeast-2.amazonaws.com
 s3-website.ap-northeast-2.amazonaws.com
+s3.dualstack.ap-northeast-3.amazonaws.com
+s3-accesspoint.dualstack.ap-northeast-3.amazonaws.com
+s3-website.dualstack.ap-northeast-3.amazonaws.com
+s3.ap-northeast-3.amazonaws.com
+s3-accesspoint.ap-northeast-3.amazonaws.com
+s3-object-lambda.ap-northeast-3.amazonaws.com
+s3-website.ap-northeast-3.amazonaws.com
 s3.dualstack.ap-south-1.amazonaws.com
+s3-accesspoint.dualstack.ap-south-1.amazonaws.com
+s3-website.dualstack.ap-south-1.amazonaws.com
 s3.ap-south-1.amazonaws.com
+s3-accesspoint.ap-south-1.amazonaws.com
+s3-object-lambda.ap-south-1.amazonaws.com
 s3-website.ap-south-1.amazonaws.com
+s3.dualstack.ap-south-2.amazonaws.com
+s3-accesspoint.dualstack.ap-south-2.amazonaws.com
+s3.ap-south-2.amazonaws.com
+s3-accesspoint.ap-south-2.amazonaws.com
+s3-object-lambda.ap-south-2.amazonaws.com
+s3-website.ap-south-2.amazonaws.com
 s3.dualstack.ap-southeast-1.amazonaws.com
+s3-accesspoint.dualstack.ap-southeast-1.amazonaws.com
+s3-website.dualstack.ap-southeast-1.amazonaws.com
+s3.ap-southeast-1.amazonaws.com
+s3-accesspoint.ap-southeast-1.amazonaws.com
+s3-object-lambda.ap-southeast-1.amazonaws.com
+s3-website.ap-southeast-1.amazonaws.com
 s3.dualstack.ap-southeast-2.amazonaws.com
+s3-accesspoint.dualstack.ap-southeast-2.amazonaws.com
+s3-website.dualstack.ap-southeast-2.amazonaws.com
+s3.ap-southeast-2.amazonaws.com
+s3-accesspoint.ap-southeast-2.amazonaws.com
+s3-object-lambda.ap-southeast-2.amazonaws.com
+s3-website.ap-southeast-2.amazonaws.com
+s3.dualstack.ap-southeast-3.amazonaws.com
+s3-accesspoint.dualstack.ap-southeast-3.amazonaws.com
+s3.ap-southeast-3.amazonaws.com
+s3-accesspoint.ap-southeast-3.amazonaws.com
+s3-object-lambda.ap-southeast-3.amazonaws.com
+s3-website.ap-southeast-3.amazonaws.com
+s3.dualstack.ap-southeast-4.amazonaws.com
+s3-accesspoint.dualstack.ap-southeast-4.amazonaws.com
+s3.ap-southeast-4.amazonaws.com
+s3-accesspoint.ap-southeast-4.amazonaws.com
+s3-object-lambda.ap-southeast-4.amazonaws.com
+s3-website.ap-southeast-4.amazonaws.com
 s3.dualstack.ca-central-1.amazonaws.com
+s3-accesspoint.dualstack.ca-central-1.amazonaws.com
+s3-accesspoint-fips.dualstack.ca-central-1.amazonaws.com
+s3-fips.dualstack.ca-central-1.amazonaws.com
+s3-website.dualstack.ca-central-1.amazonaws.com
 s3.ca-central-1.amazonaws.com
+s3-accesspoint.ca-central-1.amazonaws.com
+s3-accesspoint-fips.ca-central-1.amazonaws.com
+s3-fips.ca-central-1.amazonaws.com
+s3-object-lambda.ca-central-1.amazonaws.com
 s3-website.ca-central-1.amazonaws.com
 s3.dualstack.eu-central-1.amazonaws.com
+s3-accesspoint.dualstack.eu-central-1.amazonaws.com
+s3-website.dualstack.eu-central-1.amazonaws.com
 s3.eu-central-1.amazonaws.com
+s3-accesspoint.eu-central-1.amazonaws.com
+s3-object-lambda.eu-central-1.amazonaws.com
 s3-website.eu-central-1.amazonaws.com
+s3.dualstack.eu-central-2.amazonaws.com
+s3-accesspoint.dualstack.eu-central-2.amazonaws.com
+s3.eu-central-2.amazonaws.com
+s3-accesspoint.eu-central-2.amazonaws.com
+s3-object-lambda.eu-central-2.amazonaws.com
+s3-website.eu-central-2.amazonaws.com
+s3.dualstack.eu-north-1.amazonaws.com
+s3-accesspoint.dualstack.eu-north-1.amazonaws.com
+s3.eu-north-1.amazonaws.com
+s3-accesspoint.eu-north-1.amazonaws.com
+s3-object-lambda.eu-north-1.amazonaws.com
+s3-website.eu-north-1.amazonaws.com
+s3.dualstack.eu-south-1.amazonaws.com
+s3-accesspoint.dualstack.eu-south-1.amazonaws.com
+s3-website.dualstack.eu-south-1.amazonaws.com
+s3.eu-south-1.amazonaws.com
+s3-accesspoint.eu-south-1.amazonaws.com
+s3-object-lambda.eu-south-1.amazonaws.com
+s3-website.eu-south-1.amazonaws.com
+s3.dualstack.eu-south-2.amazonaws.com
+s3-accesspoint.dualstack.eu-south-2.amazonaws.com
+s3.eu-south-2.amazonaws.com
+s3-accesspoint.eu-south-2.amazonaws.com
+s3-object-lambda.eu-south-2.amazonaws.com
+s3-website.eu-south-2.amazonaws.com
 s3.dualstack.eu-west-1.amazonaws.com
+s3-accesspoint.dualstack.eu-west-1.amazonaws.com
+s3-website.dualstack.eu-west-1.amazonaws.com
+s3.eu-west-1.amazonaws.com
+s3-accesspoint.eu-west-1.amazonaws.com
+s3-deprecated.eu-west-1.amazonaws.com
+s3-object-lambda.eu-west-1.amazonaws.com
+s3-website.eu-west-1.amazonaws.com
 s3.dualstack.eu-west-2.amazonaws.com
+s3-accesspoint.dualstack.eu-west-2.amazonaws.com
 s3.eu-west-2.amazonaws.com
+s3-accesspoint.eu-west-2.amazonaws.com
+s3-object-lambda.eu-west-2.amazonaws.com
 s3-website.eu-west-2.amazonaws.com
 s3.dualstack.eu-west-3.amazonaws.com
+s3-accesspoint.dualstack.eu-west-3.amazonaws.com
+s3-website.dualstack.eu-west-3.amazonaws.com
 s3.eu-west-3.amazonaws.com
+s3-accesspoint.eu-west-3.amazonaws.com
+s3-object-lambda.eu-west-3.amazonaws.com
 s3-website.eu-west-3.amazonaws.com
+s3.dualstack.il-central-1.amazonaws.com
+s3-accesspoint.dualstack.il-central-1.amazonaws.com
+s3.il-central-1.amazonaws.com
+s3-accesspoint.il-central-1.amazonaws.com
+s3-object-lambda.il-central-1.amazonaws.com
+s3-website.il-central-1.amazonaws.com
+s3.dualstack.me-central-1.amazonaws.com
+s3-accesspoint.dualstack.me-central-1.amazonaws.com
+s3.me-central-1.amazonaws.com
+s3-accesspoint.me-central-1.amazonaws.com
+s3-object-lambda.me-central-1.amazonaws.com
+s3-website.me-central-1.amazonaws.com
+s3.dualstack.me-south-1.amazonaws.com
+s3-accesspoint.dualstack.me-south-1.amazonaws.com
+s3.me-south-1.amazonaws.com
+s3-accesspoint.me-south-1.amazonaws.com
+s3-object-lambda.me-south-1.amazonaws.com
+s3-website.me-south-1.amazonaws.com
 s3.amazonaws.com
+s3-1.amazonaws.com
+s3-ap-east-1.amazonaws.com
 s3-ap-northeast-1.amazonaws.com
 s3-ap-northeast-2.amazonaws.com
+s3-ap-northeast-3.amazonaws.com
 s3-ap-south-1.amazonaws.com
 s3-ap-southeast-1.amazonaws.com
 s3-ap-southeast-2.amazonaws.com
 s3-ca-central-1.amazonaws.com
 s3-eu-central-1.amazonaws.com
+s3-eu-north-1.amazonaws.com
 s3-eu-west-1.amazonaws.com
 s3-eu-west-2.amazonaws.com
 s3-eu-west-3.amazonaws.com
 s3-external-1.amazonaws.com
+s3-fips-us-gov-east-1.amazonaws.com
 s3-fips-us-gov-west-1.amazonaws.com
+mrap.accesspoint.s3-global.amazonaws.com
+s3-me-south-1.amazonaws.com
 s3-sa-east-1.amazonaws.com
 s3-us-east-2.amazonaws.com
+s3-us-gov-east-1.amazonaws.com
 s3-us-gov-west-1.amazonaws.com
 s3-us-west-1.amazonaws.com
 s3-us-west-2.amazonaws.com
@@ -10252,80 +11707,277 @@
 s3-website-eu-west-1.amazonaws.com
 s3-website-sa-east-1.amazonaws.com
 s3-website-us-east-1.amazonaws.com
+s3-website-us-gov-west-1.amazonaws.com
 s3-website-us-west-1.amazonaws.com
 s3-website-us-west-2.amazonaws.com
 s3.dualstack.sa-east-1.amazonaws.com
+s3-accesspoint.dualstack.sa-east-1.amazonaws.com
+s3-website.dualstack.sa-east-1.amazonaws.com
+s3.sa-east-1.amazonaws.com
+s3-accesspoint.sa-east-1.amazonaws.com
+s3-object-lambda.sa-east-1.amazonaws.com
+s3-website.sa-east-1.amazonaws.com
 s3.dualstack.us-east-1.amazonaws.com
+s3-accesspoint.dualstack.us-east-1.amazonaws.com
+s3-accesspoint-fips.dualstack.us-east-1.amazonaws.com
+s3-fips.dualstack.us-east-1.amazonaws.com
+s3-website.dualstack.us-east-1.amazonaws.com
+s3.us-east-1.amazonaws.com
+s3-accesspoint.us-east-1.amazonaws.com
+s3-accesspoint-fips.us-east-1.amazonaws.com
+s3-deprecated.us-east-1.amazonaws.com
+s3-fips.us-east-1.amazonaws.com
+s3-object-lambda.us-east-1.amazonaws.com
+s3-website.us-east-1.amazonaws.com
 s3.dualstack.us-east-2.amazonaws.com
+s3-accesspoint.dualstack.us-east-2.amazonaws.com
+s3-accesspoint-fips.dualstack.us-east-2.amazonaws.com
+s3-fips.dualstack.us-east-2.amazonaws.com
 s3.us-east-2.amazonaws.com
+s3-accesspoint.us-east-2.amazonaws.com
+s3-accesspoint-fips.us-east-2.amazonaws.com
+s3-deprecated.us-east-2.amazonaws.com
+s3-fips.us-east-2.amazonaws.com
+s3-object-lambda.us-east-2.amazonaws.com
 s3-website.us-east-2.amazonaws.com
+s3.dualstack.us-gov-east-1.amazonaws.com
+s3-accesspoint.dualstack.us-gov-east-1.amazonaws.com
+s3-accesspoint-fips.dualstack.us-gov-east-1.amazonaws.com
+s3-fips.dualstack.us-gov-east-1.amazonaws.com
+s3.us-gov-east-1.amazonaws.com
+s3-accesspoint.us-gov-east-1.amazonaws.com
+s3-accesspoint-fips.us-gov-east-1.amazonaws.com
+s3-fips.us-gov-east-1.amazonaws.com
+s3-object-lambda.us-gov-east-1.amazonaws.com
+s3-website.us-gov-east-1.amazonaws.com
+s3.dualstack.us-gov-west-1.amazonaws.com
+s3-accesspoint.dualstack.us-gov-west-1.amazonaws.com
+s3-accesspoint-fips.dualstack.us-gov-west-1.amazonaws.com
+s3-fips.dualstack.us-gov-west-1.amazonaws.com
+s3.us-gov-west-1.amazonaws.com
+s3-accesspoint.us-gov-west-1.amazonaws.com
+s3-accesspoint-fips.us-gov-west-1.amazonaws.com
+s3-fips.us-gov-west-1.amazonaws.com
+s3-object-lambda.us-gov-west-1.amazonaws.com
+s3-website.us-gov-west-1.amazonaws.com
+s3.dualstack.us-west-1.amazonaws.com
+s3-accesspoint.dualstack.us-west-1.amazonaws.com
+s3-accesspoint-fips.dualstack.us-west-1.amazonaws.com
+s3-fips.dualstack.us-west-1.amazonaws.com
+s3-website.dualstack.us-west-1.amazonaws.com
+s3.us-west-1.amazonaws.com
+s3-accesspoint.us-west-1.amazonaws.com
+s3-accesspoint-fips.us-west-1.amazonaws.com
+s3-fips.us-west-1.amazonaws.com
+s3-object-lambda.us-west-1.amazonaws.com
+s3-website.us-west-1.amazonaws.com
+s3.dualstack.us-west-2.amazonaws.com
+s3-accesspoint.dualstack.us-west-2.amazonaws.com
+s3-accesspoint-fips.dualstack.us-west-2.amazonaws.com
+s3-fips.dualstack.us-west-2.amazonaws.com
+s3-website.dualstack.us-west-2.amazonaws.com
+s3.us-west-2.amazonaws.com
+s3-accesspoint.us-west-2.amazonaws.com
+s3-accesspoint-fips.us-west-2.amazonaws.com
+s3-deprecated.us-west-2.amazonaws.com
+s3-fips.us-west-2.amazonaws.com
+s3-object-lambda.us-west-2.amazonaws.com
+s3-website.us-west-2.amazonaws.com
+
+// Amazon SageMaker Notebook Instances
+// Submitted by AWS Security <psl-maintainers@amazon.com>
+// Reference: fe8c9e94-5a22-486d-8750-991a3a9b13c6
+notebook.af-south-1.sagemaker.aws
+notebook.ap-east-1.sagemaker.aws
+notebook.ap-northeast-1.sagemaker.aws
+notebook.ap-northeast-2.sagemaker.aws
+notebook.ap-northeast-3.sagemaker.aws
+notebook.ap-south-1.sagemaker.aws
+notebook.ap-south-2.sagemaker.aws
+notebook.ap-southeast-1.sagemaker.aws
+notebook.ap-southeast-2.sagemaker.aws
+notebook.ap-southeast-3.sagemaker.aws
+notebook.ap-southeast-4.sagemaker.aws
+notebook.ca-central-1.sagemaker.aws
+notebook.eu-central-1.sagemaker.aws
+notebook.eu-central-2.sagemaker.aws
+notebook.eu-north-1.sagemaker.aws
+notebook.eu-south-1.sagemaker.aws
+notebook.eu-south-2.sagemaker.aws
+notebook.eu-west-1.sagemaker.aws
+notebook.eu-west-2.sagemaker.aws
+notebook.eu-west-3.sagemaker.aws
+notebook.il-central-1.sagemaker.aws
+notebook.me-central-1.sagemaker.aws
+notebook.me-south-1.sagemaker.aws
+notebook.sa-east-1.sagemaker.aws
+notebook.us-east-1.sagemaker.aws
+notebook-fips.us-east-1.sagemaker.aws
+notebook.us-east-2.sagemaker.aws
+notebook-fips.us-east-2.sagemaker.aws
+notebook.us-gov-east-1.sagemaker.aws
+notebook-fips.us-gov-east-1.sagemaker.aws
+notebook.us-gov-west-1.sagemaker.aws
+notebook-fips.us-gov-west-1.sagemaker.aws
+notebook.us-west-1.sagemaker.aws
+notebook.us-west-2.sagemaker.aws
+notebook-fips.us-west-2.sagemaker.aws
+notebook.cn-north-1.sagemaker.com.cn
+notebook.cn-northwest-1.sagemaker.com.cn
+
+// Amazon SageMaker Studio
+// Submitted by AWS Security <psl-maintainers@amazon.com>
+// Reference: 057ee397-6bf8-4f20-b807-d7bc145ac980
+studio.af-south-1.sagemaker.aws
+studio.ap-east-1.sagemaker.aws
+studio.ap-northeast-1.sagemaker.aws
+studio.ap-northeast-2.sagemaker.aws
+studio.ap-northeast-3.sagemaker.aws
+studio.ap-south-1.sagemaker.aws
+studio.ap-southeast-1.sagemaker.aws
+studio.ap-southeast-2.sagemaker.aws
+studio.ap-southeast-3.sagemaker.aws
+studio.ca-central-1.sagemaker.aws
+studio.eu-central-1.sagemaker.aws
+studio.eu-north-1.sagemaker.aws
+studio.eu-south-1.sagemaker.aws
+studio.eu-west-1.sagemaker.aws
+studio.eu-west-2.sagemaker.aws
+studio.eu-west-3.sagemaker.aws
+studio.il-central-1.sagemaker.aws
+studio.me-central-1.sagemaker.aws
+studio.me-south-1.sagemaker.aws
+studio.sa-east-1.sagemaker.aws
+studio.us-east-1.sagemaker.aws
+studio.us-east-2.sagemaker.aws
+studio.us-gov-east-1.sagemaker.aws
+studio-fips.us-gov-east-1.sagemaker.aws
+studio.us-gov-west-1.sagemaker.aws
+studio-fips.us-gov-west-1.sagemaker.aws
+studio.us-west-1.sagemaker.aws
+studio.us-west-2.sagemaker.aws
+studio.cn-north-1.sagemaker.com.cn
+studio.cn-northwest-1.sagemaker.com.cn
+
+// Analytics on AWS
+// Submitted by AWS Security <psl-maintainers@amazon.com>
+// Reference: 955f9f40-a495-4e73-ae85-67b77ac9cadd
+analytics-gateway.ap-northeast-1.amazonaws.com
+analytics-gateway.ap-northeast-2.amazonaws.com
+analytics-gateway.ap-south-1.amazonaws.com
+analytics-gateway.ap-southeast-1.amazonaws.com
+analytics-gateway.ap-southeast-2.amazonaws.com
+analytics-gateway.eu-central-1.amazonaws.com
+analytics-gateway.eu-west-1.amazonaws.com
+analytics-gateway.us-east-1.amazonaws.com
+analytics-gateway.us-east-2.amazonaws.com
+analytics-gateway.us-west-2.amazonaws.com
+
+// AWS Amplify
+// Submitted by AWS Security <psl-maintainers@amazon.com>
+// Reference: 5ecce854-c033-4fc4-a755-1a9916d9a9bb
+*.amplifyapp.com
+
+// AWS App Runner
+// Submitted by AWS Security <psl-maintainers@amazon.com>
+// Reference: 6828c008-ba5d-442f-ade5-48da4e7c2316
+*.awsapprunner.com
 
 // AWS Cloud9
 // Submitted by: AWS Security <psl-maintainers@amazon.com>
-// Reference: 2b6dfa9a-3a7f-4367-b2e7-0321e77c0d59
+// Reference: 05c44955-977c-4b57-938a-f2af92733f9f
+webview-assets.aws-cloud9.af-south-1.amazonaws.com
 vfs.cloud9.af-south-1.amazonaws.com
 webview-assets.cloud9.af-south-1.amazonaws.com
+webview-assets.aws-cloud9.ap-east-1.amazonaws.com
 vfs.cloud9.ap-east-1.amazonaws.com
 webview-assets.cloud9.ap-east-1.amazonaws.com
+webview-assets.aws-cloud9.ap-northeast-1.amazonaws.com
 vfs.cloud9.ap-northeast-1.amazonaws.com
 webview-assets.cloud9.ap-northeast-1.amazonaws.com
+webview-assets.aws-cloud9.ap-northeast-2.amazonaws.com
 vfs.cloud9.ap-northeast-2.amazonaws.com
 webview-assets.cloud9.ap-northeast-2.amazonaws.com
+webview-assets.aws-cloud9.ap-northeast-3.amazonaws.com
 vfs.cloud9.ap-northeast-3.amazonaws.com
 webview-assets.cloud9.ap-northeast-3.amazonaws.com
+webview-assets.aws-cloud9.ap-south-1.amazonaws.com
 vfs.cloud9.ap-south-1.amazonaws.com
 webview-assets.cloud9.ap-south-1.amazonaws.com
+webview-assets.aws-cloud9.ap-southeast-1.amazonaws.com
 vfs.cloud9.ap-southeast-1.amazonaws.com
 webview-assets.cloud9.ap-southeast-1.amazonaws.com
+webview-assets.aws-cloud9.ap-southeast-2.amazonaws.com
 vfs.cloud9.ap-southeast-2.amazonaws.com
 webview-assets.cloud9.ap-southeast-2.amazonaws.com
+webview-assets.aws-cloud9.ca-central-1.amazonaws.com
 vfs.cloud9.ca-central-1.amazonaws.com
 webview-assets.cloud9.ca-central-1.amazonaws.com
+webview-assets.aws-cloud9.eu-central-1.amazonaws.com
 vfs.cloud9.eu-central-1.amazonaws.com
 webview-assets.cloud9.eu-central-1.amazonaws.com
+webview-assets.aws-cloud9.eu-north-1.amazonaws.com
 vfs.cloud9.eu-north-1.amazonaws.com
 webview-assets.cloud9.eu-north-1.amazonaws.com
+webview-assets.aws-cloud9.eu-south-1.amazonaws.com
 vfs.cloud9.eu-south-1.amazonaws.com
 webview-assets.cloud9.eu-south-1.amazonaws.com
+webview-assets.aws-cloud9.eu-west-1.amazonaws.com
 vfs.cloud9.eu-west-1.amazonaws.com
 webview-assets.cloud9.eu-west-1.amazonaws.com
+webview-assets.aws-cloud9.eu-west-2.amazonaws.com
 vfs.cloud9.eu-west-2.amazonaws.com
 webview-assets.cloud9.eu-west-2.amazonaws.com
+webview-assets.aws-cloud9.eu-west-3.amazonaws.com
 vfs.cloud9.eu-west-3.amazonaws.com
 webview-assets.cloud9.eu-west-3.amazonaws.com
+webview-assets.aws-cloud9.me-south-1.amazonaws.com
 vfs.cloud9.me-south-1.amazonaws.com
 webview-assets.cloud9.me-south-1.amazonaws.com
+webview-assets.aws-cloud9.sa-east-1.amazonaws.com
 vfs.cloud9.sa-east-1.amazonaws.com
 webview-assets.cloud9.sa-east-1.amazonaws.com
+webview-assets.aws-cloud9.us-east-1.amazonaws.com
 vfs.cloud9.us-east-1.amazonaws.com
 webview-assets.cloud9.us-east-1.amazonaws.com
+webview-assets.aws-cloud9.us-east-2.amazonaws.com
 vfs.cloud9.us-east-2.amazonaws.com
 webview-assets.cloud9.us-east-2.amazonaws.com
+webview-assets.aws-cloud9.us-west-1.amazonaws.com
 vfs.cloud9.us-west-1.amazonaws.com
 webview-assets.cloud9.us-west-1.amazonaws.com
+webview-assets.aws-cloud9.us-west-2.amazonaws.com
 vfs.cloud9.us-west-2.amazonaws.com
 webview-assets.cloud9.us-west-2.amazonaws.com
 
 // AWS Elastic Beanstalk
-// Submitted by Luke Wells <psl-maintainers@amazon.com>
-// Reference: aa202394-43a0-4857-b245-8db04549137e
+// Submitted by AWS Security <psl-maintainers@amazon.com>
+// Reference: bb5a965c-dec3-4967-aa22-e306ad064797
 cn-north-1.eb.amazonaws.com.cn
 cn-northwest-1.eb.amazonaws.com.cn
 elasticbeanstalk.com
+af-south-1.elasticbeanstalk.com
+ap-east-1.elasticbeanstalk.com
 ap-northeast-1.elasticbeanstalk.com
 ap-northeast-2.elasticbeanstalk.com
 ap-northeast-3.elasticbeanstalk.com
 ap-south-1.elasticbeanstalk.com
 ap-southeast-1.elasticbeanstalk.com
 ap-southeast-2.elasticbeanstalk.com
+ap-southeast-3.elasticbeanstalk.com
 ca-central-1.elasticbeanstalk.com
 eu-central-1.elasticbeanstalk.com
+eu-north-1.elasticbeanstalk.com
+eu-south-1.elasticbeanstalk.com
 eu-west-1.elasticbeanstalk.com
 eu-west-2.elasticbeanstalk.com
 eu-west-3.elasticbeanstalk.com
+il-central-1.elasticbeanstalk.com
+me-south-1.elasticbeanstalk.com
 sa-east-1.elasticbeanstalk.com
 us-east-1.elasticbeanstalk.com
 us-east-2.elasticbeanstalk.com
+us-gov-east-1.elasticbeanstalk.com
 us-gov-west-1.elasticbeanstalk.com
 us-west-1.elasticbeanstalk.com
 us-west-2.elasticbeanstalk.com
@@ -11588,7 +13240,7 @@
 // Submitted by Daniel A. Maierhofer <vorstand@funkfeuer.at>
 wien.funkfeuer.at
 
-// Futureweb OG : http://www.futureweb.at
+// Futureweb GmbH : https://www.futureweb.at
 // Submitted by Andreas Schnederle-Wagner <schnederle@futureweb.at>
 *.futurecms.at
 *.ex.futurecms.at
@@ -12095,7 +13747,6 @@
 // Submitted by Ihor Kolodyuk <ik@jelastic.com>
 mel.cloudlets.com.au
 cloud.interhostsolutions.be
-users.scale.virtualcloud.com.br
 mycloud.by
 alp1.ae.flow.ch
 appengine.flow.ch
@@ -12119,9 +13770,7 @@
 de.trendhosting.cloud
 jele.club
 amscompute.com
-clicketcloud.com
 dopaas.com
-hidora.com
 paas.hosted-by-previder.com
 rag-cloud.hosteur.com
 rag-cloud-ch.hosteur.com
@@ -12436,6 +14085,10 @@
 1.azurestaticapps.net
 2.azurestaticapps.net
 3.azurestaticapps.net
+4.azurestaticapps.net
+5.azurestaticapps.net
+6.azurestaticapps.net
+7.azurestaticapps.net
 centralus.azurestaticapps.net
 eastasia.azurestaticapps.net
 eastus2.azurestaticapps.net
@@ -12516,6 +14169,9 @@
 us.ngrok.io
 ngrok.pizza
 
+// Nicolaus Copernicus University in Torun - MSK TORMAN (https://www.man.torun.pl)
+torun.pl
+
 // Nimbus Hosting Ltd. : https://www.nimbushosting.co.uk/
 // Submitted by Nicholas Ford <nick@nimbushosting.co.uk>
 nh-serv.co.uk
@@ -13230,6 +14886,20 @@
 alpha.bounty-full.com
 beta.bounty-full.com
 
+// Smallregistry by Promopixel SARL: https://www.smallregistry.net
+// Former AFNIC's SLDs 
+// Submitted by Jérôme Lipowicz <support@promopixel.com>
+aeroport.fr
+avocat.fr
+chambagri.fr
+chirurgiens-dentistes.fr
+experts-comptables.fr
+medecin.fr
+notaires.fr
+pharmacien.fr
+port.fr
+veterinaire.fr
+
 // Small Technology Foundation : https://small-tech.org
 // Submitted by Aral Balkan <aral@small-tech.org>
 small-web.org
@@ -13323,6 +14993,10 @@
 // Submitted by Jacob Lee <jacob@stdlib.com>
 api.stdlib.com
 
+// Storipress : https://storipress.com
+// Submitted by Benno Liu <benno@storipress.com>
+storipress.app
+
 // Storj Labs Inc. : https://storj.io/
 // Submitted by Philip Hutchins <hostmaster@storj.io>
 storj.farm
@@ -13690,6 +15364,8 @@
 // Submitted by Shahar Talmi <shahar@wix.com>
 wixsite.com
 editorx.io
+wixstudio.io
+wix.run
 
 // XenonCloud GbR: https://xenoncloud.net
 // Submitted by Julian Uphoff <publicsuffixlist@xenoncloud.net>
diff --git a/make/data/tzdata/VERSION b/make/data/tzdata/VERSION
index 66bd061..b138ed7 100644
--- a/make/data/tzdata/VERSION
+++ b/make/data/tzdata/VERSION
@@ -21,4 +21,4 @@
 # or visit www.oracle.com if you need additional information or have any
 # questions.
 #
-tzdata2023c
+tzdata2024a
diff --git a/make/data/tzdata/africa b/make/data/tzdata/africa
index a73405f..72b188f 100644
--- a/make/data/tzdata/africa
+++ b/make/data/tzdata/africa
@@ -53,6 +53,10 @@
 # Milne J. Civil time. Geogr J. 1899 Feb;13(2):173-94.
 # https://www.jstor.org/stable/1774359
 #
+# For the 1911/1912 establishment of standard time in French possessions, see:
+# Société Française de Physique, Recueil de constantes physiques (1913),
+# page 752, 18b.
+#
 # European-style abbreviations are commonly used along the Mediterranean.
 # For sub-Saharan Africa abbreviations were less standardized.
 # Previous editions of this database used WAT, CAT, SAT, and EAT
@@ -136,7 +140,7 @@
 
 # Chad
 # Zone	NAME		STDOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Ndjamena	1:00:12 -	LMT	1912        # N'Djamena
+Zone	Africa/Ndjamena	1:00:12 -	LMT	1912 Jan  1 # N'Djamena
 			1:00	-	WAT	1979 Oct 14
 			1:00	1:00	WAST	1980 Mar  8
 			1:00	-	WAT
@@ -162,7 +166,7 @@
 #	Inaccessible, Nightingale: uninhabited
 
 # Zone	NAME		STDOFF	RULES	FORMAT	[UNTIL]
-Zone	Africa/Abidjan	-0:16:08 -	LMT	1912
+Zone	Africa/Abidjan	-0:16:08 -	LMT	1912 Jan  1
 			 0:00	-	GMT
 
 ###############################################################################
@@ -308,13 +312,6 @@
 # reproduced by other (more accessible) sites[, e.g.,]...
 # http://elgornal.net/news/news.aspx?id=4699258
 
-# From Paul Eggert (2014-06-04):
-# Sarah El Deeb and Lee Keath of AP report that the Egyptian government says
-# the change is because of blackouts in Cairo, even though Ahram Online (cited
-# above) says DST had no affect on electricity consumption.  There is
-# no information about when DST will end this fall.  See:
-# http://abcnews.go.com/International/wireStory/el-sissi-pushes-egyptians-line-23614833
-
 # From Steffen Thorsen (2015-04-08):
 # Egypt will start DST on midnight after Thursday, April 30, 2015.
 # This is based on a law (no 35) from May 15, 2014 saying it starts the last
diff --git a/make/data/tzdata/antarctica b/make/data/tzdata/antarctica
index 3de5e72..fc7176c 100644
--- a/make/data/tzdata/antarctica
+++ b/make/data/tzdata/antarctica
@@ -103,6 +103,11 @@
 # - 2018 Oct  7 4:00 - 2019 Mar 17 3:00 - 2019 Oct  4 3:00 - 2020 Mar  8 3:00
 # and now - 2020 Oct  4 0:01
 
+# From Paul Eggert (2023-12-20):
+# Transitions from 2021 on are taken from:
+# https://www.timeanddate.com/time/zone/antarctica/casey
+# retrieved at various dates.
+
 # Zone	NAME		STDOFF	RULES	FORMAT	[UNTIL]
 Zone Antarctica/Casey	 0	-	-00	1969
 			 8:00	-	+08	2009 Oct 18  2:00
@@ -116,7 +121,12 @@
 			 8:00	-	+08	2019 Oct  4  3:00
 			11:00	-	+11	2020 Mar  8  3:00
 			 8:00	-	+08	2020 Oct  4  0:01
-			11:00	-	+11
+			11:00	-	+11	2021 Mar 14  0:00
+			 8:00	-	+08	2021 Oct  3  0:01
+			11:00	-	+11	2022 Mar 13  0:00
+			 8:00	-	+08	2022 Oct  2  0:01
+			11:00	-	+11	2023 Mar  9  3:00
+			 8:00	-	+08
 Zone Antarctica/Davis	0	-	-00	1957 Jan 13
 			7:00	-	+07	1964 Nov
 			0	-	-00	1969 Feb
@@ -263,7 +273,50 @@
 #	year-round from 1960/61 to 1992
 
 # Vostok, since 1957-12-16, temporarily closed 1994-02/1994-11
-# See Asia/Urumqi.
+# From Craig Mundell (1994-12-15):
+# http://quest.arc.nasa.gov/antarctica/QA/computers/Directions,Time,ZIP
+# Vostok, which is one of the Russian stations, is set on the same
+# time as Moscow, Russia.
+#
+# From Lee Hotz (2001-03-08):
+# I queried the folks at Columbia who spent the summer at Vostok and this is
+# what they had to say about time there:
+# "in the US Camp (East Camp) we have been on New Zealand (McMurdo)
+# time, which is 12 hours ahead of GMT. The Russian Station Vostok was
+# 6 hours behind that (although only 2 miles away, i.e. 6 hours ahead
+# of GMT). This is a time zone I think two hours east of Moscow. The
+# natural time zone is in between the two: 8 hours ahead of GMT."
+#
+# From Paul Eggert (2001-05-04):
+# This seems to be hopelessly confusing, so I asked Lee Hotz about it
+# in person.  He said that some Antarctic locations set their local
+# time so that noon is the warmest part of the day, and that this
+# changes during the year and does not necessarily correspond to mean
+# solar noon.  So the Vostok time might have been whatever the clocks
+# happened to be during their visit.  So we still don't really know what time
+# it is at Vostok.
+#
+# From Zakhary V. Akulov (2023-12-17 22:00:48 +0700):
+# ... from December, 18, 2023 00:00 by my decision the local time of
+# the Antarctic research base Vostok will correspond to UTC+5.
+# (2023-12-19): We constantly interact with Progress base, with company who
+# builds new wintering station, with sledge convoys, with aviation - they all
+# use UTC+5. Besides, difference between Moscow time is just 2 hours now, not 4.
+# (2023-12-19, in response to the question "Has local time at Vostok
+# been UTC+6 ever since 1957, or has it changed before?"): No. At least
+# since my antarctic career start, 10 years ago, Vostok base has UTC+7.
+# (In response to a 2023-12-18 question "from 02:00 to 00:00 today"): This.
+#
+# From Paul Eggert (2023-12-18):
+# For lack of better info, guess Vostok was at +07 from founding through today,
+# except when closed.
+
+# Zone	NAME		STDOFF	RULES	FORMAT	[UNTIL]
+Zone Antarctica/Vostok	0	-	-00	1957 Dec 16
+			7:00	-	+07	1994 Feb
+			0	-	-00	1994 Nov
+			7:00	-	+07	2023 Dec 18  2:00
+			5:00	-	+05
 
 # S Africa - year-round bases
 # Marion Island, -4653+03752
diff --git a/make/data/tzdata/asia b/make/data/tzdata/asia
index 6a048c3..3a54291 100644
--- a/make/data/tzdata/asia
+++ b/make/data/tzdata/asia
@@ -678,7 +678,6 @@
 			8:00	PRC	C%sT
 # Xinjiang time, used by many in western China; represented by Ürümqi / Ürümchi
 # / Wulumuqi.  (Please use Asia/Shanghai if you prefer Beijing time.)
-# Vostok base in Antarctica matches this since 1970.
 Zone	Asia/Urumqi	5:50:20	-	LMT	1928
 			6:00	-	+06
 
@@ -2481,18 +2480,33 @@
 # effective December 21st, 2018....
 # http://adilet.zan.kz/rus/docs/P1800000817 (russian language).
 
+# From Zhanbolat Raimbekov (2024-01-19):
+# Kazakhstan (all parts) switching to UTC+5 on March 1, 2024
+# https://www.gov.kz/memleket/entities/mti/press/news/details/688998?lang=ru
+# [in Russian]
+# (2024-01-20): https://primeminister.kz/ru/decisions/19012024-20
+#
+# From Alexander Krivenyshev (2024-01-19):
+# According to a different news and the official web site for the Ministry of
+# Trade and Integration of the Republic of Kazakhstan:
+# https://en.inform.kz/news/kazakhstan-to-switch-to-single-hour-zone-mar-1-54ad0b/
+
 # Zone	NAME		STDOFF	RULES	FORMAT	[UNTIL]
 #
 # Almaty (formerly Alma-Ata), representing most locations in Kazakhstan
-# This includes KZ-AKM, KZ-ALA, KZ-ALM, KZ-AST, KZ-BAY, KZ-VOS, KZ-ZHA,
-# KZ-KAR, KZ-SEV, KZ-PAV, and KZ-YUZ.
+# This includes Abai/Abay (ISO 3166-2 code KZ-10), Aqmola/Akmola (KZ-11),
+# Almaty (KZ-19), Almaty city (KZ-75), Astana city (KZ-71),
+# East Kazkhstan (KZ-63), Jambyl/Zhambyl (KZ-31), Jetisu/Zhetysu (KZ-33),
+# Karaganda (KZ-35), North Kazakhstan (KZ-59), Pavlodar (KZ-55),
+# Shyumkent city (KZ-79), Turkistan (KZ-61), and Ulytau (KZ-62).
 Zone	Asia/Almaty	5:07:48 -	LMT	1924 May  2 # or Alma-Ata
 			5:00	-	+05	1930 Jun 21
 			6:00 RussiaAsia +06/+07	1991 Mar 31  2:00s
 			5:00 RussiaAsia	+05/+06	1992 Jan 19  2:00s
 			6:00 RussiaAsia	+06/+07	2004 Oct 31  2:00s
-			6:00	-	+06
-# Qyzylorda (aka Kyzylorda, Kizilorda, Kzyl-Orda, etc.) (KZ-KZY)
+			6:00	-	+06	2024 Mar  1  0:00
+			5:00	-	+05
+# Qyzylorda (aka Kyzylorda, Kizilorda, Kzyl-Orda, etc.) (KZ-43)
 Zone	Asia/Qyzylorda	4:21:52 -	LMT	1924 May  2
 			4:00	-	+04	1930 Jun 21
 			5:00	-	+05	1981 Apr  1
@@ -2505,8 +2519,7 @@
 			5:00 RussiaAsia	+05/+06	2004 Oct 31  2:00s
 			6:00	-	+06	2018 Dec 21  0:00
 			5:00	-	+05
-#
-# Qostanay (aka Kostanay, Kustanay) (KZ-KUS)
+# Qostanay (aka Kostanay, Kustanay) (KZ-39)
 # The 1991/2 rules are unclear partly because of the 1997 Turgai
 # reorganization.
 Zone	Asia/Qostanay	4:14:28 -	LMT	1924 May  2
@@ -2517,9 +2530,9 @@
 			5:00 RussiaAsia	+05/+06	1991 Mar 31  2:00s
 			4:00 RussiaAsia	+04/+05	1992 Jan 19  2:00s
 			5:00 RussiaAsia	+05/+06	2004 Oct 31  2:00s
-			6:00	-	+06
-
-# Aqtöbe (aka Aktobe, formerly Aktyubinsk) (KZ-AKT)
+			6:00	-	+06	2024 Mar  1  0:00
+			5:00	-	+05
+# Aqtöbe (aka Aktobe, formerly Aktyubinsk) (KZ-15)
 Zone	Asia/Aqtobe	3:48:40	-	LMT	1924 May  2
 			4:00	-	+04	1930 Jun 21
 			5:00	-	+05	1981 Apr  1
@@ -2529,7 +2542,7 @@
 			4:00 RussiaAsia	+04/+05	1992 Jan 19  2:00s
 			5:00 RussiaAsia	+05/+06	2004 Oct 31  2:00s
 			5:00	-	+05
-# Mangghystaū (KZ-MAN)
+# Mangghystaū (KZ-47)
 # Aqtau was not founded until 1963, but it represents an inhabited region,
 # so include timestamps before 1963.
 Zone	Asia/Aqtau	3:21:04	-	LMT	1924 May  2
@@ -2541,7 +2554,7 @@
 			5:00 RussiaAsia	+05/+06	1994 Sep 25  2:00s
 			4:00 RussiaAsia	+04/+05	2004 Oct 31  2:00s
 			5:00	-	+05
-# Atyraū (KZ-ATY) is like Mangghystaū except it switched from
+# Atyraū (KZ-23) is like Mangghystaū except it switched from
 # +04/+05 to +05/+06 in spring 1999, not fall 1994.
 Zone	Asia/Atyrau	3:27:44	-	LMT	1924 May  2
 			3:00	-	+03	1930 Jun 21
@@ -2552,7 +2565,7 @@
 			5:00 RussiaAsia	+05/+06	1999 Mar 28  2:00s
 			4:00 RussiaAsia	+04/+05	2004 Oct 31  2:00s
 			5:00	-	+05
-# West Kazakhstan (KZ-ZAP)
+# West Kazakhstan (KZ-27)
 # From Paul Eggert (2016-03-18):
 # The 1989 transition is from USSR act No. 227 (1989-03-14).
 Zone	Asia/Oral	3:25:24	-	LMT	1924 May  2 # or Ural'sk
@@ -3450,20 +3463,30 @@
 # From Heba Hamad (2023-03-22):
 # ... summer time will begin in Palestine from Saturday 04-29-2023,
 # 02:00 AM by 60 minutes forward.
+# From Heba Hemad (2023-10-09):
+# ... winter time will begin in Palestine from Saturday 10-28-2023,
+# 02:00 AM by 60 minutes back.
 #
-# From Paul Eggert (2023-03-22):
+# From Heba Hamad (2024-01-25):
+# the summer time for the years 2024,2025 will begin in Palestine
+# from Saturday at 02:00 AM by 60 minutes forward as shown below:
+# year date
+# 2024 2024-04-20
+# 2025 2025-04-12
+#
+# From Paul Eggert (2024-01-25):
 # For now, guess that spring and fall transitions will normally
 # continue to use 2022's rules, that during DST Palestine will switch
 # to standard time at 02:00 the last Saturday before Ramadan and back
-# to DST at 02:00 the first Saturday after Ramadan, and that
+# to DST at 02:00 the second Saturday after Ramadan, and that
 # if the normal spring-forward or fall-back transition occurs during
 # Ramadan the former is delayed and the latter advanced.
 # To implement this, I predicted Ramadan-oriented transition dates for
-# 2023 through 2086 by running the following program under GNU Emacs 28.2,
+# 2026 through 2086 by running the following program under GNU Emacs 29.2,
 # with the results integrated by hand into the table below.
 # Predictions after 2086 are approximated without Ramadan.
 #
-# (let ((islamic-year 1444))
+# (let ((islamic-year 1447))
 #   (require 'cal-islam)
 #   (while (< islamic-year 1510)
 #     (let ((a (calendar-islamic-to-absolute (list 9 1 islamic-year)))
@@ -3472,6 +3495,7 @@
 #       (while (/= saturday (mod (setq a (1- a)) 7)))
 #       (while (/= saturday (mod b 7))
 #         (setq b (1+ b)))
+#       (setq b (+ 7 b))
 #       (setq a (calendar-gregorian-from-absolute a))
 #       (setq b (calendar-gregorian-from-absolute b))
 #       (insert
@@ -3522,84 +3546,84 @@
 Rule Palestine	2022	only	-	Mar	27	0:00	1:00	S
 Rule Palestine	2022	2035	-	Oct	Sat<=30	2:00	0	-
 Rule Palestine	2023	only	-	Apr	29	2:00	1:00	S
-Rule Palestine	2024	only	-	Apr	13	2:00	1:00	S
-Rule Palestine	2025	only	-	Apr	 5	2:00	1:00	S
+Rule Palestine	2024	only	-	Apr	20	2:00	1:00	S
+Rule Palestine	2025	only	-	Apr	12	2:00	1:00	S
 Rule Palestine	2026	2054	-	Mar	Sat<=30	2:00	1:00	S
 Rule Palestine	2036	only	-	Oct	18	2:00	0	-
 Rule Palestine	2037	only	-	Oct	10	2:00	0	-
 Rule Palestine	2038	only	-	Sep	25	2:00	0	-
 Rule Palestine	2039	only	-	Sep	17	2:00	0	-
-Rule Palestine	2039	only	-	Oct	22	2:00	1:00	S
-Rule Palestine	2039	2067	-	Oct	Sat<=30	2:00	0	-
 Rule Palestine	2040	only	-	Sep	 1	2:00	0	-
-Rule Palestine	2040	only	-	Oct	13	2:00	1:00	S
+Rule Palestine	2040	only	-	Oct	20	2:00	1:00	S
+Rule Palestine	2040	2067	-	Oct	Sat<=30	2:00	0	-
 Rule Palestine	2041	only	-	Aug	24	2:00	0	-
-Rule Palestine	2041	only	-	Sep	28	2:00	1:00	S
+Rule Palestine	2041	only	-	Oct	 5	2:00	1:00	S
 Rule Palestine	2042	only	-	Aug	16	2:00	0	-
-Rule Palestine	2042	only	-	Sep	20	2:00	1:00	S
+Rule Palestine	2042	only	-	Sep	27	2:00	1:00	S
 Rule Palestine	2043	only	-	Aug	 1	2:00	0	-
-Rule Palestine	2043	only	-	Sep	12	2:00	1:00	S
+Rule Palestine	2043	only	-	Sep	19	2:00	1:00	S
 Rule Palestine	2044	only	-	Jul	23	2:00	0	-
-Rule Palestine	2044	only	-	Aug	27	2:00	1:00	S
+Rule Palestine	2044	only	-	Sep	 3	2:00	1:00	S
 Rule Palestine	2045	only	-	Jul	15	2:00	0	-
-Rule Palestine	2045	only	-	Aug	19	2:00	1:00	S
+Rule Palestine	2045	only	-	Aug	26	2:00	1:00	S
 Rule Palestine	2046	only	-	Jun	30	2:00	0	-
-Rule Palestine	2046	only	-	Aug	11	2:00	1:00	S
+Rule Palestine	2046	only	-	Aug	18	2:00	1:00	S
 Rule Palestine	2047	only	-	Jun	22	2:00	0	-
-Rule Palestine	2047	only	-	Jul	27	2:00	1:00	S
+Rule Palestine	2047	only	-	Aug	 3	2:00	1:00	S
 Rule Palestine	2048	only	-	Jun	 6	2:00	0	-
-Rule Palestine	2048	only	-	Jul	18	2:00	1:00	S
+Rule Palestine	2048	only	-	Jul	25	2:00	1:00	S
 Rule Palestine	2049	only	-	May	29	2:00	0	-
-Rule Palestine	2049	only	-	Jul	 3	2:00	1:00	S
+Rule Palestine	2049	only	-	Jul	10	2:00	1:00	S
 Rule Palestine	2050	only	-	May	21	2:00	0	-
-Rule Palestine	2050	only	-	Jun	25	2:00	1:00	S
+Rule Palestine	2050	only	-	Jul	 2	2:00	1:00	S
 Rule Palestine	2051	only	-	May	 6	2:00	0	-
-Rule Palestine	2051	only	-	Jun	17	2:00	1:00	S
+Rule Palestine	2051	only	-	Jun	24	2:00	1:00	S
 Rule Palestine	2052	only	-	Apr	27	2:00	0	-
-Rule Palestine	2052	only	-	Jun	 1	2:00	1:00	S
+Rule Palestine	2052	only	-	Jun	 8	2:00	1:00	S
 Rule Palestine	2053	only	-	Apr	12	2:00	0	-
-Rule Palestine	2053	only	-	May	24	2:00	1:00	S
+Rule Palestine	2053	only	-	May	31	2:00	1:00	S
 Rule Palestine	2054	only	-	Apr	 4	2:00	0	-
-Rule Palestine	2054	only	-	May	16	2:00	1:00	S
-Rule Palestine	2055	only	-	May	 1	2:00	1:00	S
-Rule Palestine	2056	only	-	Apr	22	2:00	1:00	S
-Rule Palestine	2057	only	-	Apr	 7	2:00	1:00	S
-Rule Palestine	2058	max	-	Mar	Sat<=30	2:00	1:00	S
+Rule Palestine	2054	only	-	May	23	2:00	1:00	S
+Rule Palestine	2055	only	-	May	 8	2:00	1:00	S
+Rule Palestine	2056	only	-	Apr	29	2:00	1:00	S
+Rule Palestine	2057	only	-	Apr	14	2:00	1:00	S
+Rule Palestine	2058	only	-	Apr	 6	2:00	1:00	S
+Rule Palestine	2059	max	-	Mar	Sat<=30	2:00	1:00	S
 Rule Palestine	2068	only	-	Oct	20	2:00	0	-
 Rule Palestine	2069	only	-	Oct	12	2:00	0	-
 Rule Palestine	2070	only	-	Oct	 4	2:00	0	-
 Rule Palestine	2071	only	-	Sep	19	2:00	0	-
 Rule Palestine	2072	only	-	Sep	10	2:00	0	-
-Rule Palestine	2072	only	-	Oct	15	2:00	1:00	S
+Rule Palestine	2072	only	-	Oct	22	2:00	1:00	S
+Rule Palestine	2072	max	-	Oct	Sat<=30	2:00	0	-
 Rule Palestine	2073	only	-	Sep	 2	2:00	0	-
-Rule Palestine	2073	only	-	Oct	 7	2:00	1:00	S
+Rule Palestine	2073	only	-	Oct	14	2:00	1:00	S
 Rule Palestine	2074	only	-	Aug	18	2:00	0	-
-Rule Palestine	2074	only	-	Sep	29	2:00	1:00	S
+Rule Palestine	2074	only	-	Oct	 6	2:00	1:00	S
 Rule Palestine	2075	only	-	Aug	10	2:00	0	-
-Rule Palestine	2075	only	-	Sep	14	2:00	1:00	S
-Rule Palestine	2075	max	-	Oct	Sat<=30	2:00	0	-
+Rule Palestine	2075	only	-	Sep	21	2:00	1:00	S
 Rule Palestine	2076	only	-	Jul	25	2:00	0	-
-Rule Palestine	2076	only	-	Sep	 5	2:00	1:00	S
+Rule Palestine	2076	only	-	Sep	12	2:00	1:00	S
 Rule Palestine	2077	only	-	Jul	17	2:00	0	-
-Rule Palestine	2077	only	-	Aug	28	2:00	1:00	S
+Rule Palestine	2077	only	-	Sep	 4	2:00	1:00	S
 Rule Palestine	2078	only	-	Jul	 9	2:00	0	-
-Rule Palestine	2078	only	-	Aug	13	2:00	1:00	S
+Rule Palestine	2078	only	-	Aug	20	2:00	1:00	S
 Rule Palestine	2079	only	-	Jun	24	2:00	0	-
-Rule Palestine	2079	only	-	Aug	 5	2:00	1:00	S
+Rule Palestine	2079	only	-	Aug	12	2:00	1:00	S
 Rule Palestine	2080	only	-	Jun	15	2:00	0	-
-Rule Palestine	2080	only	-	Jul	20	2:00	1:00	S
+Rule Palestine	2080	only	-	Jul	27	2:00	1:00	S
 Rule Palestine	2081	only	-	Jun	 7	2:00	0	-
-Rule Palestine	2081	only	-	Jul	12	2:00	1:00	S
+Rule Palestine	2081	only	-	Jul	19	2:00	1:00	S
 Rule Palestine	2082	only	-	May	23	2:00	0	-
-Rule Palestine	2082	only	-	Jul	 4	2:00	1:00	S
+Rule Palestine	2082	only	-	Jul	11	2:00	1:00	S
 Rule Palestine	2083	only	-	May	15	2:00	0	-
-Rule Palestine	2083	only	-	Jun	19	2:00	1:00	S
+Rule Palestine	2083	only	-	Jun	26	2:00	1:00	S
 Rule Palestine	2084	only	-	Apr	29	2:00	0	-
-Rule Palestine	2084	only	-	Jun	10	2:00	1:00	S
+Rule Palestine	2084	only	-	Jun	17	2:00	1:00	S
 Rule Palestine	2085	only	-	Apr	21	2:00	0	-
-Rule Palestine	2085	only	-	Jun	 2	2:00	1:00	S
+Rule Palestine	2085	only	-	Jun	 9	2:00	1:00	S
 Rule Palestine	2086	only	-	Apr	13	2:00	0	-
-Rule Palestine	2086	only	-	May	18	2:00	1:00	S
+Rule Palestine	2086	only	-	May	25	2:00	1:00	S
 
 # Zone	NAME		STDOFF	RULES	FORMAT	[UNTIL]
 Zone	Asia/Gaza	2:17:52	-	LMT	1900 Oct
@@ -3627,7 +3651,7 @@
 
 # Philippines
 
-# From Paul Eggert (2018-11-18):
+# From Paul Eggert (2024-01-21):
 # The Spanish initially used American (west-of-Greenwich) time.
 # It is unknown what time Manila kept when the British occupied it from
 # 1762-10-06 through 1764-04; for now assume it kept American time.
@@ -3635,7 +3659,7 @@
 # Philippines, issued a proclamation announcing that 1844-12-30 was to
 # be immediately followed by 1845-01-01; see R.H. van Gent's
 # History of the International Date Line
-# https://www.staff.science.uu.nl/~gent0113/idl/idl_philippines.htm
+# https://webspace.science.uu.nl/~gent0113/idl/idl_philippines.htm
 # The rest of the data entries are from Shanks & Pottenger.
 
 # From Jesper Nørgaard Welen (2006-04-26):
@@ -4062,7 +4086,8 @@
 # The English-language name of Vietnam's most populous city is "Ho Chi Minh
 # City"; use Ho_Chi_Minh below to avoid a name of more than 14 characters.
 
-# From Paul Eggert (2022-07-27) after a 2014 heads-up from Trần Ngọc Quân:
+# From Paul Eggert (2024-01-14) after a 2014 heads-up from Trần Ngọc Quân
+# and a 2024-01-14 heads-up from Đoàn Trần Công Danh:
 # Trần Tiến Bình's authoritative book "Lịch Việt Nam: thế kỷ XX-XXI (1901-2100)"
 # (Nhà xuất bản Văn Hoá - Thông Tin, Hanoi, 2005), pp 49-50,
 # is quoted verbatim in:
@@ -4092,14 +4117,35 @@
 #
 # Trần cites the following sources; it's unclear which supplied the info above.
 #
-# Hoàng Xuân Hãn: "Lịch và lịch Việt Nam". Tập san Khoa học Xã hội,
-# No. 9, Paris, February 1982.
+#   Hoàng Xuân Hãn: "Lịch và lịch Việt Nam". Tập san Khoa học Xã hội,
+#   No. 9, Paris, February 1982.
 #
-# Lê Thành Lân: "Lịch và niên biểu lịch sử hai mươi thế kỷ (0001-2010)",
-# NXB Thống kê, Hanoi, 2000.
+#   Lê Thành Lân: "Lịch và niên biểu lịch sử hai mươi thế kỷ (0001-2010)",
+#   NXB Thống kê, Hanoi, 2000.
 #
-# Lê Thành Lân: "Lịch hai thế kỷ (1802-2010) và các lịch vĩnh cửu",
-# NXB Thuận Hoá, Huế, 1995.
+#   Lê Thành Lân: "Lịch hai thế kỷ (1802-2010) và các lịch vĩnh cửu",
+#   NXB Thuận Hoá, Huế, 1995.
+#
+# Here is the decision for the September 1945 transition:
+# Võ Nguyên Giáp, Việt Nam Dân Quốc Công Báo, No. 1 (1945-09-29), page 13
+# http://baochi.nlv.gov.vn/baochi/cgi-bin/baochi?a=d&d=JwvzO19450929.2.5&dliv=none
+# It says that on 1945-09-01 at 24:00, Vietnam moved back two hours, to +07.
+# It also mentions a 1945-03-29 decree (by a Japanese Goveror-General)
+# to set the time zone to +09, but does not say whether that decree
+# merely legalized an earlier change to +09.
+#
+# July 1955 transition:
+# Ngô Đình Diệm, Công Báo Việt Nam, No. 92 (1955-07-02), page 1780-1781
+# Ordinance (Dụ) No. 46 (1955-06-25)
+# http://ddsnext.crl.edu/titles/32341#?c=0&m=29&s=0&cv=4&r=0&xywh=-89%2C342%2C1724%2C1216
+# It says that on 1955-07-01 at 01:00, South Vietnam moved back 1 hour (to +07).
+#
+# December 1959 transition:
+# Ngô Đình Diệm, Công Báo Việt Nam Cộng Hòa, 1960 part 1 (1960-01-02), page 62
+# Decree (Sắc lệnh) No. 362-TTP (1959-12-30)
+# http://ddsnext.crl.edu/titles/32341#?c=0&m=138&s=0&cv=793&r=0&xywh=-54%2C1504%2C1705%2C1202
+# It says that on 1959-12-31 at 23:00, South Vietnam moved forward 1 hour (to +08).
+
 
 # Zone	NAME		STDOFF	RULES	FORMAT	[UNTIL]
 		#STDOFF	7:06:30.13
@@ -4107,9 +4153,9 @@
 			7:06:30	-	PLMT	1911 May  1 # Phù Liễn MT
 			7:00	-	+07	1942 Dec 31 23:00
 			8:00	-	+08	1945 Mar 14 23:00
-			9:00	-	+09	1945 Sep  2
+			9:00	-	+09	1945 Sep  1 24:00
 			7:00	-	+07	1947 Apr  1
-			8:00	-	+08	1955 Jul  1
+			8:00	-	+08	1955 Jul  1 01:00
 			7:00	-	+07	1959 Dec 31 23:00
 			8:00	-	+08	1975 Jun 13
 			7:00	-	+07
diff --git a/make/data/tzdata/australasia b/make/data/tzdata/australasia
index 893d705..624735b 100644
--- a/make/data/tzdata/australasia
+++ b/make/data/tzdata/australasia
@@ -414,8 +414,14 @@
 # Please note that there will not be any daylight savings time change
 # in Fiji for 2022-2023....
 # https://www.facebook.com/FijianGovernment/posts/pfbid0mmWVTYmTibn66ybpFda75pDcf34SSpoSaskJW5gXwaKo5Sgc7273Q4fXWc6kQV6Hl
+
+# From Almaz Mingaleev (2023-10-06):
+# Cabinet approved the suspension of Daylight Saving and appropriate
+# legislative changes will be considered including the repeal of the
+# Daylight Saving Act 1998
+# https://www.fiji.gov.fj/Media-Centre/Speeches/English/CABINET-DECISIONS-3-OCTOBER-2023
 #
-# From Paul Eggert (2022-10-27):
+# From Paul Eggert (2023-10-06):
 # For now, assume DST is suspended indefinitely.
 
 # Rule	NAME	FROM	TO	-	IN	ON	AT	SAVE	LETTER/S
@@ -437,11 +443,11 @@
 
 # French Polynesia
 # Zone	NAME		STDOFF	RULES	FORMAT	[UNTIL]
-Zone	Pacific/Gambier	 -8:59:48 -	LMT	1912 Oct # Rikitea
+Zone	Pacific/Gambier	 -8:59:48 -	LMT	1912 Oct  1 # Rikitea
 			 -9:00	-	-09
-Zone	Pacific/Marquesas -9:18:00 -	LMT	1912 Oct
+Zone	Pacific/Marquesas -9:18:00 -	LMT	1912 Oct  1
 			 -9:30	-	-0930
-Zone	Pacific/Tahiti	 -9:58:16 -	LMT	1912 Oct # Papeete
+Zone	Pacific/Tahiti	 -9:58:16 -	LMT	1912 Oct  1 # Papeete
 			-10:00	-	-10
 # Clipperton (near North America) is administered from French Polynesia;
 # it is uninhabited.
@@ -819,7 +825,7 @@
 # Solomon Is
 # excludes Bougainville, for which see Papua New Guinea
 # Zone	NAME		STDOFF	RULES	FORMAT	[UNTIL]
-Zone Pacific/Guadalcanal 10:39:48 -	LMT	1912 Oct # Honiara
+Zone Pacific/Guadalcanal 10:39:48 -	LMT	1912 Oct  1 # Honiara
 			11:00	-	+11
 
 # Tokelau
@@ -980,6 +986,10 @@
 # Milne J. Civil time. Geogr J. 1899 Feb;13(2):173-94.
 # https://www.jstor.org/stable/1774359
 #
+# For the 1911/1912 establishment of standard time in French possessions, see:
+# Société Française de Physique, Recueil de constantes physiques (1913),
+# page 752, 18b.
+#
 # A reliable and entertaining source about time zones is
 # Derek Howse, Greenwich time and longitude, Philip Wilson Publishers (1997).
 #
@@ -2056,7 +2066,7 @@
 # ordaining - by a masterpiece of diplomatic flattery - that
 # the Fourth of July should be celebrated twice in that year."
 # This happened in 1892, according to the Evening News (Sydney) of 1892-07-20.
-# https://www.staff.science.uu.nl/~gent0113/idl/idl.htm
+# https://webspace.science.uu.nl/~gent0113/idl/idl_alaska_samoa.htm
 
 # Although Shanks & Pottenger says they both switched to UT -11:30
 # in 1911, and to -11 in 1950. many earlier sources give -11
diff --git a/make/data/tzdata/backward b/make/data/tzdata/backward
index c0746d6..7ddc6cc 100644
--- a/make/data/tzdata/backward
+++ b/make/data/tzdata/backward
@@ -228,7 +228,6 @@
 Link	Pacific/Port_Moresby	Antarctica/DumontDUrville
 Link	Pacific/Auckland	Antarctica/McMurdo
 Link	Asia/Riyadh		Antarctica/Syowa
-Link	Asia/Urumqi		Antarctica/Vostok
 Link	Europe/Berlin		Arctic/Longyearbyen
 Link	Asia/Riyadh		Asia/Aden
 Link	Asia/Qatar		Asia/Bahrain
diff --git a/make/data/tzdata/etcetera b/make/data/tzdata/etcetera
index 8ae294f..2714771 100644
--- a/make/data/tzdata/etcetera
+++ b/make/data/tzdata/etcetera
@@ -28,7 +28,7 @@
 
 # These entries are for uses not otherwise covered by the tz database.
 # Their main practical use is for platforms like Android that lack
-# support for POSIX-style TZ strings.  On such platforms these entries
+# support for POSIX.1-2017-style TZ strings.  On such platforms these entries
 # can be useful if the timezone database is wrong or if a ship or
 # aircraft at sea is not in a timezone.
 
diff --git a/make/data/tzdata/europe b/make/data/tzdata/europe
index 446d2e1..18865f3 100644
--- a/make/data/tzdata/europe
+++ b/make/data/tzdata/europe
@@ -1013,9 +1013,34 @@
 # Czech Republic (Czechia)
 # Slovakia
 #
-# From Paul Eggert (2018-04-15):
-# The source for Czech data is: Kdy začíná a končí letní čas. 2018-04-15.
+# From Ivan Benovic (2024-01-30):
+# https://www.slov-lex.sk/pravne-predpisy/SK/ZZ/1946/54/
+# (This is an official link to the Czechoslovak Summer Time Act of
+# March 8, 1946 that authorizes the Czechoslovak government to set the
+# exact dates of change to summer time and back to Central European Time.
+# The act also implicitly confirms Central European Time as the
+# official time zone of Czechoslovakia and currently remains in force
+# in both the Czech Republic and Slovakia.)
+# https://www.psp.cz/eknih/1945pns/tisky/t0216_00.htm
+# (This is a link to the original legislative proposal dating back to
+# February 22, 1946. The accompanying memorandum to the proposal says
+# that an advisory committee on European railroad transportation that
+# met in Brussels in October 1945 decided that the change of time
+# should be carried out in all participating countries in a strictly
+# coordinated manner....)
+#
+# From Paul Eggert (2024-01-30):
+# The source for Czech data is: Kdy začíná a končí letní čas.
 # https://kalendar.beda.cz/kdy-zacina-a-konci-letni-cas
+# Its main text disagrees with its quoted sources only in 1918,
+# where the main text says spring and autumn transitions
+# occurred at 02:00 and 03:00 respectively (as usual),
+# whereas the 1918 source "Oznámení o zavedení letního času v roce 1918"
+# says transitions were at 01:00 and 02:00 respectively.
+# As the 1918 source appears to be a humorous piece, and it is
+# unlikely that Prague would have disagreed with its neighbors by an hour,
+# go with the main text for now.
+#
 # We know of no English-language name for historical Czech winter time;
 # abbreviate it as "GMT", as it happened to be GMT.
 #
@@ -1146,6 +1171,23 @@
 # 2. The shift *from* DST in 2023 happens as normal, but coincides with the
 #    shift to UTC-02 normaltime (people will not change their clocks here).
 # 3. After this, DST is still observed, but as -02/-01 instead of -03/-02.
+#
+# From Múte Bourup Egede via Jógvan Svabo Samuelsen (2023-03-15):
+# Greenland will not switch to Daylight Saving Time this year, 2023,
+# because the standard time for Greenland will change from UTC -3 to UTC -2.
+# However, Greenland will change to Daylight Saving Time again in 2024
+# and onwards.
+
+# From a contributor who wishes to remain anonymous for now (2023-10-29):
+# https://www.dr.dk/nyheder/seneste/i-nat-skal-uret-stilles-en-time-tilbage-men-foerste-gang-sker-det-ikke-i-groenland
+# with a link to that page:
+# https://naalakkersuisut.gl/Nyheder/2023/10/2710_sommertid
+# ... Ittoqqortoormiit joins the time of Nuuk at March 2024.
+# What would mean that America/Scoresbysund would either be in -01 year round
+# or in -02/-01 like America/Nuuk, but no longer in -01/+00.
+#
+# From Paul Eggert (2023-10-29):
+# For now, assume it will be like America/Nuuk.
 
 # Rule	NAME	FROM	TO	-	IN	ON	AT	SAVE	LETTER/S
 Rule	Thule	1991	1992	-	Mar	lastSun	2:00	1:00	D
@@ -1166,10 +1208,12 @@
 Zone America/Scoresbysund -1:27:52 -	LMT	1916 Jul 28 # Ittoqqortoormiit
 			-2:00	-	-02	1980 Apr  6  2:00
 			-2:00	C-Eur	-02/-01	1981 Mar 29
-			-1:00	EU	-01/+00
+			-1:00	EU	-01/+00 2024 Mar 31
+			-2:00	EU	-02/-01
 Zone America/Nuuk	-3:26:56 -	LMT	1916 Jul 28 # Godthåb
 			-3:00	-	-03	1980 Apr  6  2:00
-			-3:00	EU	-03/-02	2023 Oct 29  1:00u
+			-3:00	EU	-03/-02	2023 Mar 26  1:00u
+			-2:00	-	-02	2023 Oct 29  1:00u
 			-2:00	EU	-02/-01
 Zone America/Thule	-4:35:08 -	LMT	1916 Jul 28 # Pituffik
 			-4:00	Thule	A%sT
@@ -3734,11 +3778,7 @@
 # and not at 3:00 as would have been under EU rules.
 # This is why I have set the change to EU rules into May 1996,
 # so that the change in March is stil covered by the Ukraine rule.
-# The next change in October 1996 happened under EU rules....
-# TZ database holds three other zones for Ukraine.... I have not yet
-# worked out the consequences for these three zones, as we (me and my
-# US colleague David Cochrane) are still trying to get more
-# information upon these local deviations from Kiev rules.
+# The next change in October 1996 happened under EU rules.
 #
 # From Paul Eggert (2022-08-27):
 # For now, assume that Ukraine's zones all followed the same rules,
diff --git a/make/data/tzdata/iso3166.tab b/make/data/tzdata/iso3166.tab
index cea1773..7fa350e 100644
--- a/make/data/tzdata/iso3166.tab
+++ b/make/data/tzdata/iso3166.tab
@@ -26,17 +26,22 @@
 # This file is in the public domain, so clarified as of
 # 2009-05-17 by Arthur David Olson.
 #
-# From Paul Eggert (2022-11-18):
+# From Paul Eggert (2023-09-06):
 # This file contains a table of two-letter country codes.  Columns are
 # separated by a single tab.  Lines beginning with '#' are comments.
 # All text uses UTF-8 encoding.  The columns of the table are as follows:
 #
 # 1.  ISO 3166-1 alpha-2 country code, current as of
-#     ISO 3166-1 N1087 (2022-09-02).  See: Updates on ISO 3166-1
-#     https://isotc.iso.org/livelink/livelink/Open/16944257
-# 2.  The usual English name for the coded region,
-#     chosen so that alphabetic sorting of subsets produces helpful lists.
-#     This is not the same as the English name in the ISO 3166 tables.
+#     ISO/TC 46 N1108 (2023-04-05).  See: ISO/TC 46 Documents
+#     https://www.iso.org/committee/48750.html?view=documents
+# 2.  The usual English name for the coded region.  This sometimes
+#     departs from ISO-listed names, sometimes so that sorted subsets
+#     of names are useful (e.g., "Samoa (American)" and "Samoa
+#     (western)" rather than "American Samoa" and "Samoa"),
+#     sometimes to avoid confusion among non-experts (e.g.,
+#     "Czech Republic" and "Turkey" rather than "Czechia" and "Türkiye"),
+#     and sometimes to omit needless detail or churn (e.g., "Netherlands"
+#     rather than "Netherlands (the)" or "Netherlands (Kingdom of the)").
 #
 # The table is sorted by country code.
 #
diff --git a/make/data/tzdata/leapseconds b/make/data/tzdata/leapseconds
index 89ce8b8..8e7df3d 100644
--- a/make/data/tzdata/leapseconds
+++ b/make/data/tzdata/leapseconds
@@ -26,13 +26,10 @@
 # This file is in the public domain.
 
 # This file is generated automatically from the data in the public-domain
-# NIST format leap-seconds.list file, which can be copied from
-# <ftp://ftp.nist.gov/pub/time/leap-seconds.list>
-# or <ftp://ftp.boulder.nist.gov/pub/time/leap-seconds.list>.
-# The NIST file is used instead of its IERS upstream counterpart
+# NIST/IERS format leap-seconds.list file, which can be copied from
 # <https://hpiers.obspm.fr/iers/bul/bulc/ntp/leap-seconds.list>
-# because under US law the NIST file is public domain
-# whereas the IERS file's copyright and license status is unclear.
+# or, in a variant with different comments, from
+# <ftp://ftp.boulder.nist.gov/pub/time/leap-seconds.list>.
 # For more about leap-seconds.list, please see
 # The NTP Timescale and Leap Seconds
 # <https://www.eecis.udel.edu/~mills/leap.html>.
@@ -95,11 +92,11 @@
 # Any additional leap seconds will come after this.
 # This Expires line is commented out for now,
 # so that pre-2020a zic implementations do not reject this file.
-#Expires 2023	Dec	28	00:00:00
+#Expires 2024	Dec	28	00:00:00
 
 # POSIX timestamps for the data in this file:
-#updated 1467936000 (2016-07-08 00:00:00 UTC)
-#expires 1703721600 (2023-12-28 00:00:00 UTC)
+#updated 1704708379 (2024-01-08 10:06:19 UTC)
+#expires 1735344000 (2024-12-28 00:00:00 UTC)
 
-#	Updated through IERS Bulletin C65
-#	File expires on:  28 December 2023
+#	Updated through IERS Bulletin C (https://hpiers.obspm.fr/iers/bul/bulc/bulletinc.dat)
+#	File expires on 28 December 2024
diff --git a/make/data/tzdata/northamerica b/make/data/tzdata/northamerica
index e240cf3..a8b2ef3 100644
--- a/make/data/tzdata/northamerica
+++ b/make/data/tzdata/northamerica
@@ -1,3 +1,4 @@
+#
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -1290,6 +1291,10 @@
 #	<http://cs.ucla.edu/~eggert/The-Waste-of-Daylight-19th.pdf>
 #	[PDF] (1914-03)
 #
+# For the 1911/1912 establishment of standard time in French possessions, see:
+# Société Française de Physique, Recueil de constantes physiques (1913),
+# page 752, 18b.
+#
 # See the 'europe' file for Greenland.
 
 # Canada
@@ -1376,7 +1381,7 @@
 # From Paul Eggert (2014-10-18):
 # H. David Matthews and Mary Vincent's map
 # "It's about TIME", _Canadian Geographic_ (September-October 1998)
-# http://www.canadiangeographic.ca/Magazine/SO98/alacarte.asp
+# https://web.archive.org/web/19990827055050/https://canadiangeographic.ca/SO98/geomap.htm
 # contains detailed boundaries for regions observing nonstandard
 # time and daylight saving time arrangements in Canada circa 1998.
 #
@@ -1475,7 +1480,7 @@
 Rule	StJohns	2007	2011	-	Mar	Sun>=8	0:01	1:00	D
 Rule	StJohns	2007	2010	-	Nov	Sun>=1	0:01	0	S
 #
-# St John's has an apostrophe, but Posix file names can't have apostrophes.
+# St John's has an apostrophe, but POSIX file names can't have apostrophes.
 # Zone	NAME		STDOFF	RULES	FORMAT	[UNTIL]
 Zone America/St_Johns	-3:30:52 -	LMT	1884
 			-3:30:52 StJohns N%sT	1918
@@ -1664,6 +1669,15 @@
 #     Some cities in the United States have pushed the deadline back
 #     three weeks and will change over from daylight saving in October.
 
+# From Chris Walton (2024-01-09):
+# The [Toronto] changes in 1947, 1948, and 1949 took place at 2:00 a.m. local
+# time instead of midnight....  Toronto Daily Star - ...
+# April 2, 1947 - Page 39 ... April 7, 1948 - Page 13 ...
+# April 2, 1949 - Page 1 ... April 7, 1949 - Page 24 ...
+# November 25, 1949 - Page 52 ... April 21, 1950 - Page 14 ...
+# September 19, 1950 - Page 46 ... September 20, 1950 - Page 3 ...
+# November 24, 1950 - Page 21
+
 # From Arthur David Olson (2010-07-17):
 #
 # "Standard Time and Time Zones in Canada" appeared in
@@ -1725,13 +1739,9 @@
 Rule	Toronto	1928	1937	-	Apr	Sun>=25	2:00	1:00	D
 Rule	Toronto	1938	1940	-	Apr	lastSun	2:00	1:00	D
 Rule	Toronto	1938	1939	-	Sep	lastSun	2:00	0	S
-Rule	Toronto	1945	1946	-	Sep	lastSun	2:00	0	S
-Rule	Toronto	1946	only	-	Apr	lastSun	2:00	1:00	D
-Rule	Toronto	1947	1949	-	Apr	lastSun	0:00	1:00	D
-Rule	Toronto	1947	1948	-	Sep	lastSun	0:00	0	S
-Rule	Toronto	1949	only	-	Nov	lastSun	0:00	0	S
-Rule	Toronto	1950	1973	-	Apr	lastSun	2:00	1:00	D
-Rule	Toronto	1950	only	-	Nov	lastSun	2:00	0	S
+Rule	Toronto	1945	1948	-	Sep	lastSun	2:00	0	S
+Rule	Toronto	1946	1973	-	Apr	lastSun	2:00	1:00	D
+Rule	Toronto	1949	1950	-	Nov	lastSun	2:00	0	S
 Rule	Toronto	1951	1956	-	Sep	lastSun	2:00	0	S
 # Shanks & Pottenger say Toronto ended DST a week early in 1971,
 # namely on 1971-10-24, but Mark Brader wrote (2003-05-31) that this
@@ -3454,7 +3464,7 @@
 # Martinique
 # Zone	NAME		STDOFF	RULES	FORMAT	[UNTIL]
 Zone America/Martinique	-4:04:20 -      LMT	1890        # Fort-de-France
-			-4:04:20 -	FFMT	1911 May    # Fort-de-France MT
+			-4:04:20 -	FFMT	1911 May  1 # Fort-de-France MT
 			-4:00	-	AST	1980 Apr  6
 			-4:00	1:00	ADT	1980 Sep 28
 			-4:00	-	AST
@@ -3561,7 +3571,7 @@
 # St Pierre and Miquelon
 # There are too many St Pierres elsewhere, so we'll use 'Miquelon'.
 # Zone	NAME		STDOFF	RULES	FORMAT	[UNTIL]
-Zone America/Miquelon	-3:44:40 -	LMT	1911 May 15 # St Pierre
+Zone America/Miquelon	-3:44:40 -	LMT	1911 Jun 15 # St Pierre
 			-4:00	-	AST	1980 May
 			-3:00	-	-03	1987
 			-3:00	Canada	-03/-02
diff --git a/make/data/tzdata/southamerica b/make/data/tzdata/southamerica
index 4024e71..d77acc0 100644
--- a/make/data/tzdata/southamerica
+++ b/make/data/tzdata/southamerica
@@ -1593,8 +1593,11 @@
 			-3:00	-	-03
 
 # French Guiana
+# For the 1911/1912 establishment of standard time in French possessions, see:
+# Société Française de Physique, Recueil de constantes physiques (1913),
+# page 752, 18b.
 # Zone	NAME		STDOFF	RULES	FORMAT	[UNTIL]
-Zone America/Cayenne	-3:29:20 -	LMT	1911 Jul
+Zone America/Cayenne	-3:29:20 -	LMT	1911 Jul  1
 			-4:00	-	-04	1967 Oct
 			-3:00	-	-03
 
@@ -1720,6 +1723,12 @@
 # From Carlos Raúl Perasso (2014-02-28):
 # Decree 1264 can be found at:
 # http://www.presidencia.gov.py/archivos/documentos/DECRETO1264_ey9r8zai.pdf
+#
+# From Paul Eggert (2023-07-26):
+# Transition dates are now set by Law No. 7115, not by presidential decree.
+# https://www.abc.com.py/politica/2023/07/12/promulgacion-el-cambio-de-hora-sera-por-ley/
+# From Carlos Raúl Perasso (2023-07-27):
+# http://silpy.congreso.gov.py/descarga/ley-144138
 Rule	Para	2013	max	-	Mar	Sun>=22	0:00	0	-
 
 # Zone	NAME		STDOFF	RULES	FORMAT	[UNTIL]
diff --git a/make/data/tzdata/zone.tab b/make/data/tzdata/zone.tab
index 3edb0d6..0a01e87 100644
--- a/make/data/tzdata/zone.tab
+++ b/make/data/tzdata/zone.tab
@@ -71,7 +71,7 @@
 AR	-2447-06525	America/Argentina/Salta	Salta (SA, LP, NQ, RN)
 AR	-2411-06518	America/Argentina/Jujuy	Jujuy (JY)
 AR	-2649-06513	America/Argentina/Tucuman	Tucuman (TM)
-AR	-2828-06547	America/Argentina/Catamarca	Catamarca (CT); Chubut (CH)
+AR	-2828-06547	America/Argentina/Catamarca	Catamarca (CT), Chubut (CH)
 AR	-2926-06651	America/Argentina/La_Rioja	La Rioja (LR)
 AR	-3132-06831	America/Argentina/San_Juan	San Juan (SJ)
 AR	-3253-06849	America/Argentina/Mendoza	Mendoza (MZ)
@@ -110,7 +110,7 @@
 BO	-1630-06809	America/La_Paz
 BQ	+120903-0681636	America/Kralendijk
 BR	-0351-03225	America/Noronha	Atlantic islands
-BR	-0127-04829	America/Belem	Para (east); Amapa
+BR	-0127-04829	America/Belem	Para (east), Amapa
 BR	-0343-03830	America/Fortaleza	Brazil (northeast: MA, PI, CE, RN, PB)
 BR	-0803-03454	America/Recife	Pernambuco
 BR	-0712-04812	America/Araguaina	Tocantins
@@ -130,21 +130,21 @@
 BW	-2439+02555	Africa/Gaborone
 BY	+5354+02734	Europe/Minsk
 BZ	+1730-08812	America/Belize
-CA	+4734-05243	America/St_Johns	Newfoundland; Labrador (southeast)
-CA	+4439-06336	America/Halifax	Atlantic - NS (most areas); PE
+CA	+4734-05243	America/St_Johns	Newfoundland, Labrador (SE)
+CA	+4439-06336	America/Halifax	Atlantic - NS (most areas), PE
 CA	+4612-05957	America/Glace_Bay	Atlantic - NS (Cape Breton)
 CA	+4606-06447	America/Moncton	Atlantic - New Brunswick
 CA	+5320-06025	America/Goose_Bay	Atlantic - Labrador (most areas)
 CA	+5125-05707	America/Blanc-Sablon	AST - QC (Lower North Shore)
-CA	+4339-07923	America/Toronto	Eastern - ON, QC (most areas)
+CA	+4339-07923	America/Toronto	Eastern - ON & QC (most areas)
 CA	+6344-06828	America/Iqaluit	Eastern - NU (most areas)
-CA	+484531-0913718	America/Atikokan	EST - ON (Atikokan); NU (Coral H)
-CA	+4953-09709	America/Winnipeg	Central - ON (west); Manitoba
+CA	+484531-0913718	America/Atikokan	EST - ON (Atikokan), NU (Coral H)
+CA	+4953-09709	America/Winnipeg	Central - ON (west), Manitoba
 CA	+744144-0944945	America/Resolute	Central - NU (Resolute)
 CA	+624900-0920459	America/Rankin_Inlet	Central - NU (central)
 CA	+5024-10439	America/Regina	CST - SK (most areas)
 CA	+5017-10750	America/Swift_Current	CST - SK (midwest)
-CA	+5333-11328	America/Edmonton	Mountain - AB; BC (E); NT (E); SK (W)
+CA	+5333-11328	America/Edmonton	Mountain - AB, BC(E), NT(E), SK(W)
 CA	+690650-1050310	America/Cambridge_Bay	Mountain - NU (west)
 CA	+682059-1334300	America/Inuvik	Mountain - NT (west)
 CA	+4906-11631	America/Creston	MST - BC (Creston)
@@ -230,8 +230,8 @@
 HU	+4730+01905	Europe/Budapest
 ID	-0610+10648	Asia/Jakarta	Java, Sumatra
 ID	-0002+10920	Asia/Pontianak	Borneo (west, central)
-ID	-0507+11924	Asia/Makassar	Borneo (east, south); Sulawesi/Celebes, Bali, Nusa Tengarra; Timor (west)
-ID	-0232+14042	Asia/Jayapura	New Guinea (West Papua / Irian Jaya); Malukus/Moluccas
+ID	-0507+11924	Asia/Makassar	Borneo (east, south), Sulawesi/Celebes, Bali, Nusa Tengarra, Timor (west)
+ID	-0232+14042	Asia/Jayapura	New Guinea (West Papua / Irian Jaya), Malukus/Moluccas
 IE	+5320-00615	Europe/Dublin
 IL	+314650+0351326	Asia/Jerusalem
 IM	+5409-00428	Europe/Isle_of_Man
@@ -378,7 +378,7 @@
 RU	+643337+1431336	Asia/Ust-Nera	MSK+07 - Oymyakonsky
 RU	+5934+15048	Asia/Magadan	MSK+08 - Magadan
 RU	+4658+14242	Asia/Sakhalin	MSK+08 - Sakhalin Island
-RU	+6728+15343	Asia/Srednekolymsk	MSK+08 - Sakha (E); N Kuril Is
+RU	+6728+15343	Asia/Srednekolymsk	MSK+08 - Sakha (E), N Kuril Is
 RU	+5301+15839	Asia/Kamchatka	MSK+09 - Kamchatka
 RU	+6445+17729	Asia/Anadyr	MSK+09 - Bering Sea
 RW	-0157+03004	Africa/Kigali
@@ -441,7 +441,7 @@
 US	+465042-1012439	America/North_Dakota/New_Salem	Central - ND (Morton rural)
 US	+471551-1014640	America/North_Dakota/Beulah	Central - ND (Mercer)
 US	+394421-1045903	America/Denver	Mountain (most areas)
-US	+433649-1161209	America/Boise	Mountain - ID (south); OR (east)
+US	+433649-1161209	America/Boise	Mountain - ID (south), OR (east)
 US	+332654-1120424	America/Phoenix	MST - AZ (except Navajo)
 US	+340308-1181434	America/Los_Angeles	Pacific
 US	+611305-1495401	America/Anchorage	Alaska (most areas)
diff --git a/make/jdk/src/classes/build/tools/generatecurrencydata/GenerateCurrencyData.java b/make/jdk/src/classes/build/tools/generatecurrencydata/GenerateCurrencyData.java
index 561edbe..9655e08 100644
--- a/make/jdk/src/classes/build/tools/generatecurrencydata/GenerateCurrencyData.java
+++ b/make/jdk/src/classes/build/tools/generatecurrencydata/GenerateCurrencyData.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,6 +32,7 @@
 import java.io.FileOutputStream;
 import java.io.InputStream;
 import java.text.SimpleDateFormat;
+import java.util.Arrays;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.Locale;
@@ -339,9 +340,15 @@
                 validCurrencyCodes.substring(i * 7 + 3, i * 7 + 6));
             checkCurrencyCode(currencyCode);
             int tableEntry = mainTable[(currencyCode.charAt(0) - 'A') * A_TO_Z + (currencyCode.charAt(1) - 'A')];
-            if (tableEntry == INVALID_COUNTRY_ENTRY ||
-                    (tableEntry & SPECIAL_CASE_COUNTRY_MASK) != 0 ||
-                    (tableEntry & SIMPLE_CASE_COUNTRY_FINAL_CHAR_MASK) != (currencyCode.charAt(2) - 'A')) {
+
+            // Do not allow a future currency to be classified as an otherCurrency,
+            // otherwise it will leak out into Currency:getAvailableCurrencies
+            boolean futureCurrency = Arrays.asList(specialCaseNewCurrencies).contains(currencyCode);
+            boolean simpleCurrency = (tableEntry & SIMPLE_CASE_COUNTRY_FINAL_CHAR_MASK) == (currencyCode.charAt(2) - 'A');
+
+            // If neither a simple currency, or one defined in the future
+            // then the current currency is applicable to be added to the otherTable
+            if (!futureCurrency && !simpleCurrency) {
                 if (otherCurrenciesCount == maxOtherCurrencies) {
                     throw new RuntimeException("too many other currencies");
                 }
diff --git a/make/modules/java.desktop/lib/Awt2dLibraries.gmk b/make/modules/java.desktop/lib/Awt2dLibraries.gmk
index 0318958..0efcbf8 100644
--- a/make/modules/java.desktop/lib/Awt2dLibraries.gmk
+++ b/make/modules/java.desktop/lib/Awt2dLibraries.gmk
@@ -474,7 +474,6 @@
     LIBFREETYPE_LIBS := -lfreetype
   endif
 
-  # gcc_ftobjs.c := maybe-uninitialized required for GCC 7 builds.
   $(eval $(call SetupJdkLibrary, BUILD_LIBFREETYPE, \
       NAME := freetype, \
       OPTIMIZATION := HIGHEST, \
@@ -483,7 +482,6 @@
       EXTRA_HEADER_DIRS := $(BUILD_LIBFREETYPE_HEADER_DIRS), \
       DISABLED_WARNINGS_microsoft := 4018 4267 4244 4312 4819, \
       DISABLED_WARNINGS_gcc := implicit-fallthrough cast-function-type bad-function-cast dangling-pointer stringop-overflow, \
-      DISABLED_WARNINGS_gcc_ftobjs.c := maybe-uninitialized, \
       LDFLAGS := $(LDFLAGS_JDKLIB) \
           $(call SET_SHARED_LIBRARY_ORIGIN), \
   ))
@@ -518,6 +516,11 @@
    # hb-ft.cc is not presently needed, and requires freetype 2.4.2 or later.
    LIBFONTMANAGER_EXCLUDE_FILES += libharfbuzz/hb-ft.cc
 
+   # list of disabled warnings and the compilers for which it was specifically added.
+   # array-bounds         -> GCC 12 on Alpine Linux
+   # parentheses          -> GCC 6
+   # range-loop-analysis  -> clang on Xcode12
+
    HARFBUZZ_DISABLED_WARNINGS_gcc := type-limits missing-field-initializers strict-aliasing \
         array-bounds parentheses
    # noexcept-type required for GCC 7 builds. Not required for GCC 8+.
diff --git a/make/test/JtregNativeHotspot.gmk b/make/test/JtregNativeHotspot.gmk
index a55cce7..92af1a8 100644
--- a/make/test/JtregNativeHotspot.gmk
+++ b/make/test/JtregNativeHotspot.gmk
@@ -144,12 +144,14 @@
    NO_FRAMEPOINTER_CFLAGS := -fomit-frame-pointer
 endif
 
+JVMTI_COMMON_INCLUDES=-I$(TOPDIR)/test/lib/jdk/test/lib/jvmti
+
 BUILD_HOTSPOT_JTREG_LIBRARIES_CFLAGS_libNoFramePointer := $(NO_FRAMEPOINTER_CFLAGS)
 # Optimization -O3 needed, HIGH == -O3
 BUILD_HOTSPOT_JTREG_LIBRARIES_OPTIMIZATION_libNoFramePointer := HIGH
 
-BUILD_HOTSPOT_JTREG_LIBRARIES_CFLAGS := -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS
-BUILD_HOTSPOT_JTREG_EXECUTABLES_CFLAGS := -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS
+BUILD_HOTSPOT_JTREG_LIBRARIES_CFLAGS := -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS $(JVMTI_COMMON_INCLUDES)
+BUILD_HOTSPOT_JTREG_EXECUTABLES_CFLAGS := -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS $(JVMTI_COMMON_INCLUDES)
 
 BUILD_HOTSPOT_JTREG_LIBRARIES_CFLAGS_libProcessUtils := $(VM_SHARE_INCLUDES)
 
diff --git a/make/test/JtregNativeJdk.gmk b/make/test/JtregNativeJdk.gmk
index 0e21b97..fed0db4 100644
--- a/make/test/JtregNativeJdk.gmk
+++ b/make/test/JtregNativeJdk.gmk
@@ -110,6 +110,8 @@
   # stripping during the test libraries' build.
   BUILD_JDK_JTREG_LIBRARIES_CFLAGS_libFib := -g
   BUILD_JDK_JTREG_LIBRARIES_STRIP_SYMBOLS_libFib := false
+  # nio tests' libCreationTimeHelper native needs -ldl linker flag
+  BUILD_JDK_JTREG_LIBRARIES_LIBS_libCreationTimeHelper := -ldl
 endif
 
 # This evaluation is expensive and should only be done if this target was
diff --git a/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp
index d4de8ae..ae5ee62 100644
--- a/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp
+++ b/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp
@@ -282,7 +282,8 @@
         __ bind(L);
       }
 #endif
-      __ ldp(r19, r20, Address(OSR_buf, slot_offset));
+      __ ldr(r19, Address(OSR_buf, slot_offset));
+      __ ldr(r20, Address(OSR_buf, slot_offset + BytesPerWord));
       __ str(r19, frame_map()->address_for_monitor_lock(i));
       __ str(r20, frame_map()->address_for_monitor_object(i));
     }
@@ -2725,7 +2726,10 @@
   __ verify_oop(obj);
 
   if (tmp != obj) {
+    assert_different_registers(obj, tmp, rscratch1, rscratch2, mdo_addr.base(), mdo_addr.index());
     __ mov(tmp, obj);
+  } else {
+    assert_different_registers(obj, rscratch1, rscratch2, mdo_addr.base(), mdo_addr.index());
   }
   if (do_null) {
     __ cbnz(tmp, update);
@@ -2782,10 +2786,11 @@
           __ cbz(rscratch2, none);
           __ cmp(rscratch2, (u1)TypeEntries::null_seen);
           __ br(Assembler::EQ, none);
-          // There is a chance that the checks above (re-reading profiling
-          // data from memory) fail if another thread has just set the
+          // There is a chance that the checks above
+          // fail if another thread has just set the
           // profiling to this obj's klass
           __ dmb(Assembler::ISHLD);
+          __ eor(tmp, tmp, rscratch2); // get back original value before XOR
           __ ldr(rscratch2, mdo_addr);
           __ eor(tmp, tmp, rscratch2);
           __ andr(rscratch1, tmp, TypeEntries::type_klass_mask);
@@ -2810,6 +2815,10 @@
         __ bind(none);
         // first time here. Set profile type.
         __ str(tmp, mdo_addr);
+#ifdef ASSERT
+        __ andr(tmp, tmp, TypeEntries::type_mask);
+        __ verify_klass_ptr(tmp);
+#endif
       }
     } else {
       // There's a single possible klass at this profile point
@@ -2841,6 +2850,10 @@
 #endif
         // first time here. Set profile type.
         __ str(tmp, mdo_addr);
+#ifdef ASSERT
+        __ andr(tmp, tmp, TypeEntries::type_mask);
+        __ verify_klass_ptr(tmp);
+#endif
       } else {
         assert(ciTypeEntries::valid_ciklass(current_klass) != NULL &&
                ciTypeEntries::valid_ciklass(current_klass) != exact_klass, "inconsistent");
diff --git a/src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp
index d2cbdbd..209f50e 100644
--- a/src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp
+++ b/src/hotspot/cpu/aarch64/c1_LIRGenerator_aarch64.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2014, Red Hat Inc. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -167,8 +167,10 @@
   if (index->is_register()) {
     // apply the shift and accumulate the displacement
     if (shift > 0) {
-      LIR_Opr tmp = new_pointer_register();
-      __ shift_left(index, shift, tmp);
+      // Use long register to avoid overflow when shifting large index values left.
+      LIR_Opr tmp = new_register(T_LONG);
+      __ convert(Bytecodes::_i2l, index, tmp);
+      __ shift_left(tmp, shift, tmp);
       index = tmp;
     }
     if (large_disp != 0) {
diff --git a/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp b/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp
index bbecb7d..1db1037 100644
--- a/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp
+++ b/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp
@@ -1638,7 +1638,7 @@
 }
 
 void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& mdo_addr) {
-  assert_different_registers(obj, rscratch1);
+  assert_different_registers(obj, rscratch1, mdo_addr.base(), mdo_addr.index());
   Label update, next, none;
 
   verify_oop(obj);
@@ -1660,13 +1660,13 @@
   tbnz(obj, exact_log2(TypeEntries::type_unknown), next);
   // already unknown. Nothing to do anymore.
 
-  ldr(rscratch1, mdo_addr);
   cbz(rscratch1, none);
   cmp(rscratch1, (u1)TypeEntries::null_seen);
   br(Assembler::EQ, none);
-  // There is a chance that the checks above (re-reading profiling
-  // data from memory) fail if another thread has just set the
+  // There is a chance that the checks above
+  // fail if another thread has just set the
   // profiling to this obj's klass
+  eor(obj, obj, rscratch1); // get back original value before XOR
   ldr(rscratch1, mdo_addr);
   eor(obj, obj, rscratch1);
   tst(obj, TypeEntries::type_klass_mask);
@@ -1679,6 +1679,10 @@
   bind(none);
   // first time here. Set profile type.
   str(obj, mdo_addr);
+#ifdef ASSERT
+  andr(obj, obj, TypeEntries::type_mask);
+  verify_klass_ptr(obj);
+#endif
 
   bind(next);
 }
diff --git a/src/hotspot/cpu/aarch64/relocInfo_aarch64.hpp b/src/hotspot/cpu/aarch64/relocInfo_aarch64.hpp
index 7708b44..904fe08 100644
--- a/src/hotspot/cpu/aarch64/relocInfo_aarch64.hpp
+++ b/src/hotspot/cpu/aarch64/relocInfo_aarch64.hpp
@@ -29,8 +29,9 @@
   // machine-dependent parts of class relocInfo
  private:
   enum {
-    // Relocations are byte-aligned.
-    offset_unit        =  1,
+    // AArch64 instructions are always 4 bytes long and 4-aligned, so
+    // the two lowest offset bits can always be discarded.
+    offset_unit        =  4,
     // Must be at least 1 for RelocInfo::narrow_oop_in_const.
     format_width       =  1
   };
diff --git a/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp b/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp
index 10ecd0e..02f5927 100644
--- a/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp
+++ b/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp
@@ -3134,7 +3134,7 @@
         // Klass seen before, nothing to do (regardless of unknown bit).
         //beq(CCR1, do_nothing);
 
-        __ andi_(R0, klass, TypeEntries::type_unknown);
+        __ andi_(R0, tmp, TypeEntries::type_unknown);
         // Already unknown. Nothing to do anymore.
         //bne(CCR0, do_nothing);
         __ crorc(CCR0, Assembler::equal, CCR1, Assembler::equal); // cr0 eq = cr1 eq or cr0 ne
diff --git a/src/hotspot/cpu/ppc/c1_LIRGenerator_ppc.cpp b/src/hotspot/cpu/ppc/c1_LIRGenerator_ppc.cpp
index 2c68592..0a5ab12 100644
--- a/src/hotspot/cpu/ppc/c1_LIRGenerator_ppc.cpp
+++ b/src/hotspot/cpu/ppc/c1_LIRGenerator_ppc.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2012, 2019 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -164,8 +164,10 @@
   if (index->is_register()) {
     // Apply the shift and accumulate the displacement.
     if (shift > 0) {
-      LIR_Opr tmp = new_pointer_register();
-      __ shift_left(index, shift, tmp);
+      // Use long register to avoid overflow when shifting large index values left.
+      LIR_Opr tmp = new_register(T_LONG);
+      __ convert(Bytecodes::_i2l, index, tmp);
+      __ shift_left(tmp, shift, tmp);
       index = tmp;
     }
     if (large_disp != 0) {
diff --git a/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp b/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp
index fb07b3f..b474fe8 100644
--- a/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp
+++ b/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp
@@ -1734,7 +1734,7 @@
   // Klass seen before, nothing to do (regardless of unknown bit).
   //beq(CCR1, do_nothing);
 
-  andi_(R0, klass, TypeEntries::type_unknown);
+  andi_(R0, tmp, TypeEntries::type_unknown);
   // Already unknown. Nothing to do anymore.
   //bne(CCR0, do_nothing);
   crorc(CCR0, Assembler::equal, CCR1, Assembler::equal); // cr0 eq = cr1 eq or cr0 ne
diff --git a/src/hotspot/cpu/riscv/assembler_riscv.hpp b/src/hotspot/cpu/riscv/assembler_riscv.hpp
index c7e9569..98c51e9 100644
--- a/src/hotspot/cpu/riscv/assembler_riscv.hpp
+++ b/src/hotspot/cpu/riscv/assembler_riscv.hpp
@@ -2782,6 +2782,17 @@
     return uabs(target - branch) < branch_range;
   }
 
+  // Decode the given instruction, checking if it's a 16-bit compressed
+  // instruction and return the address of the next instruction.
+  static address locate_next_instruction(address inst) {
+    // Instruction wider than 16 bits has the two least-significant bits set.
+    if ((0x3 & *inst) == 0x3) {
+      return inst + instruction_size;
+    } else {
+      return inst + compressed_instruction_size;
+    }
+  }
+
   Assembler(CodeBuffer* code) : AbstractAssembler(code), _in_compressible_region(false) {}
 
   virtual ~Assembler() {}
diff --git a/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp b/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp
index 9c9b6ac..e62b295 100644
--- a/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp
+++ b/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp
@@ -1649,10 +1649,11 @@
       __ beqz(t1, none);
       __ mv(t0, (u1)TypeEntries::null_seen);
       __ beq(t0, t1, none);
-      // There is a chance that the checks above (re-reading profiling
-      // data from memory) fail if another thread has just set the
+      // There is a chance that the checks above
+      // fail if another thread has just set the
       // profiling to this obj's klass
       __ membar(MacroAssembler::LoadLoad);
+      __ xorr(tmp, tmp, t1); // get back original value before XOR
       __ ld(t1, mdo_addr);
       __ xorr(tmp, tmp, t1);
       __ andi(t0, tmp, TypeEntries::type_klass_mask);
@@ -1679,6 +1680,10 @@
     __ bind(none);
     // first time here. Set profile type.
     __ sd(tmp, mdo_addr);
+#ifdef ASSERT
+    __ andi(tmp, tmp, TypeEntries::type_mask);
+    __ verify_klass_ptr(tmp);
+#endif
   }
 }
 
@@ -1713,6 +1718,10 @@
 #endif
     // first time here. Set profile type.
     __ sd(tmp, mdo_addr);
+#ifdef ASSERT
+    __ andi(tmp, tmp, TypeEntries::type_mask);
+    __ verify_klass_ptr(tmp);
+#endif
   } else {
     assert(ciTypeEntries::valid_ciklass(current_klass) != NULL &&
            ciTypeEntries::valid_ciklass(current_klass) != exact_klass, "inconsistent");
diff --git a/src/hotspot/cpu/riscv/interp_masm_riscv.cpp b/src/hotspot/cpu/riscv/interp_masm_riscv.cpp
index dadf1b7..cb9375b 100644
--- a/src/hotspot/cpu/riscv/interp_masm_riscv.cpp
+++ b/src/hotspot/cpu/riscv/interp_masm_riscv.cpp
@@ -1682,8 +1682,8 @@
   bind(update);
   load_klass(obj, obj);
 
-  ld(t0, mdo_addr);
-  xorr(obj, obj, t0);
+  ld(tmp, mdo_addr);
+  xorr(obj, obj, tmp);
   andi(t0, obj, TypeEntries::type_klass_mask);
   beqz(t0, next); // klass seen before, nothing to
                   // do. The unknown bit may have been
@@ -1693,15 +1693,15 @@
   bnez(t0, next);
   // already unknown. Nothing to do anymore.
 
-  ld(t0, mdo_addr);
-  beqz(t0, none);
-  mv(tmp, (u1)TypeEntries::null_seen);
-  beq(t0, tmp, none);
-  // There is a chance that the checks above (re-reading profiling
-  // data from memory) fail if another thread has just set the
+  beqz(tmp, none);
+  mv(t0, (u1)TypeEntries::null_seen);
+  beq(tmp, t0, none);
+  // There is a chance that the checks above
+  // fail if another thread has just set the
   // profiling to this obj's klass
-  ld(t0, mdo_addr);
-  xorr(obj, obj, t0);
+  xorr(obj, obj, tmp); // get back original value before XOR
+  ld(tmp, mdo_addr);
+  xorr(obj, obj, tmp);
   andi(t0, obj, TypeEntries::type_klass_mask);
   beqz(t0, next);
 
@@ -1712,6 +1712,10 @@
   bind(none);
   // first time here. Set profile type.
   sd(obj, mdo_addr);
+#ifdef ASSERT
+  andi(obj, obj, TypeEntries::type_mask);
+  verify_klass_ptr(obj);
+#endif
 
   bind(next);
 }
diff --git a/src/hotspot/cpu/riscv/vm_version_riscv.hpp b/src/hotspot/cpu/riscv/vm_version_riscv.hpp
index 3d91fa9..1e4bdb0 100644
--- a/src/hotspot/cpu/riscv/vm_version_riscv.hpp
+++ b/src/hotspot/cpu/riscv/vm_version_riscv.hpp
@@ -199,6 +199,9 @@
   static void initialize_cpu_information();
 
   constexpr static bool supports_stack_watermark_barrier() { return true; }
+
+  // RISCV64 supports fast class initialization checks
+  static bool supports_fast_class_init_checks() { return true; }
 };
 
 #endif // CPU_RISCV_VM_VERSION_RISCV_HPP
diff --git a/src/hotspot/cpu/s390/c1_LIRGenerator_s390.cpp b/src/hotspot/cpu/s390/c1_LIRGenerator_s390.cpp
index c6d5085..67d838b 100644
--- a/src/hotspot/cpu/s390/c1_LIRGenerator_s390.cpp
+++ b/src/hotspot/cpu/s390/c1_LIRGenerator_s390.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2016, 2017 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -157,8 +157,10 @@
     return new LIR_Address(base, index, type);
   } else {
     if (shift > 0) {
-      LIR_Opr tmp = new_pointer_register();
-      __ shift_left(index, shift, tmp);
+      // Use long register to avoid overflow when shifting large index values left.
+      LIR_Opr tmp = new_register(T_LONG);
+      __ convert(Bytecodes::_i2l, index, tmp);
+      __ shift_left(tmp, shift, tmp);
       index = tmp;
     }
     return new LIR_Address(base, index, disp, type);
diff --git a/src/hotspot/cpu/x86/assembler_x86.cpp b/src/hotspot/cpu/x86/assembler_x86.cpp
index f7a4609..b05646a 100644
--- a/src/hotspot/cpu/x86/assembler_x86.cpp
+++ b/src/hotspot/cpu/x86/assembler_x86.cpp
@@ -5603,6 +5603,14 @@
   emit_int8(imm8);
 }
 
+void Assembler::testl(Address dst, int32_t imm32) {
+  InstructionMark im(this);
+  prefix(dst);
+  emit_int8((unsigned char)0xF7);
+  emit_operand(as_Register(0), dst, 4);
+  emit_int32(imm32);
+}
+
 void Assembler::testl(Register dst, int32_t imm32) {
   // not using emit_arith because test
   // doesn't support sign-extension of
diff --git a/src/hotspot/cpu/x86/assembler_x86.hpp b/src/hotspot/cpu/x86/assembler_x86.hpp
index c3d25ad..e8a61ef 100644
--- a/src/hotspot/cpu/x86/assembler_x86.hpp
+++ b/src/hotspot/cpu/x86/assembler_x86.hpp
@@ -318,7 +318,7 @@
   }
 
   bool xmmindex_needs_rex() const {
-    return _xmmindex->is_valid() && _xmmindex->encoding() >= 8;
+    return _xmmindex->is_valid() && ((_xmmindex->encoding() & 8) == 8);
   }
 
   relocInfo::relocType reloc() const { return _rspec.type(); }
@@ -2063,6 +2063,7 @@
   void testb(Register dst, int imm8);
   void testb(Address dst, int imm8);
 
+  void testl(Address dst, int32_t imm32);
   void testl(Register dst, int32_t imm32);
   void testl(Register dst, Register src);
   void testl(Register dst, Address src);
diff --git a/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp b/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp
index d73e730..592efea 100644
--- a/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp
+++ b/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp
@@ -3632,13 +3632,33 @@
 
   __ verify_oop(obj);
 
-  if (tmp != obj) {
-    __ mov(tmp, obj);
+#ifdef ASSERT
+  if (obj == tmp) {
+#ifdef _LP64
+    assert_different_registers(obj, rscratch1, mdo_addr.base(), mdo_addr.index());
+#else
+    assert_different_registers(obj, mdo_addr.base(), mdo_addr.index());
+#endif
+  } else {
+#ifdef _LP64
+    assert_different_registers(obj, tmp, rscratch1, mdo_addr.base(), mdo_addr.index());
+#else
+    assert_different_registers(obj, tmp, mdo_addr.base(), mdo_addr.index());
+#endif
   }
+#endif
   if (do_null) {
-    __ testptr(tmp, tmp);
+    __ testptr(obj, obj);
     __ jccb(Assembler::notZero, update);
     if (!TypeEntries::was_null_seen(current_klass)) {
+      __ testptr(mdo_addr, TypeEntries::null_seen);
+#ifndef ASSERT
+      __ jccb(Assembler::notZero, next); // already set
+#else
+      __ jcc(Assembler::notZero, next); // already set
+#endif
+      // atomic update to prevent overwriting Klass* with 0
+      __ lock();
       __ orptr(mdo_addr, TypeEntries::null_seen);
     }
     if (do_update) {
@@ -3649,7 +3669,7 @@
       __ jmp(next);
     }
   } else {
-    __ testptr(tmp, tmp);
+    __ testptr(obj, obj);
     __ jcc(Assembler::notZero, update);
     __ stop("unexpect null obj");
 #endif
@@ -3661,7 +3681,7 @@
 #ifdef ASSERT
     if (exact_klass != NULL) {
       Label ok;
-      __ load_klass(tmp, tmp, tmp_load_klass);
+      __ load_klass(tmp, obj, tmp_load_klass);
       __ push(tmp);
       __ mov_metadata(tmp, exact_klass->constant_encoding());
       __ cmpptr(tmp, Address(rsp, 0));
@@ -3676,9 +3696,11 @@
         if (exact_klass != NULL) {
           __ mov_metadata(tmp, exact_klass->constant_encoding());
         } else {
-          __ load_klass(tmp, tmp, tmp_load_klass);
+          __ load_klass(tmp, obj, tmp_load_klass);
         }
-
+#ifdef _LP64
+        __ mov(rscratch1, tmp); // save original value before XOR
+#endif
         __ xorptr(tmp, mdo_addr);
         __ testptr(tmp, TypeEntries::type_klass_mask);
         // klass seen before, nothing to do. The unknown bit may have been
@@ -3689,23 +3711,23 @@
         __ jccb(Assembler::notZero, next); // already unknown. Nothing to do anymore.
 
         if (TypeEntries::is_type_none(current_klass)) {
-          __ cmpptr(mdo_addr, 0);
-          __ jccb(Assembler::equal, none);
-          __ cmpptr(mdo_addr, TypeEntries::null_seen);
-          __ jccb(Assembler::equal, none);
+          __ testptr(mdo_addr, TypeEntries::type_mask);
+          __ jccb(Assembler::zero, none);
+#ifdef _LP64
           // There is a chance that the checks above (re-reading profiling
           // data from memory) fail if another thread has just set the
           // profiling to this obj's klass
+          __ mov(tmp, rscratch1); // get back original value before XOR
           __ xorptr(tmp, mdo_addr);
           __ testptr(tmp, TypeEntries::type_klass_mask);
           __ jccb(Assembler::zero, next);
+#endif
         }
       } else {
         assert(ciTypeEntries::valid_ciklass(current_klass) != NULL &&
                ciTypeEntries::valid_ciklass(current_klass) != exact_klass, "conflict only");
 
-        __ movptr(tmp, mdo_addr);
-        __ testptr(tmp, TypeEntries::type_unknown);
+        __ testptr(mdo_addr, TypeEntries::type_unknown);
         __ jccb(Assembler::notZero, next); // already unknown. Nothing to do anymore.
       }
 
@@ -3718,6 +3740,10 @@
         __ bind(none);
         // first time here. Set profile type.
         __ movptr(mdo_addr, tmp);
+#ifdef ASSERT
+        __ andptr(tmp, TypeEntries::type_klass_mask);
+        __ verify_klass_ptr(tmp);
+#endif
       }
     } else {
       // There's a single possible klass at this profile point
@@ -3732,10 +3758,8 @@
         {
           Label ok;
           __ push(tmp);
-          __ cmpptr(mdo_addr, 0);
-          __ jcc(Assembler::equal, ok);
-          __ cmpptr(mdo_addr, TypeEntries::null_seen);
-          __ jcc(Assembler::equal, ok);
+          __ testptr(mdo_addr, TypeEntries::type_mask);
+          __ jcc(Assembler::zero, ok);
           // may have been set by another thread
           __ mov_metadata(tmp, exact_klass->constant_encoding());
           __ xorptr(tmp, mdo_addr);
@@ -3751,20 +3775,22 @@
 #endif
         // first time here. Set profile type.
         __ movptr(mdo_addr, tmp);
+#ifdef ASSERT
+        __ andptr(tmp, TypeEntries::type_klass_mask);
+        __ verify_klass_ptr(tmp);
+#endif
       } else {
         assert(ciTypeEntries::valid_ciklass(current_klass) != NULL &&
                ciTypeEntries::valid_ciklass(current_klass) != exact_klass, "inconsistent");
 
-        __ movptr(tmp, mdo_addr);
-        __ testptr(tmp, TypeEntries::type_unknown);
+        __ testptr(mdo_addr, TypeEntries::type_unknown);
         __ jccb(Assembler::notZero, next); // already unknown. Nothing to do anymore.
 
         __ orptr(mdo_addr, TypeEntries::type_unknown);
       }
     }
-
-    __ bind(next);
   }
+  __ bind(next);
 }
 
 void LIR_Assembler::emit_delay(LIR_OpDelay*) {
diff --git a/src/hotspot/cpu/x86/interp_masm_x86.cpp b/src/hotspot/cpu/x86/interp_masm_x86.cpp
index d92885d..26c0777 100644
--- a/src/hotspot/cpu/x86/interp_masm_x86.cpp
+++ b/src/hotspot/cpu/x86/interp_masm_x86.cpp
@@ -52,16 +52,29 @@
 void InterpreterMacroAssembler::profile_obj_type(Register obj, const Address& mdo_addr) {
   Label update, next, none;
 
+#ifdef _LP64
+  assert_different_registers(obj, rscratch1, mdo_addr.base(), mdo_addr.index());
+#else
+  assert_different_registers(obj, mdo_addr.base(), mdo_addr.index());
+#endif
+
   interp_verify_oop(obj, atos);
 
   testptr(obj, obj);
   jccb(Assembler::notZero, update);
+  testptr(mdo_addr, TypeEntries::null_seen);
+  jccb(Assembler::notZero, next); // null already seen. Nothing to do anymore.
+  // atomic update to prevent overwriting Klass* with 0
+  lock();
   orptr(mdo_addr, TypeEntries::null_seen);
   jmpb(next);
 
   bind(update);
   Register tmp_load_klass = LP64_ONLY(rscratch1) NOT_LP64(noreg);
   load_klass(obj, obj, tmp_load_klass);
+#ifdef _LP64
+  mov(rscratch1, obj);
+#endif
 
   xorptr(obj, mdo_addr);
   testptr(obj, TypeEntries::type_klass_mask);
@@ -76,12 +89,15 @@
   jccb(Assembler::equal, none);
   cmpptr(mdo_addr, TypeEntries::null_seen);
   jccb(Assembler::equal, none);
+#ifdef _LP64
   // There is a chance that the checks above (re-reading profiling
   // data from memory) fail if another thread has just set the
   // profiling to this obj's klass
+  mov(obj, rscratch1);
   xorptr(obj, mdo_addr);
   testptr(obj, TypeEntries::type_klass_mask);
   jccb(Assembler::zero, next);
+#endif
 
   // different than before. Cannot keep accurate profile.
   orptr(mdo_addr, TypeEntries::type_unknown);
@@ -90,6 +106,10 @@
   bind(none);
   // first time here. Set profile type.
   movptr(mdo_addr, obj);
+#ifdef ASSERT
+  andptr(obj, TypeEntries::type_klass_mask);
+  verify_klass_ptr(obj);
+#endif
 
   bind(next);
 }
diff --git a/src/hotspot/cpu/x86/macroAssembler_x86.hpp b/src/hotspot/cpu/x86/macroAssembler_x86.hpp
index dc5c902..88c2b0c 100644
--- a/src/hotspot/cpu/x86/macroAssembler_x86.hpp
+++ b/src/hotspot/cpu/x86/macroAssembler_x86.hpp
@@ -825,6 +825,7 @@
 
   void testptr(Register src, int32_t imm32) {  LP64_ONLY(testq(src, imm32)) NOT_LP64(testl(src, imm32)); }
   void testptr(Register src1, Address src2) { LP64_ONLY(testq(src1, src2)) NOT_LP64(testl(src1, src2)); }
+  void testptr(Address src, int32_t imm32) {  LP64_ONLY(testq(src, imm32)) NOT_LP64(testl(src, imm32)); }
   void testptr(Register src1, Register src2);
 
   void xorptr(Register dst, Register src) { LP64_ONLY(xorq(dst, src)) NOT_LP64(xorl(dst, src)); }
diff --git a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp
index 163455c..9707738 100644
--- a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp
+++ b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -5966,7 +5966,7 @@
     const Register isURL = c_rarg5;// Base64 or URL character set
     __ movl(isMIME, Address(rbp, 2 * wordSize));
 #else
-    const Address  dp_mem(rbp, 6 * wordSize);  // length is on stack on Win64
+    const Address dp_mem(rbp, 6 * wordSize);  // length is on stack on Win64
     const Address isURL_mem(rbp, 7 * wordSize);
     const Register isURL = r10;      // pick the volatile windows register
     const Register dp = r12;
@@ -6188,10 +6188,12 @@
       // output_size in r13
 
       // Strip pad characters, if any, and adjust length and mask
+      __ addq(length, start_offset);
       __ cmpb(Address(source, length, Address::times_1, -1), '=');
       __ jcc(Assembler::equal, L_padding);
 
       __ BIND(L_donePadding);
+      __ subq(length, start_offset);
 
       // Output size is (64 - output_size), output mask is (all 1s >> output_size).
       __ kmovql(input_mask, rax);
diff --git a/src/hotspot/os/aix/attachListener_aix.cpp b/src/hotspot/os/aix/attachListener_aix.cpp
index 25dfe8d..461b7fc 100644
--- a/src/hotspot/os/aix/attachListener_aix.cpp
+++ b/src/hotspot/os/aix/attachListener_aix.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2012, 2018 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -28,7 +28,6 @@
 #include "runtime/interfaceSupport.inline.hpp"
 #include "runtime/os.inline.hpp"
 #include "services/attachListener.hpp"
-#include "services/dtraceAttacher.hpp"
 
 #include <signal.h>
 #include <sys/socket.h>
diff --git a/src/hotspot/os/bsd/attachListener_bsd.cpp b/src/hotspot/os/bsd/attachListener_bsd.cpp
index 9daad43..b8702c5 100644
--- a/src/hotspot/os/bsd/attachListener_bsd.cpp
+++ b/src/hotspot/os/bsd/attachListener_bsd.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,6 @@
 #include "runtime/interfaceSupport.inline.hpp"
 #include "runtime/os.inline.hpp"
 #include "services/attachListener.hpp"
-#include "services/dtraceAttacher.hpp"
 
 #include <unistd.h>
 #include <signal.h>
diff --git a/src/hotspot/os/linux/attachListener_linux.cpp b/src/hotspot/os/linux/attachListener_linux.cpp
index 628c3f1..0ce7672 100644
--- a/src/hotspot/os/linux/attachListener_linux.cpp
+++ b/src/hotspot/os/linux/attachListener_linux.cpp
@@ -28,7 +28,6 @@
 #include "runtime/interfaceSupport.inline.hpp"
 #include "runtime/os.inline.hpp"
 #include "services/attachListener.hpp"
-#include "services/dtraceAttacher.hpp"
 
 #include <unistd.h>
 #include <signal.h>
diff --git a/src/hotspot/os/linux/os_linux.cpp b/src/hotspot/os/linux/os_linux.cpp
index ace3a01..55918bd 100644
--- a/src/hotspot/os/linux/os_linux.cpp
+++ b/src/hotspot/os/linux/os_linux.cpp
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2015, 2022 SAP SE. All rights reserved.
+ * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2024 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -2091,7 +2091,6 @@
   "/etc/mandrake-release",
   "/etc/sun-release",
   "/etc/redhat-release",
-  "/etc/SuSE-release",
   "/etc/lsb-release",
   "/etc/turbolinux-release",
   "/etc/gentoo-release",
@@ -2099,6 +2098,7 @@
   "/etc/angstrom-version",
   "/etc/system-release",
   "/etc/os-release",
+  "/etc/SuSE-release", // Deprecated in favor of os-release since SuSE 12
   NULL };
 
 void os::Linux::print_distro_info(outputStream* st) {
@@ -2210,6 +2210,8 @@
   // https://www.kernel.org/doc/Documentation/vm/transhuge.txt
   _print_ascii_file_h("/sys/kernel/mm/transparent_hugepage/enabled",
                       "/sys/kernel/mm/transparent_hugepage/enabled", st);
+  _print_ascii_file_h("/sys/kernel/mm/transparent_hugepage/hpage_pmd_size",
+                      "/sys/kernel/mm/transparent_hugepage/hpage_pmd_size", st);
   _print_ascii_file_h("/sys/kernel/mm/transparent_hugepage/defrag (defrag/compaction efforts parameter)",
                       "/sys/kernel/mm/transparent_hugepage/defrag", st);
 }
diff --git a/src/hotspot/os/posix/os_posix.hpp b/src/hotspot/os/posix/os_posix.hpp
index 0556d84..c1f9601 100644
--- a/src/hotspot/os/posix/os_posix.hpp
+++ b/src/hotspot/os/posix/os_posix.hpp
@@ -25,6 +25,15 @@
 #ifndef OS_POSIX_OS_POSIX_HPP
 #define OS_POSIX_OS_POSIX_HPP
 
+// Note: the Posix API aims to capture functionality available on all Posix
+// compliant platforms, but in practice the implementations may depend on
+// non-Posix functionality. For example, the use of lseek64 and ftruncate64.
+// This use of non-Posix API's is made possible by compiling/linking in a mode
+// that is not restricted to being fully Posix complaint, such as by declaring
+// -D_GNU_SOURCE. But be aware that in doing so we may enable non-Posix
+// behaviour in API's that are defined by Posix. For example, that SIGSTKSZ
+// is not defined as a constant as of Glibc 2.34.
+
 // File conventions
 static const char* file_separator() { return "/"; }
 static const char* line_separator() { return "\n"; }
diff --git a/src/hotspot/os/windows/attachListener_windows.cpp b/src/hotspot/os/windows/attachListener_windows.cpp
index 8b5a2cb..710afc4 100644
--- a/src/hotspot/os/windows/attachListener_windows.cpp
+++ b/src/hotspot/os/windows/attachListener_windows.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,6 @@
 #include "runtime/interfaceSupport.inline.hpp"
 #include "runtime/os.hpp"
 #include "services/attachListener.hpp"
-#include "services/dtraceAttacher.hpp"
 
 #include <windows.h>
 #include <signal.h>             // SIGBREAK
diff --git a/src/hotspot/os/windows/globals_windows.hpp b/src/hotspot/os/windows/globals_windows.hpp
index 7ddf3c9..4e6eac3 100644
--- a/src/hotspot/os/windows/globals_windows.hpp
+++ b/src/hotspot/os/windows/globals_windows.hpp
@@ -37,7 +37,10 @@
                          constraint)                                      \
                                                                           \
 product(bool, UseOSErrorReporting, false,                                 \
-        "Let VM fatal error propagate to the OS (ie. WER on Windows)")
+        "Let VM fatal error propagate to the OS (ie. WER on Windows)")    \
+                                                                          \
+product(bool, UseCriticalSection, true, EXPERIMENTAL,                     \
+        "Use the critical section API instead of WaitForSingleObject")
 
 // end of RUNTIME_OS_FLAGS
 
diff --git a/src/hotspot/os/windows/threadCritical_windows.cpp b/src/hotspot/os/windows/threadCritical_windows.cpp
index b433309..c0c8163 100644
--- a/src/hotspot/os/windows/threadCritical_windows.cpp
+++ b/src/hotspot/os/windows/threadCritical_windows.cpp
@@ -39,6 +39,8 @@
 static int lock_count = 0;
 static HANDLE lock_event;
 static DWORD lock_owner = 0;
+static CRITICAL_SECTION critical_section;
+
 
 //
 // Note that Microsoft's critical region code contains a race
@@ -52,8 +54,13 @@
 //
 
 static BOOL WINAPI initialize(PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context) {
-  lock_event = CreateEvent(NULL, false, true, NULL);
-  assert(lock_event != NULL, "unexpected return value from CreateEvent");
+  if (UseCriticalSection) {
+    bool success = InitializeCriticalSectionAndSpinCount(&critical_section, 0x00000400);
+    assert(success, "unexpected return value from InitializeCriticalSectionAndSpinCount");
+  } else {
+    lock_event = CreateEvent(NULL, false, true, NULL);
+    assert(lock_event != NULL, "unexpected return value from CreateEvent");
+  }
   return true;
 }
 
@@ -62,9 +69,13 @@
 
   DWORD current_thread = GetCurrentThreadId();
   if (lock_owner != current_thread) {
-    // Grab the lock before doing anything.
-    DWORD ret = WaitForSingleObject(lock_event,  INFINITE);
-    assert(ret == WAIT_OBJECT_0, "unexpected return value from WaitForSingleObject");
+    if (UseCriticalSection) {
+      EnterCriticalSection(&critical_section);
+    } else {
+      // Grab the lock before doing anything.
+      DWORD ret = WaitForSingleObject(lock_event,  INFINITE);
+      assert(ret == WAIT_OBJECT_0, "unexpected return value from WaitForSingleObject");
+    }
     lock_owner = current_thread;
   }
   // Atomicity isn't required. Bump the recursion count.
@@ -79,8 +90,12 @@
   if (lock_count == 0) {
     // We're going to unlock
     lock_owner = 0;
-    // No lost wakeups, lock_event stays signaled until reset.
-    DWORD ret = SetEvent(lock_event);
-    assert(ret != 0, "unexpected return value from SetEvent");
+    if (UseCriticalSection) {
+      LeaveCriticalSection(&critical_section);
+    } else {
+      // No lost wakeups, lock_event stays signaled until reset.
+      DWORD ret = SetEvent(lock_event);
+      assert(ret != 0, "unexpected return value from SetEvent");
+    }
   }
 }
diff --git a/src/hotspot/os_cpu/bsd_aarch64/atomic_bsd_aarch64.hpp b/src/hotspot/os_cpu/bsd_aarch64/atomic_bsd_aarch64.hpp
index fba5987..5a88b1a 100644
--- a/src/hotspot/os_cpu/bsd_aarch64/atomic_bsd_aarch64.hpp
+++ b/src/hotspot/os_cpu/bsd_aarch64/atomic_bsd_aarch64.hpp
@@ -37,9 +37,13 @@
 struct Atomic::PlatformAdd {
   template<typename D, typename I>
   D add_and_fetch(D volatile* dest, I add_value, atomic_memory_order order) const {
-    D res = __atomic_add_fetch(dest, add_value, __ATOMIC_RELEASE);
-    FULL_MEM_BARRIER;
-    return res;
+    if (order == memory_order_relaxed) {
+      return __atomic_add_fetch(dest, add_value, __ATOMIC_RELAXED);
+    } else {
+      D res = __atomic_add_fetch(dest, add_value, __ATOMIC_RELEASE);
+      FULL_MEM_BARRIER;
+      return res;
+    }
   }
 
   template<typename D, typename I>
diff --git a/src/hotspot/os_cpu/linux_riscv/os_linux_riscv.cpp b/src/hotspot/os_cpu/linux_riscv/os_linux_riscv.cpp
index 06d704f..531ada1 100644
--- a/src/hotspot/os_cpu/linux_riscv/os_linux_riscv.cpp
+++ b/src/hotspot/os_cpu/linux_riscv/os_linux_riscv.cpp
@@ -231,7 +231,7 @@
         CompiledMethod* nm = (cb != NULL) ? cb->as_compiled_method_or_null() : NULL;
         bool is_unsafe_arraycopy = (thread->doing_unsafe_access() && UnsafeCopyMemory::contains_pc(pc));
         if ((nm != NULL && nm->has_unsafe_access()) || is_unsafe_arraycopy) {
-          address next_pc = pc + NativeCall::instruction_size;
+          address next_pc = Assembler::locate_next_instruction(pc);
           if (is_unsafe_arraycopy) {
             next_pc = UnsafeCopyMemory::page_error_continue_pc(pc);
           }
@@ -272,7 +272,7 @@
                 thread->thread_state() == _thread_in_native) &&
                 sig == SIGBUS && /* info->si_code == BUS_OBJERR && */
                 thread->doing_unsafe_access()) {
-      address next_pc = pc + NativeCall::instruction_size;
+      address next_pc = Assembler::locate_next_instruction(pc);
       if (UnsafeCopyMemory::contains_pc(pc)) {
         next_pc = UnsafeCopyMemory::page_error_continue_pc(pc);
       }
diff --git a/src/hotspot/os_cpu/linux_riscv/vm_version_linux_riscv.cpp b/src/hotspot/os_cpu/linux_riscv/vm_version_linux_riscv.cpp
index a701b9f..ddbb57a 100644
--- a/src/hotspot/os_cpu/linux_riscv/vm_version_linux_riscv.cpp
+++ b/src/hotspot/os_cpu/linux_riscv/vm_version_linux_riscv.cpp
@@ -168,13 +168,13 @@
 }
 
 VM_Version::VM_MODE VM_Version::parse_satp_mode(const char* vm_mode) {
-  if (!strcmp(vm_mode, "sv39")) {
+  if (!strncmp(vm_mode, "sv39", sizeof "sv39" - 1)) {
     return VM_SV39;
-  } else if (!strcmp(vm_mode, "sv48")) {
+  } else if (!strncmp(vm_mode, "sv48", sizeof "sv48" - 1)) {
     return VM_SV48;
-  } else if (!strcmp(vm_mode, "sv57")) {
+  } else if (!strncmp(vm_mode, "sv57", sizeof "sv57" - 1)) {
     return VM_SV57;
-  } else if (!strcmp(vm_mode, "sv64")) {
+  } else if (!strncmp(vm_mode, "sv64", sizeof "sv64" - 1)) {
     return VM_SV64;
   } else {
     return VM_MBARE;
@@ -196,7 +196,7 @@
     if ((p = strchr(buf, ':')) != nullptr) {
       if (mode == VM_NOTSET) {
         if (strncmp(buf, "mmu", sizeof "mmu" - 1) == 0) {
-          mode = VM_Version::parse_satp_mode(p);
+          mode = VM_Version::parse_satp_mode(p + 2);
         }
       }
       if (ret == nullptr) {
diff --git a/src/hotspot/share/adlc/output_c.cpp b/src/hotspot/share/adlc/output_c.cpp
index ea070e9..0a183ab 100644
--- a/src/hotspot/share/adlc/output_c.cpp
+++ b/src/hotspot/share/adlc/output_c.cpp
@@ -3034,6 +3034,9 @@
     fprintf(fp_cpp, "    if( i != cisc_operand() ) \n");
     fprintf(fp_cpp, "      to[i] = _opnds[i]->clone();\n");
     fprintf(fp_cpp, "  }\n");
+    fprintf(fp_cpp, "  // Do not increment node index counter, since node reuses my index\n");
+    fprintf(fp_cpp, "  Compile* C = Compile::current();\n");
+    fprintf(fp_cpp, "  C->set_unique(C->unique() - 1);\n");
     fprintf(fp_cpp, "}\n");
   }
   fprintf(fp_cpp, "\n");
diff --git a/src/hotspot/share/cds/filemap.cpp b/src/hotspot/share/cds/filemap.cpp
index 888e602..8a46f3e 100644
--- a/src/hotspot/share/cds/filemap.cpp
+++ b/src/hotspot/share/cds/filemap.cpp
@@ -365,7 +365,7 @@
   _from_class_path_attr = ent->_from_class_path_attr;
   set_name(ent->name(), CHECK);
 
-  if (ent->is_jar() && !ent->is_signed() && ent->manifest() != NULL) {
+  if (ent->is_jar() && ent->manifest() != NULL) {
     Array<u1>* buf = MetadataFactory::new_array<u1>(loader_data,
                                                     ent->manifest_size(),
                                                     CHECK);
@@ -633,29 +633,6 @@
     buf[len] = 0;
     return buf;
   }
-
-  // The return value indicates if the JAR is signed or not
-  bool check_is_signed() {
-    u1* attr = _current;
-    bool isSigned = false;
-    while (_current < _buffer_end) {
-      if (*_current == '\n') {
-        *_current = '\0';
-        u1* value = (u1*)strchr((char*)attr, ':');
-        if (value != NULL) {
-          assert(*(value+1) == ' ', "Unrecognized format" );
-          if (strstr((char*)attr, "-Digest") != NULL) {
-            isSigned = true;
-            break;
-          }
-        }
-        *_current = '\n'; // restore
-        attr = _current + 1;
-      }
-      _current ++;
-    }
-    return isSigned;
-  }
 };
 
 void FileMapInfo::update_jar_manifest(ClassPathEntry *cpe, SharedClassPathEntry* ent, TRAPS) {
@@ -668,18 +645,14 @@
   if (manifest != NULL) {
     ManifestStream* stream = new ManifestStream((u1*)manifest,
                                                 manifest_size);
-    if (stream->check_is_signed()) {
-      ent->set_is_signed();
-    } else {
-      // Copy the manifest into the shared archive
-      manifest = ClassLoaderExt::read_raw_manifest(THREAD, cpe, &manifest_size);
-      Array<u1>* buf = MetadataFactory::new_array<u1>(loader_data,
-                                                      manifest_size,
-                                                      CHECK);
-      char* p = (char*)(buf->data());
-      memcpy(p, manifest, manifest_size);
-      ent->set_manifest(buf);
-    }
+    // Copy the manifest into the shared archive
+    manifest = ClassLoaderExt::read_raw_manifest(THREAD, cpe, &manifest_size);
+    Array<u1>* buf = MetadataFactory::new_array<u1>(loader_data,
+                                                    manifest_size,
+                                                    CHECK);
+    char* p = (char*)(buf->data());
+    memcpy(p, manifest, manifest_size);
+    ent->set_manifest(buf);
   }
 }
 
diff --git a/src/hotspot/share/cds/filemap.hpp b/src/hotspot/share/cds/filemap.hpp
index 9dc2b23..d12aa4c 100644
--- a/src/hotspot/share/cds/filemap.hpp
+++ b/src/hotspot/share/cds/filemap.hpp
@@ -49,7 +49,6 @@
   enum {
     modules_image_entry,
     jar_entry,
-    signed_jar_entry,
     dir_entry,
     non_existent_entry,
     unknown_entry
@@ -78,10 +77,6 @@
   bool is_dir()           const { return _type == dir_entry; }
   bool is_modules_image() const { return _type == modules_image_entry; }
   bool is_jar()           const { return _type == jar_entry; }
-  bool is_signed()        const { return _type == signed_jar_entry; }
-  void set_is_signed() {
-    _type = signed_jar_entry;
-  }
   bool from_class_path_attr() { return _from_class_path_attr; }
   time_t timestamp() const { return _timestamp; }
   const char* name() const;
diff --git a/src/hotspot/share/classfile/classLoaderData.cpp b/src/hotspot/share/classfile/classLoaderData.cpp
index f5665ad..c8cad36 100644
--- a/src/hotspot/share/classfile/classLoaderData.cpp
+++ b/src/hotspot/share/classfile/classLoaderData.cpp
@@ -970,7 +970,11 @@
     _holder.print_on(out);
     out->print_cr("");
   }
-  out->print_cr(" - class loader        " INTPTR_FORMAT, p2i(_class_loader.ptr_raw()));
+  if (!_unloading) {
+    out->print_cr(" - class loader        " INTPTR_FORMAT, p2i(_class_loader.peek()));
+  } else {
+    out->print_cr(" - class loader        <unloading, oop is bad>");
+  }
   out->print_cr(" - metaspace           " INTPTR_FORMAT, p2i(_metaspace));
   out->print_cr(" - unloading           %s", _unloading ? "true" : "false");
   out->print_cr(" - class mirror holder %s", _has_class_mirror_holder ? "true" : "false");
diff --git a/src/hotspot/share/classfile/javaClasses.cpp b/src/hotspot/share/classfile/javaClasses.cpp
index ccd3dc4..8dd8943 100644
--- a/src/hotspot/share/classfile/javaClasses.cpp
+++ b/src/hotspot/share/classfile/javaClasses.cpp
@@ -2079,18 +2079,17 @@
   return throwable->obj_field(_detailMessage_offset);
 }
 
-oop java_lang_Throwable::cause(oop throwable) {
-  return throwable->obj_field(_cause_offset);
+const char* java_lang_Throwable::message_as_utf8(oop throwable) {
+  oop msg = java_lang_Throwable::message(throwable);
+  const char* msg_utf8 = nullptr;
+  if (msg != nullptr) {
+    msg_utf8 = java_lang_String::as_utf8_string(msg);
+  }
+  return msg_utf8;
 }
 
-// Return Symbol for detailed_message or NULL
-Symbol* java_lang_Throwable::detail_message(oop throwable) {
-  PreserveExceptionMark pm(Thread::current());
-  oop detailed_message = java_lang_Throwable::message(throwable);
-  if (detailed_message != NULL) {
-    return java_lang_String::as_symbol(detailed_message);
-  }
-  return NULL;
+oop java_lang_Throwable::cause(oop throwable) {
+  return throwable->obj_field(_cause_offset);
 }
 
 void java_lang_Throwable::set_message(oop throwable, oop value) {
@@ -2744,15 +2743,19 @@
   assert(throwable.not_null(), "shouldn't be");
 
   // Now create the message from the original exception and thread name.
-  Symbol* message = java_lang_Throwable::detail_message(throwable());
   ResourceMark rm(current);
   stringStream st;
+  const char *message = nullptr;
+  oop detailed_message = java_lang_Throwable::message(throwable());
+  if (detailed_message != nullptr) {
+    message = java_lang_String::as_utf8_string(detailed_message);
+  }
   st.print("Exception %s%s ", throwable()->klass()->name()->as_klass_external_name(),
              message == nullptr ? "" : ":");
-  if (message == NULL) {
+  if (message == nullptr) {
     st.print("[in thread \"%s\"]", current->name());
   } else {
-    st.print("%s [in thread \"%s\"]", message->as_C_string(), current->name());
+    st.print("%s [in thread \"%s\"]", message, current->name());
   }
 
   Symbol* exception_name = vmSymbols::java_lang_ExceptionInInitializerError();
diff --git a/src/hotspot/share/classfile/javaClasses.hpp b/src/hotspot/share/classfile/javaClasses.hpp
index 2f90b54..bce0f53 100644
--- a/src/hotspot/share/classfile/javaClasses.hpp
+++ b/src/hotspot/share/classfile/javaClasses.hpp
@@ -553,12 +553,14 @@
   static void set_backtrace(oop throwable, oop value);
   static int depth(oop throwable);
   static void set_depth(oop throwable, int value);
-  static int get_detailMessage_offset() { CHECK_INIT(_detailMessage_offset); }
   // Message
+  static int get_detailMessage_offset() { CHECK_INIT(_detailMessage_offset); }
   static oop message(oop throwable);
-  static oop cause(oop throwable);
+  static const char* message_as_utf8(oop throwable);
   static void set_message(oop throwable, oop value);
-  static Symbol* detail_message(oop throwable);
+
+  static oop cause(oop throwable);
+
   static void print_stack_element(outputStream *st, Method* method, int bci);
 
   static void compute_offsets();
diff --git a/src/hotspot/share/classfile/resolutionErrors.cpp b/src/hotspot/share/classfile/resolutionErrors.cpp
index 24a5bca..4e64787 100644
--- a/src/hotspot/share/classfile/resolutionErrors.cpp
+++ b/src/hotspot/share/classfile/resolutionErrors.cpp
@@ -36,8 +36,8 @@
 // create new error entry
 void ResolutionErrorTable::add_entry(int index, unsigned int hash,
                                      const constantPoolHandle& pool, int cp_index,
-                                     Symbol* error, Symbol* message,
-                                     Symbol* cause, Symbol* cause_msg)
+                                     Symbol* error, const char* message,
+                                     Symbol* cause, const char* cause_msg)
 {
   assert_locked_or_safepoint(SystemDictionary_lock);
   assert(!pool.is_null() && error != NULL, "adding NULL obj");
@@ -95,11 +95,8 @@
   }
 }
 
-void ResolutionErrorEntry::set_message(Symbol* c) {
-  _message = c;
-  if (_message != NULL) {
-    _message->increment_refcount();
-  }
+void ResolutionErrorEntry::set_message(const char* c) {
+  _message = c != nullptr ? os::strdup(c) : nullptr;
 }
 
 void ResolutionErrorEntry::set_cause(Symbol* c) {
@@ -109,13 +106,11 @@
   }
 }
 
-void ResolutionErrorEntry::set_cause_msg(Symbol* c) {
-  _cause_msg = c;
-  if (_cause_msg != NULL) {
-    _cause_msg->increment_refcount();
-  }
+void ResolutionErrorEntry::set_cause_msg(const char* c) {
+  _cause_msg = c != nullptr ? os::strdup(c) : nullptr;
 }
 
+// The incoming nest host error message is already in the C-Heap.
 void ResolutionErrorEntry::set_nest_host_error(const char* message) {
   _nest_host_error = message;
 }
@@ -126,13 +121,13 @@
     entry->error()->decrement_refcount();
   }
   if (entry->message() != NULL) {
-    entry->message()->decrement_refcount();
+    FREE_C_HEAP_ARRAY(char, entry->message());
   }
   if (entry->cause() != NULL) {
     entry->cause()->decrement_refcount();
   }
   if (entry->cause_msg() != NULL) {
-    entry->cause_msg()->decrement_refcount();
+    FREE_C_HEAP_ARRAY(char, entry->cause_msg());
   }
   if (entry->nest_host_error() != NULL) {
     FREE_C_HEAP_ARRAY(char, entry->nest_host_error());
diff --git a/src/hotspot/share/classfile/resolutionErrors.hpp b/src/hotspot/share/classfile/resolutionErrors.hpp
index 8a9c995..31a5638 100644
--- a/src/hotspot/share/classfile/resolutionErrors.hpp
+++ b/src/hotspot/share/classfile/resolutionErrors.hpp
@@ -61,11 +61,11 @@
   }
 
   void add_entry(int index, unsigned int hash,
-                 const constantPoolHandle& pool, int which, Symbol* error, Symbol* message,
-                 Symbol* cause, Symbol* cause_msg);
+                 const constantPoolHandle& pool, int cp_index, Symbol* error, const char* error_msg,
+                 Symbol* cause, const char* cause_msg);
 
   void add_entry(int index, unsigned int hash,
-                 const constantPoolHandle& pool, int which, const char* message);
+                 const constantPoolHandle& pool, int cp_index, const char* message);
 
   // find error given the constant pool and constant pool index
   ResolutionErrorEntry* find_entry(int index, unsigned int hash,
@@ -96,9 +96,9 @@
  private:
   int               _cp_index;
   Symbol*           _error;
-  Symbol*           _message;
+  const char*       _message;
   Symbol*           _cause;
-  Symbol*           _cause_msg;
+  const char*       _cause_msg;
   const char*       _nest_host_error;
 
  public:
@@ -110,16 +110,19 @@
   Symbol*            error() const              { return _error; }
   void               set_error(Symbol* e);
 
-  Symbol*            message() const            { return _message; }
-  void               set_message(Symbol* c);
+  const char*        message() const            { return _message; }
+  // The incoming message is copied to the C-Heap.
+  void               set_message(const char* c);
 
   Symbol*            cause() const              { return _cause; }
   void               set_cause(Symbol* c);
 
-  Symbol*            cause_msg() const          { return _cause_msg; }
-  void               set_cause_msg(Symbol* c);
+  const char*        cause_msg() const          { return _cause_msg; }
+  // The incoming cause_msg is copied to the C-Heap.
+  void               set_cause_msg(const char* c);
 
   const char*        nest_host_error() const    { return _nest_host_error; }
+  // The incoming nest host error message is already in the C-Heap.
   void               set_nest_host_error(const char* message);
 
   ResolutionErrorEntry* next() const {
diff --git a/src/hotspot/share/classfile/systemDictionary.cpp b/src/hotspot/share/classfile/systemDictionary.cpp
index 420e6f3..6f02814 100644
--- a/src/hotspot/share/classfile/systemDictionary.cpp
+++ b/src/hotspot/share/classfile/systemDictionary.cpp
@@ -572,7 +572,6 @@
 void SystemDictionary::post_class_load_event(EventClassLoad* event, const InstanceKlass* k, const ClassLoaderData* init_cld) {
   assert(event != NULL, "invariant");
   assert(k != NULL, "invariant");
-  assert(event->should_commit(), "invariant");
   event->set_loadedClass(k);
   event->set_definingClassLoader(k->class_loader_data());
   event->set_initiatingClassLoader(init_cld);
@@ -1888,8 +1887,8 @@
 // Add entry to resolution error table to record the error when the first
 // attempt to resolve a reference to a class has failed.
 void SystemDictionary::add_resolution_error(const constantPoolHandle& pool, int which,
-                                            Symbol* error, Symbol* message,
-                                            Symbol* cause, Symbol* cause_msg) {
+                                            Symbol* error, const char* message,
+                                            Symbol* cause, const char* cause_msg) {
   unsigned int hash = resolution_errors()->compute_hash(pool, which);
   int index = resolution_errors()->hash_to_index(hash);
   {
@@ -1908,7 +1907,7 @@
 
 // Lookup resolution error table. Returns error if found, otherwise NULL.
 Symbol* SystemDictionary::find_resolution_error(const constantPoolHandle& pool, int which,
-                                                Symbol** message, Symbol** cause, Symbol** cause_msg) {
+                                                const char** message, Symbol** cause, const char** cause_msg) {
   unsigned int hash = resolution_errors()->compute_hash(pool, which);
   int index = resolution_errors()->hash_to_index(hash);
   {
diff --git a/src/hotspot/share/classfile/systemDictionary.hpp b/src/hotspot/share/classfile/systemDictionary.hpp
index 65185a2..4acee8e 100644
--- a/src/hotspot/share/classfile/systemDictionary.hpp
+++ b/src/hotspot/share/classfile/systemDictionary.hpp
@@ -288,10 +288,10 @@
   // Record the error when the first attempt to resolve a reference from a constant
   // pool entry to a class fails.
   static void add_resolution_error(const constantPoolHandle& pool, int which, Symbol* error,
-                                   Symbol* message, Symbol* cause = NULL, Symbol* cause_msg = NULL);
+                                   const char* message, Symbol* cause = NULL, const char* cause_msg = NULL);
   static void delete_resolution_error(ConstantPool* pool);
   static Symbol* find_resolution_error(const constantPoolHandle& pool, int which,
-                                       Symbol** message, Symbol** cause, Symbol** cause_msg);
+                                       const char** message, Symbol** cause, const char** cause_msg);
 
 
   // Record a nest host resolution/validation error
diff --git a/src/hotspot/share/code/icBuffer.cpp b/src/hotspot/share/code/icBuffer.cpp
index c30f4a3..bf7e913 100644
--- a/src/hotspot/share/code/icBuffer.cpp
+++ b/src/hotspot/share/code/icBuffer.cpp
@@ -140,7 +140,7 @@
 
 void InlineCacheBuffer::initialize() {
   if (_buffer != NULL) return; // already initialized
-  _buffer = new StubQueue(new ICStubInterface, 10*K, InlineCacheBuffer_lock, "InlineCacheBuffer");
+  _buffer = new StubQueue(new ICStubInterface, checked_cast<int>(InlineCacheBufferSize), InlineCacheBuffer_lock, "InlineCacheBuffer");
   assert (_buffer != NULL, "cannot allocate InlineCacheBuffer");
 }
 
diff --git a/src/hotspot/share/code/nmethod.cpp b/src/hotspot/share/code/nmethod.cpp
index 5105117..eef8e6b 100644
--- a/src/hotspot/share/code/nmethod.cpp
+++ b/src/hotspot/share/code/nmethod.cpp
@@ -389,6 +389,7 @@
 }
 
 void PcDescCache::add_pc_desc(PcDesc* pc_desc) {
+  MACOS_AARCH64_ONLY(ThreadWXEnable wx(WXWrite, Thread::current());)
   NOT_PRODUCT(++pc_nmethod_stats.pc_desc_adds);
   // Update the LRU cache by shifting pc_desc forward.
   for (int i = 0; i < cache_size; i++)  {
@@ -2929,9 +2930,6 @@
                                                                   AbstractDisassembler::show_block_comment());
 #endif
 
-  // Decoding an nmethod can write to a PcDescCache (see PcDescCache::add_pc_desc)
-  MACOS_AARCH64_ONLY(ThreadWXEnable wx(WXWrite, Thread::current());)
-
   st->cr();
   this->print(st);
   st->cr();
diff --git a/src/hotspot/share/code/stubs.cpp b/src/hotspot/share/code/stubs.cpp
index d022bf1..2c48ae4 100644
--- a/src/hotspot/share/code/stubs.cpp
+++ b/src/hotspot/share/code/stubs.cpp
@@ -214,8 +214,6 @@
   guarantee(0 <= _queue_begin  && _queue_begin  <  _buffer_limit, "_queue_begin out of bounds");
   guarantee(0 <= _queue_end    && _queue_end    <= _buffer_limit, "_queue_end   out of bounds");
   // verify alignment
-  guarantee(_buffer_size  % CodeEntryAlignment == 0, "_buffer_size  not aligned");
-  guarantee(_buffer_limit % CodeEntryAlignment == 0, "_buffer_limit not aligned");
   guarantee(_queue_begin  % CodeEntryAlignment == 0, "_queue_begin  not aligned");
   guarantee(_queue_end    % CodeEntryAlignment == 0, "_queue_end    not aligned");
   // verify buffer limit/size relationship
diff --git a/src/hotspot/share/compiler/compilerDefinitions.cpp b/src/hotspot/share/compiler/compilerDefinitions.cpp
index 0ddfd6f..f7cc633 100644
--- a/src/hotspot/share/compiler/compilerDefinitions.cpp
+++ b/src/hotspot/share/compiler/compilerDefinitions.cpp
@@ -466,6 +466,11 @@
                 "Invalid NonNMethodCodeHeapSize=%dK. Must be at least %uK.\n", NonNMethodCodeHeapSize/K,
                 min_code_cache_size/K);
     status = false;
+  } else if (InlineCacheBufferSize > NonNMethodCodeHeapSize / 2) {
+    jio_fprintf(defaultStream::error_stream(),
+                "Invalid InlineCacheBufferSize=" SIZE_FORMAT "K. Must be less than or equal to " SIZE_FORMAT "K.\n",
+                InlineCacheBufferSize/K, NonNMethodCodeHeapSize/2/K);
+    status = false;
   }
 
 #ifdef _LP64
diff --git a/src/hotspot/share/gc/serial/defNewGeneration.cpp b/src/hotspot/share/gc/serial/defNewGeneration.cpp
index 7ff1f97..846444b 100644
--- a/src/hotspot/share/gc/serial/defNewGeneration.cpp
+++ b/src/hotspot/share/gc/serial/defNewGeneration.cpp
@@ -845,9 +845,6 @@
     } else if (seen_incremental_collection_failed) {
       log_trace(gc)("DefNewEpilogue: cause(%s), not full, seen_failed, will_clear_seen_failed",
                             GCCause::to_string(gch->gc_cause()));
-      assert(gch->gc_cause() == GCCause::_scavenge_alot ||
-             !gch->incremental_collection_failed(),
-             "Twice in a row");
       seen_incremental_collection_failed = false;
     }
 #endif // ASSERT
diff --git a/src/hotspot/share/gc/shared/pretouchTask.cpp b/src/hotspot/share/gc/shared/pretouchTask.cpp
index a653ab8..8b41c00 100644
--- a/src/hotspot/share/gc/shared/pretouchTask.cpp
+++ b/src/hotspot/share/gc/shared/pretouchTask.cpp
@@ -36,7 +36,6 @@
                            size_t chunk_size) :
     AbstractGangTask(task_name),
     _cur_addr(start_address),
-    _start_addr(start_address),
     _end_addr(end_address),
     _page_size(page_size),
     _chunk_size(chunk_size) {
@@ -52,14 +51,13 @@
 
 void PretouchTask::work(uint worker_id) {
   while (true) {
-    char* touch_addr = Atomic::fetch_and_add(&_cur_addr, _chunk_size);
-    if (touch_addr < _start_addr || touch_addr >= _end_addr) {
+    char* cur_start = Atomic::load(&_cur_addr);
+    char* cur_end = cur_start + MIN2(_chunk_size, pointer_delta(_end_addr, cur_start, 1));
+    if (cur_start >= cur_end) {
       break;
-    }
-
-    char* end_addr = touch_addr + MIN2(_chunk_size, pointer_delta(_end_addr, touch_addr, sizeof(char)));
-
-    os::pretouch_memory(touch_addr, end_addr, _page_size);
+    } else if (cur_start == Atomic::cmpxchg(&_cur_addr, cur_start, cur_end)) {
+      os::pretouch_memory(cur_start, cur_end, _page_size);
+    } // Else attempt to claim chunk failed, so try again.
   }
 }
 
diff --git a/src/hotspot/share/gc/shared/pretouchTask.hpp b/src/hotspot/share/gc/shared/pretouchTask.hpp
index 49cd48d..c688322 100644
--- a/src/hotspot/share/gc/shared/pretouchTask.hpp
+++ b/src/hotspot/share/gc/shared/pretouchTask.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,7 +29,6 @@
 
 class PretouchTask : public AbstractGangTask {
   char* volatile _cur_addr;
-  char* const _start_addr;
   char* const _end_addr;
   size_t _page_size;
   size_t _chunk_size;
diff --git a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp
index ef848e7..ac13cf2 100644
--- a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp
+++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp
@@ -62,6 +62,7 @@
       C->clear_major_progress();
 
       C->process_for_post_loop_opts_igvn(igvn);
+      if (C->failing()) return false;
     }
     C->set_post_loop_opts_phase(); // now for real!
   }
diff --git a/src/hotspot/share/gc/shenandoah/shenandoahDegeneratedGC.cpp b/src/hotspot/share/gc/shenandoah/shenandoahDegeneratedGC.cpp
index 0fbffc5..7e0d68d 100644
--- a/src/hotspot/share/gc/shenandoah/shenandoahDegeneratedGC.cpp
+++ b/src/hotspot/share/gc/shenandoah/shenandoahDegeneratedGC.cpp
@@ -131,6 +131,27 @@
       // and we can do evacuation. Otherwise, it would be the shortcut cycle.
       if (heap->is_evacuation_in_progress()) {
 
+        if (_degen_point == _degenerated_evac) {
+          // Degeneration under oom-evac protocol allows the mutator LRB to expose
+          // references to from-space objects. This is okay, in theory, because we
+          // will come to the safepoint here to complete the evacuations and update
+          // the references. However, if the from-space reference is written to a
+          // region that was EC during final mark or was recycled after final mark
+          // it will not have TAMS or UWM updated. Such a region is effectively
+          // skipped during update references which can lead to crashes and corruption
+          // if the from-space reference is accessed.
+          if (UseTLAB) {
+            heap->labs_make_parsable();
+          }
+
+          for (size_t i = 0; i < heap->num_regions(); i++) {
+            ShenandoahHeapRegion* r = heap->get_region(i);
+            if (r->is_active() && r->top() > r->get_update_watermark()) {
+              r->set_update_watermark_at_safepoint(r->top());
+            }
+          }
+        }
+
         // Degeneration under oom-evac protocol might have left some objects in
         // collection set un-evacuated. Restart evacuation from the beginning to
         // capture all objects. For all the objects that are already evacuated,
diff --git a/src/hotspot/share/gc/shenandoah/shenandoahFullGC.cpp b/src/hotspot/share/gc/shenandoah/shenandoahFullGC.cpp
index 26c3135..d0cc794 100644
--- a/src/hotspot/share/gc/shenandoah/shenandoahFullGC.cpp
+++ b/src/hotspot/share/gc/shenandoah/shenandoahFullGC.cpp
@@ -908,6 +908,9 @@
     // Make empty regions that have been allocated into regular
     if (r->is_empty() && live > 0) {
       r->make_regular_bypass();
+      if (ZapUnusedHeapArea) {
+        SpaceMangler::mangle_region(MemRegion(r->top(), r->end()));
+      }
     }
 
     // Reclaim regular regions that became empty
diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp
index 1bf24c7..42d3391 100644
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp
@@ -465,6 +465,7 @@
   _num_regions(0),
   _regions(NULL),
   _update_refs_iterator(this),
+  _gc_state_changed(false),
   _control_thread(NULL),
   _shenandoah_policy(policy),
   _gc_mode(NULL),
@@ -1701,16 +1702,21 @@
   _update_refs_iterator.reset();
 }
 
-void ShenandoahHeap::set_gc_state_all_threads(char state) {
-  for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
-    ShenandoahThreadLocalData::set_gc_state(t, state);
+void ShenandoahHeap::set_gc_state_all_threads() {
+  assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at Shenandoah safepoint");
+  if (_gc_state_changed) {
+    _gc_state_changed = false;
+    char state = gc_state();
+    for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
+      ShenandoahThreadLocalData::set_gc_state(t, state);
+    }
   }
 }
 
 void ShenandoahHeap::set_gc_state_mask(uint mask, bool value) {
-  assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Should really be Shenandoah safepoint");
+  assert(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "Must be at Shenandoah safepoint");
   _gc_state.set_cond(mask, value);
-  set_gc_state_all_threads(_gc_state.raw_value());
+  _gc_state_changed = true;
 }
 
 void ShenandoahHeap::set_concurrent_mark_in_progress(bool in_progress) {
@@ -1872,10 +1878,6 @@
   return (address) ShenandoahHeap::heap()->_cancelled_gc.addr_of();
 }
 
-address ShenandoahHeap::gc_state_addr() {
-  return (address) ShenandoahHeap::heap()->_gc_state.addr_of();
-}
-
 size_t ShenandoahHeap::bytes_allocated_since_gc_start() {
   return Atomic::load(&_bytes_allocated_since_gc_start);
 }
diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp
index 588cb13..bf2125b 100644
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp
@@ -122,6 +122,7 @@
   friend class ShenandoahGCStateResetter;
   friend class ShenandoahParallelObjectIterator;
   friend class ShenandoahSafepoint;
+
   // Supported GC
   friend class ShenandoahConcurrentGC;
   friend class ShenandoahDegenGC;
@@ -280,6 +281,7 @@
   };
 
 private:
+  bool _gc_state_changed;
   ShenandoahSharedBitmap _gc_state;
   ShenandoahSharedFlag   _degenerated_gc_in_progress;
   ShenandoahSharedFlag   _full_gc_in_progress;
@@ -287,12 +289,12 @@
   ShenandoahSharedFlag   _progress_last_gc;
   ShenandoahSharedFlag   _concurrent_strong_root_in_progress;
 
-  void set_gc_state_all_threads(char state);
   void set_gc_state_mask(uint mask, bool value);
 
 public:
   char gc_state() const;
-  static address gc_state_addr();
+  void set_gc_state_all_threads();
+  bool has_gc_state_changed() { return _gc_state_changed; }
 
   void set_concurrent_mark_in_progress(bool in_progress);
   void set_evacuation_in_progress(bool in_progress);
diff --git a/src/hotspot/share/gc/shenandoah/shenandoahReferenceProcessor.cpp b/src/hotspot/share/gc/shenandoah/shenandoahReferenceProcessor.cpp
index e843f3b..a25487f 100644
--- a/src/hotspot/share/gc/shenandoah/shenandoahReferenceProcessor.cpp
+++ b/src/hotspot/share/gc/shenandoah/shenandoahReferenceProcessor.cpp
@@ -362,7 +362,7 @@
 
   log_trace(gc, ref)("Encountered Reference: " PTR_FORMAT " (%s)", p2i(reference), reference_type_name(type));
   uint worker_id = ShenandoahThreadLocalData::worker_id(Thread::current());
-  _ref_proc_thread_locals->inc_encountered(type);
+  _ref_proc_thread_locals[worker_id].inc_encountered(type);
 
   if (UseCompressedOops) {
     return discover<narrowOop>(reference, type, worker_id);
diff --git a/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.cpp b/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.cpp
index d6be092..970f99a 100644
--- a/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.cpp
+++ b/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.cpp
@@ -32,14 +32,27 @@
 #include "gc/shenandoah/shenandoahOopClosures.inline.hpp"
 #include "gc/shenandoah/shenandoahUtils.hpp"
 #include "gc/shenandoah/shenandoahVMOperations.hpp"
+#include "interpreter/oopMapCache.hpp"
 #include "memory/universe.hpp"
 
+bool VM_ShenandoahOperation::doit_prologue() {
+  assert(!ShenandoahHeap::heap()->has_gc_state_changed(), "GC State can only be changed on a safepoint.");
+  return true;
+}
+
+void VM_ShenandoahOperation::doit_epilogue() {
+  assert(!ShenandoahHeap::heap()->has_gc_state_changed(), "GC State was not synchronized to java threads.");
+}
+
 bool VM_ShenandoahReferenceOperation::doit_prologue() {
+  VM_ShenandoahOperation::doit_prologue();
   Heap_lock->lock();
   return true;
 }
 
 void VM_ShenandoahReferenceOperation::doit_epilogue() {
+  VM_ShenandoahOperation::doit_epilogue();
+  OopMapCache::cleanup_old_entries();
   if (Universe::has_reference_pending_list()) {
     Heap_lock->notify_all();
   }
@@ -49,34 +62,41 @@
 void VM_ShenandoahInitMark::doit() {
   ShenandoahGCPauseMark mark(_gc_id, "Init Mark", SvcGCMarker::CONCURRENT);
   _gc->entry_init_mark();
+  ShenandoahHeap::heap()->set_gc_state_all_threads();
 }
 
 void VM_ShenandoahFinalMarkStartEvac::doit() {
   ShenandoahGCPauseMark mark(_gc_id, "Final Mark", SvcGCMarker::CONCURRENT);
   _gc->entry_final_mark();
+  ShenandoahHeap::heap()->set_gc_state_all_threads();
 }
 
 void VM_ShenandoahFullGC::doit() {
   ShenandoahGCPauseMark mark(_gc_id, "Full GC", SvcGCMarker::FULL);
   _full_gc->entry_full(_gc_cause);
+  ShenandoahHeap::heap()->set_gc_state_all_threads();
 }
 
 void VM_ShenandoahDegeneratedGC::doit() {
   ShenandoahGCPauseMark mark(_gc_id, "Degenerated GC", SvcGCMarker::CONCURRENT);
   _gc->entry_degenerated();
+  ShenandoahHeap::heap()->set_gc_state_all_threads();
 }
 
 void VM_ShenandoahInitUpdateRefs::doit() {
   ShenandoahGCPauseMark mark(_gc_id, "Init Update Refs", SvcGCMarker::CONCURRENT);
   _gc->entry_init_updaterefs();
+  ShenandoahHeap::heap()->set_gc_state_all_threads();
 }
 
 void VM_ShenandoahFinalUpdateRefs::doit() {
   ShenandoahGCPauseMark mark(_gc_id, "Final Update Refs", SvcGCMarker::CONCURRENT);
   _gc->entry_final_updaterefs();
+  ShenandoahHeap::heap()->set_gc_state_all_threads();
 }
 
 void VM_ShenandoahFinalRoots::doit() {
   ShenandoahGCPauseMark mark(_gc_id, "Final Roots", SvcGCMarker::CONCURRENT);
   _gc->entry_final_roots();
+  ShenandoahHeap::heap()->set_gc_state_all_threads();
 }
diff --git a/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.hpp b/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.hpp
index 65ddd8b..1b78766 100644
--- a/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.hpp
+++ b/src/hotspot/share/gc/shenandoah/shenandoahVMOperations.hpp
@@ -47,14 +47,16 @@
   uint         _gc_id;
 public:
   VM_ShenandoahOperation() : _gc_id(GCId::current()) {};
-  virtual bool skip_thread_oop_barriers() const { return true; }
+  bool skip_thread_oop_barriers() const override { return true; }
+  bool doit_prologue() override;
+  void doit_epilogue() override;
 };
 
 class VM_ShenandoahReferenceOperation : public VM_ShenandoahOperation {
 public:
   VM_ShenandoahReferenceOperation() : VM_ShenandoahOperation() {};
-  bool doit_prologue();
-  void doit_epilogue();
+  bool doit_prologue() override;
+  void doit_epilogue() override;
 };
 
 class VM_ShenandoahInitMark: public VM_ShenandoahOperation {
diff --git a/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp b/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp
index 4748688..99be9bd 100644
--- a/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp
+++ b/src/hotspot/share/gc/shenandoah/shenandoahVerifier.cpp
@@ -619,6 +619,8 @@
   guarantee(ShenandoahSafepoint::is_at_shenandoah_safepoint(), "only when nothing else happens");
   guarantee(ShenandoahVerify, "only when enabled, and bitmap is initialized in ShenandoahHeap::initialize");
 
+  ShenandoahHeap::heap()->set_gc_state_all_threads();
+
   // Avoid side-effect of changing workers' active thread count, but bypass concurrent/parallel protocol check
   ShenandoahPushWorkerScope verify_worker_scope(_heap->workers(), _heap->max_workers(), false /*bypass check*/);
 
diff --git a/src/hotspot/share/include/jmm.h b/src/hotspot/share/include/jmm.h
index ee1c77e..c983dbf 100644
--- a/src/hotspot/share/include/jmm.h
+++ b/src/hotspot/share/include/jmm.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -316,7 +316,8 @@
   void         (JNICALL *SetVMGlobal)            (JNIEnv *env,
                                                   jstring flag_name,
                                                   jvalue  new_value);
-  void*        reserved6;
+  jlong        (JNICALL *GetTotalThreadAllocatedMemory)
+                                                 (JNIEnv *env);
   jobjectArray (JNICALL *DumpThreads)            (JNIEnv *env,
                                                   jlongArray ids,
                                                   jboolean lockedMonitors,
diff --git a/src/hotspot/share/jfr/jni/jfrJniMethod.cpp b/src/hotspot/share/jfr/jni/jfrJniMethod.cpp
index 1ed22ee..d93ddc0 100644
--- a/src/hotspot/share/jfr/jni/jfrJniMethod.cpp
+++ b/src/hotspot/share/jfr/jni/jfrJniMethod.cpp
@@ -270,19 +270,17 @@
   JfrRepository::set_chunk_path(path, thread);
 JVM_END
 
-JVM_ENTRY_NO_ENV(void, jfr_set_method_sampling_interval(JNIEnv* env, jobject jvm, jlong type, jlong intervalMillis))
-  if (intervalMillis < 0) {
-    intervalMillis = 0;
+JVM_ENTRY_NO_ENV(void, jfr_set_method_sampling_period(JNIEnv* env, jobject jvm, jlong type, jlong periodMillis))
+  if (periodMillis < 0) {
+    periodMillis = 0;
   }
   JfrEventId typed_event_id = (JfrEventId)type;
   assert(EventExecutionSample::eventId == typed_event_id || EventNativeMethodSample::eventId == typed_event_id, "invariant");
-  if (intervalMillis > 0) {
-    JfrEventSetting::set_enabled(typed_event_id, true); // ensure sampling event is enabled
-  }
+  JfrEventSetting::set_enabled(typed_event_id, periodMillis > 0);
   if (EventExecutionSample::eventId == type) {
-    JfrThreadSampling::set_java_sample_interval(intervalMillis);
+    JfrThreadSampling::set_java_sample_period(periodMillis);
   } else {
-    JfrThreadSampling::set_native_sample_interval(intervalMillis);
+    JfrThreadSampling::set_native_sample_period(periodMillis);
   }
 JVM_END
 
diff --git a/src/hotspot/share/jfr/jni/jfrJniMethod.hpp b/src/hotspot/share/jfr/jni/jfrJniMethod.hpp
index 105bad8..5e0a62d 100644
--- a/src/hotspot/share/jfr/jni/jfrJniMethod.hpp
+++ b/src/hotspot/share/jfr/jni/jfrJniMethod.hpp
@@ -83,7 +83,7 @@
 
 void JNICALL jfr_set_global_buffer_size(JNIEnv* env, jobject jvm, jlong size);
 
-void JNICALL jfr_set_method_sampling_interval(JNIEnv* env, jobject jvm, jlong type, jlong intervalMillis);
+void JNICALL jfr_set_method_sampling_period(JNIEnv* env, jobject jvm, jlong type, jlong periodMillis);
 
 void JNICALL jfr_set_output(JNIEnv* env, jobject jvm, jstring path);
 
diff --git a/src/hotspot/share/jfr/jni/jfrJniMethodRegistration.cpp b/src/hotspot/share/jfr/jni/jfrJniMethodRegistration.cpp
index 7db414b..3ab0a37 100644
--- a/src/hotspot/share/jfr/jni/jfrJniMethodRegistration.cpp
+++ b/src/hotspot/share/jfr/jni/jfrJniMethodRegistration.cpp
@@ -57,7 +57,7 @@
       (char*)"setFileNotification", (char*)"(J)V", (void*)jfr_set_file_notification,
       (char*)"setGlobalBufferCount", (char*)"(J)V", (void*)jfr_set_global_buffer_count,
       (char*)"setGlobalBufferSize", (char*)"(J)V", (void*)jfr_set_global_buffer_size,
-      (char*)"setMethodSamplingInterval", (char*)"(JJ)V", (void*)jfr_set_method_sampling_interval,
+      (char*)"setMethodSamplingPeriod", (char*)"(JJ)V", (void*)jfr_set_method_sampling_period,
       (char*)"setOutput", (char*)"(Ljava/lang/String;)V", (void*)jfr_set_output,
       (char*)"setSampleThreads", (char*)"(Z)V", (void*)jfr_set_sample_threads,
       (char*)"setStackDepth", (char*)"(I)V", (void*)jfr_set_stack_depth,
diff --git a/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.cpp b/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.cpp
index cad081a..a95cccf 100644
--- a/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.cpp
+++ b/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.cpp
@@ -34,6 +34,7 @@
 #include "jfr/utilities/jfrTime.hpp"
 #include "jfrfiles/jfrEventClasses.hpp"
 #include "logging/log.hpp"
+#include "runtime/atomic.hpp"
 #include "runtime/frame.inline.hpp"
 #include "runtime/os.hpp"
 #include "runtime/semaphore.hpp"
@@ -293,14 +294,18 @@
 void JfrThreadSampleClosure::commit_events(JfrSampleType type) {
   if (JAVA_SAMPLE == type) {
     assert(_added_java > 0 && _added_java <= MAX_NR_OF_JAVA_SAMPLES, "invariant");
-    for (uint i = 0; i < _added_java; ++i) {
-      _events[i].commit();
+    if (EventExecutionSample::is_enabled()) {
+      for (uint i = 0; i < _added_java; ++i) {
+        _events[i].commit();
+      }
     }
   } else {
     assert(NATIVE_SAMPLE == type, "invariant");
     assert(_added_native > 0 && _added_native <= MAX_NR_OF_NATIVE_SAMPLES, "invariant");
-    for (uint i = 0; i < _added_native; ++i) {
-      _events_native[i].commit();
+    if (EventNativeMethodSample::is_enabled()) {
+      for (uint i = 0; i < _added_native; ++i) {
+        _events_native[i].commit();
+      }
     }
   }
 }
@@ -321,25 +326,23 @@
   JfrStackFrame* const _frames;
   JavaThread* _last_thread_java;
   JavaThread* _last_thread_native;
-  size_t _interval_java;
-  size_t _interval_native;
+  int64_t _java_period_millis;
+  int64_t _native_period_millis;
   int _cur_index;
   const u4 _max_frames;
   volatile bool _disenrolled;
 
   JavaThread* next_thread(ThreadsList* t_list, JavaThread* first_sampled, JavaThread* current);
   void task_stacktrace(JfrSampleType type, JavaThread** last_thread);
-  JfrThreadSampler(size_t interval_java, size_t interval_native, u4 max_frames);
+  JfrThreadSampler(int64_t java_period_millis, int64_t native_period_millis, u4 max_frames);
   ~JfrThreadSampler();
 
   void start_thread();
 
   void enroll();
   void disenroll();
-  void set_java_interval(size_t interval) { _interval_java = interval; };
-  void set_native_interval(size_t interval) { _interval_native = interval; };
-  size_t get_java_interval() { return _interval_java; };
-  size_t get_native_interval() { return _interval_native; };
+  void set_java_period(int64_t period_millis);
+  void set_native_period(int64_t period_millis);
  protected:
   virtual void post_run();
  public:
@@ -348,6 +351,8 @@
   void run();
   static Monitor* transition_block() { return JfrThreadSampler_lock; }
   static void on_javathread_suspend(JavaThread* thread);
+  int64_t get_java_period() const { return Atomic::load(&_java_period_millis); };
+  int64_t get_native_period() const { return Atomic::load(&_native_period_millis); };
 };
 
 static void clear_transition_block(JavaThread* jt) {
@@ -387,23 +392,35 @@
   return ret;
 }
 
-JfrThreadSampler::JfrThreadSampler(size_t interval_java, size_t interval_native, u4 max_frames) :
+JfrThreadSampler::JfrThreadSampler(int64_t java_period_millis, int64_t native_period_millis, u4 max_frames) :
   _sample(),
   _sampler_thread(NULL),
   _frames(JfrCHeapObj::new_array<JfrStackFrame>(max_frames)),
   _last_thread_java(NULL),
   _last_thread_native(NULL),
-  _interval_java(interval_java),
-  _interval_native(interval_native),
+  _java_period_millis(java_period_millis),
+  _native_period_millis(native_period_millis),
   _cur_index(-1),
   _max_frames(max_frames),
   _disenrolled(true) {
+  assert(_java_period_millis >= 0, "invariant");
+  assert(_native_period_millis >= 0, "invariant");
 }
 
 JfrThreadSampler::~JfrThreadSampler() {
   JfrCHeapObj::free(_frames, sizeof(JfrStackFrame) * _max_frames);
 }
 
+void JfrThreadSampler::set_java_period(int64_t period_millis) {
+  assert(period_millis >= 0, "invariant");
+  Atomic::store(&_java_period_millis, period_millis);
+}
+
+void JfrThreadSampler::set_native_period(int64_t period_millis) {
+  assert(period_millis >= 0, "invariant");
+  Atomic::store(&_native_period_millis, period_millis);
+}
+
 static inline bool is_released(JavaThread* jt) {
   return !jt->is_trace_suspend();
 }
@@ -461,7 +478,7 @@
   }
 }
 
-static jlong get_monotonic_ms() {
+static int64_t get_monotonic_ms() {
   return os::javaTimeNanos() / 1000000;
 }
 
@@ -470,8 +487,8 @@
 
   _sampler_thread = this;
 
-  jlong last_java_ms = get_monotonic_ms();
-  jlong last_native_ms = last_java_ms;
+  int64_t last_java_ms = get_monotonic_ms();
+  int64_t last_native_ms = last_java_ms;
   while (true) {
     if (!_sample.trywait()) {
       // disenrolled
@@ -480,13 +497,22 @@
       last_native_ms = last_java_ms;
     }
     _sample.signal();
-    jlong java_interval = _interval_java == 0 ? max_jlong : MAX2<jlong>(_interval_java, 1);
-    jlong native_interval = _interval_native == 0 ? max_jlong : MAX2<jlong>(_interval_native, 1);
 
-    jlong now_ms = get_monotonic_ms();
+    int64_t java_period_millis = get_java_period();
+    java_period_millis = java_period_millis == 0 ? max_jlong : MAX2<int64_t>(java_period_millis, 1);
+    int64_t native_period_millis = get_native_period();
+    native_period_millis = native_period_millis == 0 ? max_jlong : MAX2<int64_t>(native_period_millis, 1);
+
+    // If both periods are max_jlong, it implies the sampler is in the process of
+    // disenrolling. Loop back for graceful disenroll by means of the semaphore.
+    if (java_period_millis == max_jlong && native_period_millis == max_jlong) {
+      continue;
+    }
+
+    const int64_t now_ms = get_monotonic_ms();
 
     /*
-     * Let I be java_interval or native_interval.
+     * Let I be java_period or native_period.
      * Let L be last_java_ms or last_native_ms.
      * Let N be now_ms.
      *
@@ -494,13 +520,13 @@
      * could potentially overflow without parenthesis (UB). Also note that
      * L - N < 0. Avoid UB, by adding parenthesis.
      */
-    jlong next_j = java_interval + (last_java_ms - now_ms);
-    jlong next_n = native_interval + (last_native_ms - now_ms);
+    const int64_t next_j = java_period_millis + (last_java_ms - now_ms);
+    const int64_t next_n = native_period_millis + (last_native_ms - now_ms);
 
-    jlong sleep_to_next = MIN2<jlong>(next_j, next_n);
+    const int64_t sleep_to_next = MIN2<int64_t>(next_j, next_n);
 
     if (sleep_to_next > 0) {
-      os::naked_short_sleep(sleep_to_next);
+      os::naked_sleep(sleep_to_next);
     }
 
     if ((next_j - sleep_to_next) <= 0) {
@@ -594,58 +620,76 @@
   }
 }
 
-static void log(size_t interval_java, size_t interval_native) {
-  log_trace(jfr)("Updated thread sampler for java: " SIZE_FORMAT "  ms, native " SIZE_FORMAT " ms", interval_java, interval_native);
+#ifdef ASSERT
+void assert_periods(const JfrThreadSampler* sampler, int64_t java_period_millis, int64_t native_period_millis) {
+  assert(sampler != nullptr, "invariant");
+  assert(sampler->get_java_period() == java_period_millis, "invariant");
+  assert(sampler->get_native_period() == native_period_millis, "invariant");
+}
+#endif
+
+static void log(int64_t java_period_millis, int64_t native_period_millis) {
+  log_trace(jfr)("Updated thread sampler for java: " INT64_FORMAT "  ms, native " INT64_FORMAT " ms", java_period_millis, native_period_millis);
 }
 
-void JfrThreadSampling::start_sampler(size_t interval_java, size_t interval_native) {
-  assert(_sampler == NULL, "invariant");
-  log_trace(jfr)("Enrolling thread sampler");
-  _sampler = new JfrThreadSampler(interval_java, interval_native, JfrOptionSet::stackdepth());
+void JfrThreadSampling::create_sampler(int64_t java_period_millis, int64_t native_period_millis) {
+  assert(_sampler == nullptr, "invariant");
+  log_trace(jfr)("Creating thread sampler for java:" INT64_FORMAT " ms, native " INT64_FORMAT " ms", java_period_millis, native_period_millis);
+  _sampler = new JfrThreadSampler(java_period_millis, native_period_millis, JfrOptionSet::stackdepth());
   _sampler->start_thread();
   _sampler->enroll();
 }
 
-void JfrThreadSampling::set_sampling_interval(bool java_interval, size_t period) {
-  size_t interval_java = 0;
-  size_t interval_native = 0;
-  if (_sampler != NULL) {
-    interval_java = _sampler->get_java_interval();
-    interval_native = _sampler->get_native_interval();
-  }
-  if (java_interval) {
-    interval_java = period;
-  } else {
-    interval_native = period;
-  }
-  if (interval_java > 0 || interval_native > 0) {
-    if (_sampler == NULL) {
-      log_trace(jfr)("Creating thread sampler for java:%zu ms, native %zu ms", interval_java, interval_native);
-      start_sampler(interval_java, interval_native);
+void JfrThreadSampling::update_run_state(int64_t java_period_millis, int64_t native_period_millis) {
+  if (java_period_millis > 0 || native_period_millis > 0) {
+    if (_sampler == nullptr) {
+      create_sampler(java_period_millis, native_period_millis);
     } else {
-      _sampler->set_java_interval(interval_java);
-      _sampler->set_native_interval(interval_native);
       _sampler->enroll();
     }
-    assert(_sampler != NULL, "invariant");
-    log(interval_java, interval_native);
-  } else if (_sampler != NULL) {
+    DEBUG_ONLY(assert_periods(_sampler, java_period_millis, native_period_millis);)
+    log(java_period_millis, native_period_millis);
+    return;
+  }
+  if (_sampler != nullptr) {
+    DEBUG_ONLY(assert_periods(_sampler, java_period_millis, native_period_millis);)
     _sampler->disenroll();
   }
 }
 
-void JfrThreadSampling::set_java_sample_interval(size_t period) {
-  if (_instance == NULL && 0 == period) {
-    return;
+void JfrThreadSampling::set_sampling_period(bool is_java_period, int64_t period_millis) {
+  int64_t java_period_millis = 0;
+  int64_t native_period_millis = 0;
+  if (is_java_period) {
+    java_period_millis = period_millis;
+    if (_sampler != nullptr) {
+      _sampler->set_java_period(java_period_millis);
+      native_period_millis = _sampler->get_native_period();
+    }
+  } else {
+    native_period_millis = period_millis;
+    if (_sampler != nullptr) {
+      _sampler->set_native_period(native_period_millis);
+      java_period_millis = _sampler->get_java_period();
+    }
   }
-  instance().set_sampling_interval(true, period);
+  update_run_state(java_period_millis, native_period_millis);
 }
 
-void JfrThreadSampling::set_native_sample_interval(size_t period) {
-  if (_instance == NULL && 0 == period) {
+void JfrThreadSampling::set_java_sample_period(int64_t period_millis) {
+  assert(period_millis >= 0, "invariant");
+  if (_instance == NULL && 0 == period_millis) {
     return;
   }
-  instance().set_sampling_interval(false, period);
+  instance().set_sampling_period(true, period_millis);
+}
+
+void JfrThreadSampling::set_native_sample_period(int64_t period_millis) {
+  assert(period_millis >= 0, "invariant");
+  if (_instance == NULL && 0 == period_millis) {
+    return;
+  }
+  instance().set_sampling_period(false, period_millis);
 }
 
 void JfrThreadSampling::on_javathread_suspend(JavaThread* thread) {
diff --git a/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.hpp b/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.hpp
index a036be6..ed3f9ce 100644
--- a/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.hpp
+++ b/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,16 +28,15 @@
 #include "jfr/utilities/jfrAllocation.hpp"
 
 class JavaThread;
-class JfrStackFrame;
 class JfrThreadSampler;
-class Thread;
 
 class JfrThreadSampling : public JfrCHeapObj {
   friend class JfrRecorder;
  private:
   JfrThreadSampler* _sampler;
-  void start_sampler(size_t interval_java, size_t interval_native);
-  void set_sampling_interval(bool java_interval, size_t period);
+  void create_sampler(int64_t java_period_millis, int64_t native_period_millis);
+  void update_run_state(int64_t java_period_millis, int64_t native_period_millis);
+  void set_sampling_period(bool is_java_period, int64_t period_millis);
 
   JfrThreadSampling();
   ~JfrThreadSampling();
@@ -47,8 +46,8 @@
   static void destroy();
 
  public:
-  static void set_java_sample_interval(size_t period);
-  static void set_native_sample_interval(size_t period);
+  static void set_java_sample_period(int64_t period_millis);
+  static void set_native_sample_period(int64_t period_millis);
   static void on_javathread_suspend(JavaThread* thread);
 };
 
diff --git a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrThreadGroup.cpp b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrThreadGroup.cpp
index 107e7fa..6d36230 100644
--- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrThreadGroup.cpp
+++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrThreadGroup.cpp
@@ -151,8 +151,12 @@
   assert(current != NULL, "invariant");
   assert(_thread_group_hierarchy != NULL, "invariant");
 
+  oop thread_oop = jt->threadObj();
+  if (thread_oop == nullptr) {
+    return 0;
+  }
   // immediate thread group
-  Handle thread_group_handle(current, java_lang_Thread::threadGroup(jt->threadObj()));
+  Handle thread_group_handle(current, java_lang_Thread::threadGroup(thread_oop));
   if (thread_group_handle == NULL) {
     return 0;
   }
@@ -167,7 +171,7 @@
   Handle parent_thread_group_handle(current, parent_thread_group_obj);
 
   // and check parents parents...
-  while (!(parent_thread_group_handle == NULL)) {
+  while (parent_thread_group_handle != nullptr) {
     const jweak parent_group_weak_ref = use_weak_handles ? JNIHandles::make_weak_global(parent_thread_group_handle) : NULL;
     thread_group_pointers = new JfrThreadGroupPointers(parent_thread_group_handle, parent_group_weak_ref);
     _thread_group_hierarchy->append(thread_group_pointers);
diff --git a/src/hotspot/share/jfr/recorder/service/jfrEvent.hpp b/src/hotspot/share/jfr/recorder/service/jfrEvent.hpp
index 7c1e953..4dc963f 100644
--- a/src/hotspot/share/jfr/recorder/service/jfrEvent.hpp
+++ b/src/hotspot/share/jfr/recorder/service/jfrEvent.hpp
@@ -63,24 +63,20 @@
  private:
   jlong _start_time;
   jlong _end_time;
-  bool _started;
   bool _untimed;
   bool _should_commit;
   bool _evaluated;
 
  protected:
   JfrEvent(EventStartTime timing=TIMED) : _start_time(0), _end_time(0),
-                                          _started(false), _untimed(timing == UNTIMED),
+                                          _untimed(timing == UNTIMED),
                                           _should_commit(false), _evaluated(false)
 #ifdef ASSERT
   , _verifier()
 #endif
   {
-    if (T::is_enabled()) {
-      _started = true;
-      if (TIMED == timing && !T::isInstant) {
-        set_starttime(JfrTicks::now());
-      }
+    if (!T::isInstant && !_untimed && is_enabled()) {
+      set_starttime(JfrTicks::now());
     }
   }
 
@@ -146,20 +142,17 @@
     return T::hasStackTrace;
   }
 
-  bool is_started() const {
-    return _started;
+  bool is_started() {
+    return is_instant() || _start_time != 0 || _untimed;
   }
 
   bool should_commit() {
-    if (!_started) {
+    if (!is_enabled()) {
       return false;
     }
     if (_untimed) {
       return true;
     }
-    if (_evaluated) {
-      return _should_commit;
-    }
     _should_commit = evaluate();
     _evaluated = true;
     return _should_commit;
@@ -167,11 +160,16 @@
 
  private:
   bool should_write() {
-    return _started && (_evaluated ? _should_commit : evaluate());
+    if (_evaluated) {
+      return _should_commit;
+    }
+    if (!is_enabled()) {
+      return false;
+    }
+    return evaluate();
   }
 
   bool evaluate() {
-    assert(_started, "invariant");
     if (_start_time == 0) {
       set_starttime(JfrTicks::now());
     } else if (_end_time == 0) {
diff --git a/src/hotspot/share/legal/siphash.md b/src/hotspot/share/legal/siphash.md
new file mode 100644
index 0000000..1583f22
--- /dev/null
+++ b/src/hotspot/share/legal/siphash.md
@@ -0,0 +1,150 @@
+## SipHash v1.0-68c8a7c
+
+### Notice
+SipHash reference C implementation
+
+```
+   Copyright (c) 2012-2021 Jean-Philippe Aumasson
+   <jeanphilippe.aumasson@gmail.com>
+   Copyright (c) 2012-2014 Daniel J. Bernstein <djb@cr.yp.to>
+   To the extent possible under law, the author(s) have dedicated all copyright
+   and related and neighboring rights to this software to the public domain
+   worldwide. This software is distributed without any warranty.
+   You should have received a copy of the CC0 Public Domain Dedication along
+   with
+   this software. If not, see
+   <http://creativecommons.org/publicdomain/zero/1.0/>.
+```
+
+### Licenses
+The code is dual-licensed CCO and MIT
+
+#### MIT License
+```
+Copyright 2012-2024 JP Aumasson
+
+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.
+```
+
+#### CC0 1.0 Universal
+```
+Statement of Purpose
+
+The laws of most jurisdictions throughout the world automatically confer
+exclusive Copyright and Related Rights (defined below) upon the creator and
+subsequent owner(s) (each and all, an "owner") of an original work of
+authorship and/or a database (each, a "Work").
+
+Certain owners wish to permanently relinquish those rights to a Work for the
+purpose of contributing to a commons of creative, cultural and scientific
+works ("Commons") that the public can reliably and without fear of later
+claims of infringement build upon, modify, incorporate in other works, reuse
+and redistribute as freely as possible in any form whatsoever and for any
+purposes, including without limitation commercial purposes. These owners may
+contribute to the Commons to promote the ideal of a free culture and the
+further production of creative, cultural and scientific works, or to gain
+reputation or greater distribution for their Work in part through the use and
+efforts of others.
+
+For these and/or other purposes and motivations, and without any expectation
+of additional consideration or compensation, the person associating CC0 with a
+Work (the "Affirmer"), to the extent that he or she is an owner of Copyright
+and Related Rights in the Work, voluntarily elects to apply CC0 to the Work
+and publicly distribute the Work under its terms, with knowledge of his or her
+Copyright and Related Rights in the Work and the meaning and intended legal
+effect of CC0 on those rights.
+
+1. Copyright and Related Rights. A Work made available under CC0 may be
+protected by copyright and related or neighboring rights ("Copyright and
+Related Rights"). Copyright and Related Rights include, but are not limited
+to, the following:
+
+  i. the right to reproduce, adapt, distribute, perform, display, communicate,
+  and translate a Work;
+
+  ii. moral rights retained by the original author(s) and/or performer(s);
+
+  iii. publicity and privacy rights pertaining to a person's image or likeness
+  depicted in a Work;
+
+  iv. rights protecting against unfair competition in regards to a Work,
+  subject to the limitations in paragraph 4(a), below;
+
+  v. rights protecting the extraction, dissemination, use and reuse of data in
+  a Work;
+
+  vi. database rights (such as those arising under Directive 96/9/EC of the
+  European Parliament and of the Council of 11 March 1996 on the legal
+  protection of databases, and under any national implementation thereof,
+  including any amended or successor version of such directive); and
+
+  vii. other similar, equivalent or corresponding rights throughout the world
+  based on applicable law or treaty, and any national implementations thereof.
+
+2. Waiver. To the greatest extent permitted by, but not in contravention of,
+applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and
+unconditionally waives, abandons, and surrenders all of Affirmer's Copyright
+and Related Rights and associated claims and causes of action, whether now
+known or unknown (including existing as well as future claims and causes of
+action), in the Work (i) in all territories worldwide, (ii) for the maximum
+duration provided by applicable law or treaty (including future time
+extensions), (iii) in any current or future medium and for any number of
+copies, and (iv) for any purpose whatsoever, including without limitation
+commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes
+the Waiver for the benefit of each member of the public at large and to the
+detriment of Affirmer's heirs and successors, fully intending that such Waiver
+shall not be subject to revocation, rescission, cancellation, termination, or
+any other legal or equitable action to disrupt the quiet enjoyment of the Work
+by the public as contemplated by Affirmer's express Statement of Purpose.
+
+3. Public License Fallback. Should any part of the Waiver for any reason be
+judged legally invalid or ineffective under applicable law, then the Waiver
+shall be preserved to the maximum extent permitted taking into account
+Affirmer's express Statement of Purpose. In addition, to the extent the Waiver
+is so judged Affirmer hereby grants to each affected person a royalty-free,
+non transferable, non sublicensable, non exclusive, irrevocable and
+unconditional license to exercise Affirmer's Copyright and Related Rights in
+the Work (i) in all territories worldwide, (ii) for the maximum duration
+provided by applicable law or treaty (including future time extensions), (iii)
+in any current or future medium and for any number of copies, and (iv) for any
+purpose whatsoever, including without limitation commercial, advertising or
+promotional purposes (the "License"). The License shall be deemed effective as
+of the date CC0 was applied by Affirmer to the Work. Should any part of the
+License for any reason be judged legally invalid or ineffective under
+applicable law, such partial invalidity or ineffectiveness shall not
+invalidate the remainder of the License, and in such case Affirmer hereby
+affirms that he or she will not (i) exercise any of his or her remaining
+Copyright and Related Rights in the Work or (ii) assert any associated claims
+and causes of action with respect to the Work, in either case contrary to
+Affirmer's express Statement of Purpose.
+
+4. Limitations and Disclaimers.
+
+  a. No trademark or patent rights held by Affirmer are waived, abandoned,
+  surrendered, licensed or otherwise affected by this document.
+
+  b. Affirmer offers the Work as-is and makes no representations or warranties
+  of any kind concerning the Work, express, implied, statutory or otherwise,
+  including without limitation warranties of title, merchantability, fitness
+  for a particular purpose, non infringement, or the absence of latent or
+  other defects, accuracy, or the present or absence of errors, whether or not
+  discoverable, all to the greatest extent permissible under applicable law.
+
+  c. Affirmer disclaims responsibility for clearing rights of other persons
+  that may apply to the Work or any use thereof, including without limitation
+  any person's Copyright and Related Rights in the Work. Further, Affirmer
+  disclaims responsibility for obtaining any necessary consents, permissions
+  or other rights required for any use of the Work.
+
+  d. Affirmer understands and acknowledges that Creative Commons is not a
+  party to this document and has no duty or obligation with respect to this
+  CC0 or use of the Work.
+
+For more information, please see
+<http://creativecommons.org/publicdomain/zero/1.0/>
+
+```
diff --git a/src/hotspot/share/metaprogramming/primitiveConversions.hpp b/src/hotspot/share/metaprogramming/primitiveConversions.hpp
index 0880644..f43cfde 100644
--- a/src/hotspot/share/metaprogramming/primitiveConversions.hpp
+++ b/src/hotspot/share/metaprogramming/primitiveConversions.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -105,7 +105,7 @@
     return converter.to;
   }
 
-  // Support thin wrappers over primitive types.
+  // Support thin wrappers over primitive types and other conversions.
   // If derived from std::true_type, provides representational conversion
   // from T to some other type.  When true, must provide
   // - Value: typedef for T.
@@ -114,7 +114,20 @@
   //   the same value representation as x.
   // - static T recover(Decayed x): return a value of type T with the
   //   same value representation as x.
-  template<typename T> struct Translate : public std::false_type {};
+  template<typename T, typename Enable = void>
+  struct Translate : public std::false_type {};
+};
+
+// Enum types translate to/from their underlying type.
+template<typename T>
+struct PrimitiveConversions::Translate<T, std::enable_if_t<std::is_enum<T>::value>>
+  : public std::true_type
+{
+  using Value = T;
+  using Decayed = std::underlying_type_t<T>;
+
+  static constexpr Decayed decay(Value x) { return static_cast<Decayed>(x); }
+  static constexpr Value recover(Decayed x) { return static_cast<Value>(x); }
 };
 
 // jfloat and jdouble translation to integral types
diff --git a/src/hotspot/share/oops/constantPool.cpp b/src/hotspot/share/oops/constantPool.cpp
index a97f2fe..53e166c 100644
--- a/src/hotspot/share/oops/constantPool.cpp
+++ b/src/hotspot/share/oops/constantPool.cpp
@@ -767,13 +767,16 @@
   }
 }
 
-static Symbol* exception_message(const constantPoolHandle& this_cp, int which, constantTag tag, oop pending_exception) {
+static const char* exception_message(const constantPoolHandle& this_cp, int which, constantTag tag, oop pending_exception) {
+  // Note: caller needs ResourceMark
+
   // Dig out the detailed message to reuse if possible
-  Symbol* message = java_lang_Throwable::detail_message(pending_exception);
-  if (message != NULL) {
-    return message;
+  const char* msg = java_lang_Throwable::message_as_utf8(pending_exception);
+  if (msg != nullptr) {
+    return msg;
   }
 
+  Symbol* message = nullptr;
   // Return specific message for the tag
   switch (tag.value()) {
   case JVM_CONSTANT_UnresolvedClass:
@@ -796,49 +799,48 @@
     ShouldNotReachHere();
   }
 
-  return message;
+  return message != nullptr ? message->as_C_string() : nullptr;
 }
 
-static void add_resolution_error(const constantPoolHandle& this_cp, int which,
+static void add_resolution_error(JavaThread* current, const constantPoolHandle& this_cp, int which,
                                  constantTag tag, oop pending_exception) {
+  ResourceMark rm(current);
 
   Symbol* error = pending_exception->klass()->name();
   oop cause = java_lang_Throwable::cause(pending_exception);
 
   // Also dig out the exception cause, if present.
   Symbol* cause_sym = NULL;
-  Symbol* cause_msg = NULL;
+  const char* cause_msg = nullptr;
   if (cause != NULL && cause != pending_exception) {
     cause_sym = cause->klass()->name();
-    cause_msg = java_lang_Throwable::detail_message(cause);
+    cause_msg = java_lang_Throwable::message_as_utf8(cause);
   }
 
-  Symbol* message = exception_message(this_cp, which, tag, pending_exception);
+  const char* message = exception_message(this_cp, which, tag, pending_exception);
   SystemDictionary::add_resolution_error(this_cp, which, error, message, cause_sym, cause_msg);
 }
 
 
 void ConstantPool::throw_resolution_error(const constantPoolHandle& this_cp, int which, TRAPS) {
   ResourceMark rm(THREAD);
-  Symbol* message = NULL;
+  const char* message = NULL;
   Symbol* cause = NULL;
-  Symbol* cause_msg = NULL;
+  const char* cause_msg = NULL;
   Symbol* error = SystemDictionary::find_resolution_error(this_cp, which, &message, &cause, &cause_msg);
   assert(error != NULL, "checking");
-  const char* cause_str = cause_msg != NULL ? cause_msg->as_C_string() : NULL;
 
   CLEAR_PENDING_EXCEPTION;
   if (message != NULL) {
-    char* msg = message->as_C_string();
     if (cause != NULL) {
-      Handle h_cause = Exceptions::new_exception(THREAD, cause, cause_str);
-      THROW_MSG_CAUSE(error, msg, h_cause);
+      Handle h_cause = Exceptions::new_exception(THREAD, cause, cause_msg);
+      THROW_MSG_CAUSE(error, message, h_cause);
     } else {
-      THROW_MSG(error, msg);
+      THROW_MSG(error, message);
     }
   } else {
     if (cause != NULL) {
-      Handle h_cause = Exceptions::new_exception(THREAD, cause, cause_str);
+      Handle h_cause = Exceptions::new_exception(THREAD, cause, cause_msg);
       THROW_CAUSE(error, h_cause);
     } else {
       THROW(error);
@@ -860,7 +862,7 @@
     // and OutOfMemoryError, etc, or if the thread was hit by stop()
     // Needs clarification to section 5.4.3 of the VM spec (see 6308271)
   } else if (this_cp->tag_at(which).value() != error_tag) {
-    add_resolution_error(this_cp, which, tag, PENDING_EXCEPTION);
+    add_resolution_error(THREAD, this_cp, which, tag, PENDING_EXCEPTION);
     // CAS in the tag.  If a thread beat us to registering this error that's fine.
     // If another thread resolved the reference, this is a race condition. This
     // thread may have had a security manager or something temporary.
diff --git a/src/hotspot/share/oops/cpCache.cpp b/src/hotspot/share/oops/cpCache.cpp
index b0cd727..d247b42 100644
--- a/src/hotspot/share/oops/cpCache.cpp
+++ b/src/hotspot/share/oops/cpCache.cpp
@@ -499,9 +499,9 @@
     CLEAR_PENDING_EXCEPTION;
     return false;
   }
-
+  ResourceMark rm(THREAD);
   Symbol* error = PENDING_EXCEPTION->klass()->name();
-  Symbol* message = java_lang_Throwable::detail_message(PENDING_EXCEPTION);
+  const char* message = java_lang_Throwable::message_as_utf8(PENDING_EXCEPTION);
 
   SystemDictionary::add_resolution_error(cpool, index, error, message);
   set_indy_resolution_failed();
diff --git a/src/hotspot/share/oops/instanceKlass.cpp b/src/hotspot/share/oops/instanceKlass.cpp
index 72997d8..c2054fb 100644
--- a/src/hotspot/share/oops/instanceKlass.cpp
+++ b/src/hotspot/share/oops/instanceKlass.cpp
@@ -4099,6 +4099,23 @@
   return ret;
 }
 
+// This nulls out jmethodIDs for all methods in 'klass'
+// It needs to be called explicitly for all previous versions of a class because these may not be cleaned up
+// during class unloading.
+// We can not use the jmethodID cache associated with klass directly because the 'previous' versions
+// do not have the jmethodID cache filled in. Instead, we need to lookup jmethodID for each method and this
+// is expensive - O(n) for one jmethodID lookup. For all contained methods it is O(n^2).
+// The reason for expensive jmethodID lookup for each method is that there is no direct link between method and jmethodID.
+void InstanceKlass::clear_jmethod_ids(InstanceKlass* klass) {
+  Array<Method*>* method_refs = klass->methods();
+  for (int k = 0; k < method_refs->length(); k++) {
+    Method* method = method_refs->at(k);
+    if (method != nullptr && method->is_obsolete()) {
+      method->clear_jmethod_id();
+    }
+  }
+}
+
 // Purge previous versions before adding new previous versions of the class and
 // during class unloading.
 void InstanceKlass::purge_previous_version_list() {
@@ -4142,6 +4159,7 @@
       // Unlink from previous version list.
       assert(pv_node->class_loader_data() == loader_data, "wrong loader_data");
       InstanceKlass* next = pv_node->previous_versions();
+      clear_jmethod_ids(pv_node); // jmethodID maintenance for the unloaded class
       pv_node->link_previous_versions(NULL);   // point next to NULL
       last->link_previous_versions(next);
       // Delete this node directly. Nothing is referring to it and we don't
diff --git a/src/hotspot/share/oops/instanceKlass.hpp b/src/hotspot/share/oops/instanceKlass.hpp
index 0d2e122..a2a6ec6 100644
--- a/src/hotspot/share/oops/instanceKlass.hpp
+++ b/src/hotspot/share/oops/instanceKlass.hpp
@@ -1197,6 +1197,8 @@
   bool idnum_can_increment() const      { return has_been_redefined(); }
   inline jmethodID* methods_jmethod_ids_acquire() const;
   inline void release_set_methods_jmethod_ids(jmethodID* jmeths);
+  // This nulls out jmethodIDs for all methods in 'klass'
+  static void clear_jmethod_ids(InstanceKlass* klass);
 
   // Lock during initialization
 public:
diff --git a/src/hotspot/share/oops/method.cpp b/src/hotspot/share/oops/method.cpp
index a39fdb0..05859d8 100644
--- a/src/hotspot/share/oops/method.cpp
+++ b/src/hotspot/share/oops/method.cpp
@@ -2270,6 +2270,20 @@
   loader_data->jmethod_ids()->clear_all_methods();
 }
 
+void Method::clear_jmethod_id() {
+  // Being at a safepoint prevents racing against other class redefinitions
+  assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint");
+  // The jmethodID is not stored in the Method instance, we need to look it up first
+  jmethodID methodid = find_jmethod_id_or_null();
+  // We need to make sure that jmethodID actually resolves to this method
+  // - multiple redefined versions may share jmethodID slots and if a method
+  //   has already been rewired to a newer version we could be removing reference
+  //   to a still existing method instance
+  if (methodid != nullptr && *((Method**)methodid) == this) {
+    *((Method**)methodid) = nullptr;
+  }
+}
+
 bool Method::has_method_vptr(const void* ptr) {
   Method m;
   // This assumes that the vtbl pointer is the first word of a C++ object.
diff --git a/src/hotspot/share/oops/method.hpp b/src/hotspot/share/oops/method.hpp
index ae62fa7..da5615e 100644
--- a/src/hotspot/share/oops/method.hpp
+++ b/src/hotspot/share/oops/method.hpp
@@ -808,6 +808,7 @@
 
   // Clear methods
   static void clear_jmethod_ids(ClassLoaderData* loader_data);
+  void clear_jmethod_id();
   static void print_jmethod_ids_count(const ClassLoaderData* loader_data, outputStream* out) PRODUCT_RETURN;
 
   // Get this method's jmethodID -- allocate if it doesn't exist
diff --git a/src/hotspot/share/opto/block.hpp b/src/hotspot/share/opto/block.hpp
index 5ccb465..18a5916 100644
--- a/src/hotspot/share/opto/block.hpp
+++ b/src/hotspot/share/opto/block.hpp
@@ -438,6 +438,12 @@
   // Compute the instruction global latency with a backwards walk
   void compute_latencies_backwards(VectorSet &visited, Node_Stack &stack);
 
+  // Check if a block between early and LCA block of uses is cheaper by
+  // frequency-based policy, latency-based policy and random-based policy
+  bool is_cheaper_block(Block* LCA, Node* self, uint target_latency,
+                        uint end_latency, double least_freq,
+                        int cand_cnt, bool in_latency);
+
   // Pick a block between early and late that is a cheaper alternative
   // to late. Helper for schedule_late.
   Block* hoist_to_cheaper_block(Block* LCA, Block* early, Node* self);
diff --git a/src/hotspot/share/opto/callGenerator.cpp b/src/hotspot/share/opto/callGenerator.cpp
index e856ed2..837bbd9 100644
--- a/src/hotspot/share/opto/callGenerator.cpp
+++ b/src/hotspot/share/opto/callGenerator.cpp
@@ -97,6 +97,8 @@
   }
 
   Parse parser(jvms, method(), _expected_uses);
+  if (C->failing()) return nullptr;
+
   // Grab signature for matching/allocation
   GraphKit& exits = parser.exits();
 
diff --git a/src/hotspot/share/opto/compile.cpp b/src/hotspot/share/opto/compile.cpp
index 4b22284..4e8e39f 100644
--- a/src/hotspot/share/opto/compile.cpp
+++ b/src/hotspot/share/opto/compile.cpp
@@ -2107,6 +2107,8 @@
     // Inline valueOf() methods now.
     inline_boxing_calls(igvn);
 
+    if (failing())  return;
+
     if (AlwaysIncrementalInline) {
       inline_incrementally(igvn);
     }
@@ -2122,16 +2124,20 @@
   // CastPP nodes.
   remove_speculative_types(igvn);
 
+  if (failing())  return;
+
   // No more new expensive nodes will be added to the list from here
   // so keep only the actual candidates for optimizations.
   cleanup_expensive_nodes(igvn);
 
+  if (failing())  return;
+
   assert(EnableVectorSupport || !has_vbox_nodes(), "sanity");
   if (EnableVectorSupport && has_vbox_nodes()) {
     TracePhase tp("", &timers[_t_vector]);
     PhaseVector pv(igvn);
     pv.optimize_vector_boxes();
-
+    if (failing())  return;
     print_method(PHASE_ITER_GVN_AFTER_VECTOR, 2);
   }
   assert(!has_vbox_nodes(), "sanity");
@@ -2156,6 +2162,8 @@
   // safepoints
   remove_root_to_sfpts_edges(igvn);
 
+  if (failing())  return;
+
   // Perform escape analysis
   if (_do_escape_analysis && ConnectionGraph::has_candidates(this)) {
     if (has_loops()) {
@@ -2255,6 +2263,8 @@
 
   process_for_post_loop_opts_igvn(igvn);
 
+  if (failing())  return;
+
 #ifdef ASSERT
   bs->verify_gc_barriers(this, BarrierSetC2::BeforeMacroExpand);
 #endif
@@ -2293,6 +2303,7 @@
     // More opportunities to optimize virtual and MH calls.
     // Though it's maybe too late to perform inlining, strength-reducing them to direct calls is still an option.
     process_late_inline_calls_no_inline(igvn);
+    if (failing())  return;
   }
  } // (End scope of igvn; run destructor if necessary for asserts.)
 
@@ -4619,6 +4630,7 @@
     igvn.remove_speculative_types();
     if (modified > 0) {
       igvn.optimize();
+      if (failing())  return;
     }
 #ifdef ASSERT
     // Verify that after the IGVN is over no speculative type has resurfaced
diff --git a/src/hotspot/share/opto/gcm.cpp b/src/hotspot/share/opto/gcm.cpp
index 1ad8fd8..876e1d9 100644
--- a/src/hotspot/share/opto/gcm.cpp
+++ b/src/hotspot/share/opto/gcm.cpp
@@ -1130,11 +1130,41 @@
   set_latency_for_node(n, latency);
 }
 
+//------------------------------is_cheaper_block-------------------------
+// Check if a block between early and LCA block of uses is cheaper by
+// frequency-based policy, latency-based policy and random-based policy
+bool PhaseCFG::is_cheaper_block(Block* LCA, Node* self, uint target_latency,
+                                uint end_latency, double least_freq,
+                                int cand_cnt, bool in_latency) {
+  if (StressGCM) {
+    // Should be randomly accepted in stress mode
+    return C->randomized_select(cand_cnt);
+  }
+
+  // Better Frequency
+  if (LCA->_freq < least_freq) {
+    return true;
+  }
+
+  // Otherwise, choose with latency
+  const double delta = 1 + PROB_UNLIKELY_MAG(4);
+  if (!in_latency                     &&  // No block containing latency
+      LCA->_freq < least_freq * delta &&  // No worse frequency
+      target_latency >= end_latency   &&  // within latency range
+      !self->is_iteratively_computed()    // But don't hoist IV increments
+            // because they may end up above other uses of their phi forcing
+            // their result register to be different from their input.
+  ) {
+    return true;
+  }
+
+  return false;
+}
+
 //------------------------------hoist_to_cheaper_block-------------------------
-// Pick a block for node self, between early and LCA, that is a cheaper
-// alternative to LCA.
+// Pick a block for node self, between early and LCA block of uses, that is a
+// cheaper alternative to LCA.
 Block* PhaseCFG::hoist_to_cheaper_block(Block* LCA, Block* early, Node* self) {
-  const double delta = 1+PROB_UNLIKELY_MAG(4);
   Block* least       = LCA;
   double least_freq  = least->_freq;
   uint target        = get_latency_for_node(self);
@@ -1171,7 +1201,8 @@
   int cand_cnt = 0;  // number of candidates tried
 
   // Walk up the dominator tree from LCA (Lowest common ancestor) to
-  // the earliest legal location.  Capture the least execution frequency.
+  // the earliest legal location. Capture the least execution frequency,
+  // or choose a random block if -XX:+StressGCM, or using latency-based policy
   while (LCA != early) {
     LCA = LCA->_idom;         // Follow up the dominator tree
 
@@ -1205,16 +1236,7 @@
     }
 #endif
     cand_cnt++;
-    if (LCA_freq < least_freq              || // Better Frequency
-        (StressGCM && C->randomized_select(cand_cnt)) || // Should be randomly accepted in stress mode
-         (!StressGCM                    &&    // Otherwise, choose with latency
-          !in_latency                   &&    // No block containing latency
-          LCA_freq < least_freq * delta &&    // No worse frequency
-          target >= end_lat             &&    // within latency range
-          !self->is_iteratively_computed() )  // But don't hoist IV increments
-             // because they may end up above other uses of their phi forcing
-             // their result register to be different from their input.
-       ) {
+    if (is_cheaper_block(LCA, self, target, end_lat, least_freq, cand_cnt, in_latency)) {
       least = LCA;            // Found cheaper block
       least_freq = LCA_freq;
       start_latency = start_lat;
diff --git a/src/hotspot/share/opto/graphKit.hpp b/src/hotspot/share/opto/graphKit.hpp
index 38e825e..742e88e 100644
--- a/src/hotspot/share/opto/graphKit.hpp
+++ b/src/hotspot/share/opto/graphKit.hpp
@@ -82,7 +82,8 @@
 
 #ifdef ASSERT
   ~GraphKit() {
-    assert(!has_exceptions(), "user must call transfer_exceptions_into_jvms");
+    assert(failing() || !has_exceptions(),
+           "unless compilation failed, user must call transfer_exceptions_into_jvms");
   }
 #endif
 
diff --git a/src/hotspot/share/opto/loopTransform.cpp b/src/hotspot/share/opto/loopTransform.cpp
index 4d37570..ae2ed68 100644
--- a/src/hotspot/share/opto/loopTransform.cpp
+++ b/src/hotspot/share/opto/loopTransform.cpp
@@ -1898,6 +1898,9 @@
   post_head->set_normal_loop();
   post_head->set_post_loop(main_head);
 
+  // clone_loop() above changes the exit projection
+  main_exit = outer_main_end->proj_out(false);
+
   // Reduce the post-loop trip count.
   CountedLoopEndNode* post_end = old_new[main_end->_idx]->as_CountedLoopEnd();
   post_end->_prob = PROB_FAIR;
diff --git a/src/hotspot/share/opto/loopnode.cpp b/src/hotspot/share/opto/loopnode.cpp
index d1fd7c8..ce6ecc4 100644
--- a/src/hotspot/share/opto/loopnode.cpp
+++ b/src/hotspot/share/opto/loopnode.cpp
@@ -4346,6 +4346,8 @@
   int old_progress = C->major_progress();
   ResourceMark rm;
   PhaseIdealLoop loop_verify(_igvn, this);
+  if (C->failing()) return;
+
   VectorSet visited;
 
   fail = 0;
diff --git a/src/hotspot/share/opto/loopnode.hpp b/src/hotspot/share/opto/loopnode.hpp
index 6055db0..8bcdd96 100644
--- a/src/hotspot/share/opto/loopnode.hpp
+++ b/src/hotspot/share/opto/loopnode.hpp
@@ -1156,7 +1156,7 @@
     if (!C->failing()) {
       // Cleanup any modified bits
       igvn.optimize();
-
+      if (C->failing()) { return; }
       v.log_loop_tree();
     }
   }
@@ -1501,7 +1501,7 @@
   Node *find_use_block( Node *use, Node *def, Node *old_false, Node *new_false, Node *old_true, Node *new_true );
   void handle_use( Node *use, Node *def, small_cache *cache, Node *region_dom, Node *new_false, Node *new_true, Node *old_false, Node *old_true );
   bool split_up( Node *n, Node *blk1, Node *blk2 );
-  void sink_use( Node *use, Node *post_loop );
+
   Node* place_outside_loop(Node* useblock, IdealLoopTree* loop) const;
   Node* try_move_store_before_loop(Node* n, Node *n_ctrl);
   void try_move_store_after_loop(Node* n);
diff --git a/src/hotspot/share/opto/loopopts.cpp b/src/hotspot/share/opto/loopopts.cpp
index 6cfe2bd..2a1d169 100644
--- a/src/hotspot/share/opto/loopopts.cpp
+++ b/src/hotspot/share/opto/loopopts.cpp
@@ -1934,17 +1934,6 @@
   return (CmpNode*)cmp;
 }
 
-//------------------------------sink_use---------------------------------------
-// If 'use' was in the loop-exit block, it now needs to be sunk
-// below the post-loop merge point.
-void PhaseIdealLoop::sink_use( Node *use, Node *post_loop ) {
-  if (!use->is_CFG() && get_ctrl(use) == post_loop->in(2)) {
-    set_ctrl(use, post_loop);
-    for (DUIterator j = use->outs(); use->has_out(j); j++)
-      sink_use(use->out(j), post_loop);
-  }
-}
-
 void PhaseIdealLoop::clone_loop_handle_data_uses(Node* old, Node_List &old_new,
                                                  IdealLoopTree* loop, IdealLoopTree* outer_loop,
                                                  Node_List*& split_if_set, Node_List*& split_bool_set,
@@ -2011,7 +2000,7 @@
       while( use->in(idx) != old ) idx++;
       Node *prev = use->is_CFG() ? use : get_ctrl(use);
       assert(!loop->is_member(get_loop(prev)) && !outer_loop->is_member(get_loop(prev)), "" );
-      Node *cfg = prev->_idx >= new_counter
+      Node* cfg = (prev->_idx >= new_counter && prev->is_Region())
         ? prev->in(2)
         : idom(prev);
       if( use->is_Phi() )     // Phi use is in prior block
@@ -2035,7 +2024,7 @@
 
       while(!outer_loop->is_member(get_loop(cfg))) {
         prev = cfg;
-        cfg = cfg->_idx >= new_counter ? cfg->in(2) : idom(cfg);
+        cfg = (cfg->_idx >= new_counter && cfg->is_Region()) ? cfg->in(2) : idom(cfg);
       }
       // If the use occurs after merging several exits from the loop, then
       // old value must have dominated all those exits.  Since the same old
@@ -2089,10 +2078,6 @@
         if( hit )             // Go ahead and re-hash for hits.
           _igvn.replace_node( use, hit );
       }
-
-      // If 'use' was in the loop-exit block, it now needs to be sunk
-      // below the post-loop merge point.
-      sink_use( use, prev );
     }
   }
 }
@@ -2423,8 +2408,6 @@
         // We need a Region to merge the exit from the peeled body and the
         // exit from the old loop body.
         RegionNode *r = new RegionNode(3);
-        // Map the old use to the new merge point
-        old_new.map( use->_idx, r );
         uint dd_r = MIN2(dom_depth(newuse),dom_depth(use));
         assert( dd_r >= dom_depth(dom_lca(newuse,use)), "" );
 
@@ -2460,12 +2443,24 @@
           l -= uses_found;    // we deleted 1 or more copies of this edge
         }
 
+        assert(use->is_Proj(), "loop exit should be projection");
+        // lazy_replace() below moves all nodes that are:
+        // - control dependent on the loop exit or
+        // - have control set to the loop exit
+        // below the post-loop merge point. lazy_replace() takes a dead control as first input. To make it
+        // possible to use it, the loop exit projection is cloned and becomes the new exit projection. The initial one
+        // becomes dead and is "replaced" by the region.
+        Node* use_clone = use->clone();
+        register_control(use_clone, use_loop, idom(use), dom_depth(use));
         // Now finish up 'r'
         r->set_req( 1, newuse );
-        r->set_req( 2,    use );
+        r->set_req( 2, use_clone );
         _igvn.register_new_node_with_optimizer(r);
         set_loop(r, use_loop);
         set_idom(r, !side_by_side_idom ? newuse->in(0) : side_by_side_idom, dd_r);
+        lazy_replace(use, r);
+        // Map the (cloned) old use to the new merge point
+        old_new.map(use_clone->_idx, r);
       } // End of if a loop-exit test
     }
   }
diff --git a/src/hotspot/share/opto/matcher.cpp b/src/hotspot/share/opto/matcher.cpp
index 5558393..291a4f6 100644
--- a/src/hotspot/share/opto/matcher.cpp
+++ b/src/hotspot/share/opto/matcher.cpp
@@ -276,6 +276,7 @@
     // Permit args to have no register
     _calling_convention_mask[i].Clear();
     if( !vm_parm_regs[i].first()->is_valid() && !vm_parm_regs[i].second()->is_valid() ) {
+      _parm_regs[i].set_bad();
       continue;
     }
     // calling_convention returns stack arguments as a count of
@@ -352,7 +353,9 @@
   // Recursively match trees from old space into new space.
   // Correct leaves of new-space Nodes; they point to old-space.
   _visited.clear();
-  C->set_cached_top_node(xform( C->top(), live_nodes ));
+  Node* const n = xform(C->top(), live_nodes);
+  if (C->failing()) return;
+  C->set_cached_top_node(n);
   if (!C->failing()) {
     Node* xroot =        xform( C->root(), 1 );
     if (xroot == nullptr) {
diff --git a/src/hotspot/share/opto/mulnode.cpp b/src/hotspot/share/opto/mulnode.cpp
index cc42318..6d35fd8 100644
--- a/src/hotspot/share/opto/mulnode.cpp
+++ b/src/hotspot/share/opto/mulnode.cpp
@@ -63,6 +63,29 @@
   Node* in2 = in(2);
   Node* progress = nullptr;        // Progress flag
 
+  // This code is used by And nodes too, but some conversions are
+  // only valid for the actual Mul nodes.
+  uint op = Opcode();
+  bool real_mul = (op == Op_MulI) || (op == Op_MulL) ||
+                  (op == Op_MulF) || (op == Op_MulD);
+
+  // Convert "(-a)*(-b)" into "a*b".
+  if (real_mul && in1->is_Sub() && in2->is_Sub()) {
+    if (phase->type(in1->in(1))->is_zero_type() &&
+        phase->type(in2->in(1))->is_zero_type()) {
+      set_req(1, in1->in(2));
+      set_req(2, in2->in(2));
+      PhaseIterGVN* igvn = phase->is_IterGVN();
+      if (igvn) {
+        igvn->_worklist.push(in1);
+        igvn->_worklist.push(in2);
+      }
+      in1 = in(1);
+      in2 = in(2);
+      progress = this;
+    }
+  }
+
   // convert "max(a,b) * min(a,b)" into "a*b".
   if ((in(1)->Opcode() == max_opcode() && in(2)->Opcode() == min_opcode())
       || (in(1)->Opcode() == min_opcode() && in(2)->Opcode() == max_opcode())) {
@@ -107,7 +130,6 @@
 
   // If the right input is a constant, and the left input is a product of a
   // constant, flatten the expression tree.
-  uint op = Opcode();
   if( t2->singleton() &&        // Right input is a constant?
       op != Op_MulF &&          // Float & double cannot reassociate
       op != Op_MulD ) {
diff --git a/src/hotspot/share/opto/parse1.cpp b/src/hotspot/share/opto/parse1.cpp
index 7cb74b3..8ce2bde 100644
--- a/src/hotspot/share/opto/parse1.cpp
+++ b/src/hotspot/share/opto/parse1.cpp
@@ -1555,6 +1555,7 @@
 #endif //ASSERT
 
     do_one_bytecode();
+    if (failing()) return;
 
     assert(!have_se || stopped() || failing() || (sp() - pre_bc_sp) == depth,
            "incorrect depth prediction: sp=%d, pre_bc_sp=%d, depth=%d", sp(), pre_bc_sp, depth);
diff --git a/src/hotspot/share/opto/superword.cpp b/src/hotspot/share/opto/superword.cpp
index 0f82da8..07b0757 100644
--- a/src/hotspot/share/opto/superword.cpp
+++ b/src/hotspot/share/opto/superword.cpp
@@ -2460,18 +2460,18 @@
       if (n->is_Load()) {
         Node* ctl = n->in(MemNode::Control);
         Node* mem = first->in(MemNode::Memory);
+        // Set the memory dependency of the LoadVector as early as possible.
+        // Walk up the memory chain, and ignore any StoreVector that provably
+        // does not have any memory dependency.
         SWPointer p1(n->as_Mem(), this, nullptr, false);
-        // Identify the memory dependency for the new loadVector node by
-        // walking up through memory chain.
-        // This is done to give flexibility to the new loadVector node so that
-        // it can move above independent storeVector nodes.
         while (mem->is_StoreVector()) {
           SWPointer p2(mem->as_Mem(), this, nullptr, false);
-          int cmp = p1.cmp(p2);
-          if (SWPointer::not_equal(cmp) || !SWPointer::comparable(cmp)) {
+          if (p1.not_equal(p2)) {
+            // Either Less or Greater -> provably no overlap between the two memory regions.
             mem = mem->in(MemNode::Memory);
           } else {
-            break; // dependent memory
+            // No proof that there is no overlap. Stop here.
+            break;
           }
         }
         Node* adr = low_adr->in(MemNode::Address);
diff --git a/src/hotspot/share/opto/type.cpp b/src/hotspot/share/opto/type.cpp
index 2c14ded..dbef415 100644
--- a/src/hotspot/share/opto/type.cpp
+++ b/src/hotspot/share/opto/type.cpp
@@ -4224,7 +4224,7 @@
   jint hi = size->_hi;
   jint lo = size->_lo;
   jint min_lo = 0;
-  jint max_hi = max_array_length(elem()->basic_type());
+  jint max_hi = max_array_length(elem()->array_element_basic_type());
   //if (index_not_size)  --max_hi;     // type of a valid array index, FTR
   bool chg = false;
   if (lo < min_lo) {
diff --git a/src/hotspot/share/prims/forte.cpp b/src/hotspot/share/prims/forte.cpp
index ac71146..31be7b2 100644
--- a/src/hotspot/share/prims/forte.cpp
+++ b/src/hotspot/share/prims/forte.cpp
@@ -595,9 +595,6 @@
     return;
   }
 
-  // !important! make sure all to call thread->set_in_asgct(false) before every return
-  thread->set_in_asgct(true);
-
   // signify to other code in the VM that we're in ASGCT
   ThreadInAsgct tia(thread);
 
@@ -658,7 +655,6 @@
     trace->num_frames = ticks_unknown_state; // -7
     break;
   }
-  thread->set_in_asgct(false);
 }
 
 
diff --git a/src/hotspot/share/prims/jni.cpp b/src/hotspot/share/prims/jni.cpp
index afc524e..77609b9 100644
--- a/src/hotspot/share/prims/jni.cpp
+++ b/src/hotspot/share/prims/jni.cpp
@@ -946,6 +946,11 @@
     }
   }
 
+  if (selected_method->is_abstract()) {
+    ResourceMark rm(THREAD);
+    THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), selected_method->name()->as_C_string());
+  }
+
   methodHandle method(THREAD, selected_method);
 
   // Create object to hold arguments for the JavaCall, and associate it with
diff --git a/src/hotspot/share/prims/jvmtiEnvBase.cpp b/src/hotspot/share/prims/jvmtiEnvBase.cpp
index 5335945..943aedd 100644
--- a/src/hotspot/share/prims/jvmtiEnvBase.cpp
+++ b/src/hotspot/share/prims/jvmtiEnvBase.cpp
@@ -207,7 +207,8 @@
   _is_retransformable = true;
 
   // all callbacks initially NULL
-  memset(&_event_callbacks,0,sizeof(jvmtiEventCallbacks));
+  memset(&_event_callbacks, 0, sizeof(jvmtiEventCallbacks));
+  memset(&_ext_event_callbacks, 0, sizeof(jvmtiExtEventCallbacks));
 
   // all capabilities initially off
   memset(&_current_capabilities, 0, sizeof(_current_capabilities));
diff --git a/src/hotspot/share/prims/jvmtiExport.hpp b/src/hotspot/share/prims/jvmtiExport.hpp
index 6f04ce7..6220687 100644
--- a/src/hotspot/share/prims/jvmtiExport.hpp
+++ b/src/hotspot/share/prims/jvmtiExport.hpp
@@ -142,7 +142,15 @@
     JVMTI_ONLY(_can_access_local_variables = (on != 0);)
   }
   inline static void set_can_hotswap_or_post_breakpoint(bool on) {
-    JVMTI_ONLY(_can_hotswap_or_post_breakpoint = (on != 0);)
+#if INCLUDE_JVMTI
+    // Check that _can_hotswap_or_post_breakpoint is not reset once it
+    // was set to true. When _can_hotswap_or_post_breakpoint is set to true
+    // _all_dependencies_are_recorded is also set to true and never
+    // reset so we have to ensure that evol dependencies are always
+    // recorded from that point on.
+    assert(!_can_hotswap_or_post_breakpoint || on, "sanity check");
+    _can_hotswap_or_post_breakpoint = (on != 0);
+#endif
   }
   inline static void set_can_walk_any_space(bool on) {
     JVMTI_ONLY(_can_walk_any_space = (on != 0);)
diff --git a/src/hotspot/share/prims/jvmtiRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiRedefineClasses.cpp
index 8b300db..8cee27b 100644
--- a/src/hotspot/share/prims/jvmtiRedefineClasses.cpp
+++ b/src/hotspot/share/prims/jvmtiRedefineClasses.cpp
@@ -4075,17 +4075,17 @@
 // Deoptimize all compiled code that depends on this class.
 //
 // If the can_redefine_classes capability is obtained in the onload
-// phase then the compiler has recorded all dependencies from startup.
-// In that case we need only deoptimize and throw away all compiled code
-// that depends on the class.
+// phase or 'AlwaysRecordEvolDependencies' is true, then the compiler has
+// recorded all dependencies from startup. In that case we need only
+// deoptimize and throw away all compiled code that depends on the class.
 //
-// If can_redefine_classes is obtained sometime after the onload
-// phase then the dependency information may be incomplete. In that case
-// the first call to RedefineClasses causes all compiled code to be
-// thrown away. As can_redefine_classes has been obtained then
-// all future compilations will record dependencies so second and
-// subsequent calls to RedefineClasses need only throw away code
-// that depends on the class.
+// If can_redefine_classes is obtained sometime after the onload phase
+// (and 'AlwaysRecordEvolDependencies' is false) then the dependency
+// information may be incomplete. In that case the first call to
+// RedefineClasses causes all compiled code to be thrown away. As
+// can_redefine_classes has been obtained then all future compilations will
+// record dependencies so second and subsequent calls to RedefineClasses
+// need only throw away code that depends on the class.
 //
 
 // First step is to walk the code cache for each class redefined and mark
@@ -4102,6 +4102,7 @@
 
 void VM_RedefineClasses::flush_dependent_code() {
   assert(SafepointSynchronize::is_at_safepoint(), "sanity check");
+  assert(JvmtiExport::all_dependencies_are_recorded() || !AlwaysRecordEvolDependencies, "sanity check");
 
   bool deopt_needed;
 
diff --git a/src/hotspot/share/prims/unsafe.cpp b/src/hotspot/share/prims/unsafe.cpp
index 87658f1..6807fca 100644
--- a/src/hotspot/share/prims/unsafe.cpp
+++ b/src/hotspot/share/prims/unsafe.cpp
@@ -798,7 +798,6 @@
 
 static void post_thread_park_event(EventThreadPark* event, const oop obj, jlong timeout_nanos, jlong until_epoch_millis) {
   assert(event != NULL, "invariant");
-  assert(event->should_commit(), "invariant");
   event->set_parkedClass((obj != NULL) ? obj->klass() : NULL);
   event->set_timeout(timeout_nanos);
   event->set_until(until_epoch_millis);
diff --git a/src/hotspot/share/prims/whitebox.cpp b/src/hotspot/share/prims/whitebox.cpp
index 319e18d..5466ff9 100644
--- a/src/hotspot/share/prims/whitebox.cpp
+++ b/src/hotspot/share/prims/whitebox.cpp
@@ -2369,6 +2369,10 @@
   }
 WB_END
 
+WB_ENTRY(void, WB_CleanMetaspaces(JNIEnv* env, jobject target))
+  ClassLoaderDataGraph::safepoint_and_clean_metaspaces();
+WB_END
+
 #define CC (char*)
 
 static JNINativeMethod methods[] = {
@@ -2637,6 +2641,7 @@
   {CC"lockCritical",    CC"()V",                      (void*)&WB_LockCritical},
   {CC"unlockCritical",  CC"()V",                      (void*)&WB_UnlockCritical},
   {CC"preTouchMemory",  CC"(JJ)V",                    (void*)&WB_PreTouchMemory},
+  {CC"cleanMetaspaces", CC"()V",                      (void*)&WB_CleanMetaspaces},
 };
 
 
diff --git a/src/hotspot/share/runtime/abstract_vm_version.cpp b/src/hotspot/share/runtime/abstract_vm_version.cpp
index 20a7957..738714f 100644
--- a/src/hotspot/share/runtime/abstract_vm_version.cpp
+++ b/src/hotspot/share/runtime/abstract_vm_version.cpp
@@ -243,6 +243,16 @@
         #define HOTSPOT_BUILD_COMPILER "MS VC++ 17.2 (VS2022)"
       #elif _MSC_VER == 1933
         #define HOTSPOT_BUILD_COMPILER "MS VC++ 17.3 (VS2022)"
+      #elif _MSC_VER == 1934
+        #define HOTSPOT_BUILD_COMPILER "MS VC++ 17.4 (VS2022)"
+      #elif _MSC_VER == 1935
+        #define HOTSPOT_BUILD_COMPILER "MS VC++ 17.5 (VS2022)"
+      #elif _MSC_VER == 1936
+        #define HOTSPOT_BUILD_COMPILER "MS VC++ 17.6 (VS2022)"
+      #elif _MSC_VER == 1937
+        #define HOTSPOT_BUILD_COMPILER "MS VC++ 17.7 (VS2022)"
+      #elif _MSC_VER == 1938
+        #define HOTSPOT_BUILD_COMPILER "MS VC++ 17.8 (VS2022)"
       #else
         #define HOTSPOT_BUILD_COMPILER "unknown MS VC++:" XSTR(_MSC_VER)
       #endif
diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp
index a62bd67..ed1bfe1 100644
--- a/src/hotspot/share/runtime/arguments.cpp
+++ b/src/hotspot/share/runtime/arguments.cpp
@@ -424,6 +424,30 @@
   os::init_system_properties_values();
 }
 
+static const char * get_virtualization_type() {
+    VirtualizationType vrt = VM_Version::get_detected_virtualization();
+    if (vrt == XenHVM || vrt == XenPVHVM) {
+        return "Xen";
+    } else if (vrt == KVM) {
+        return "KVM";
+    } else if (vrt == VMWare) {
+        return "VMWare";
+    } else if (vrt == HyperV) {
+        return "HyperV";
+    } else if (vrt == HyperVRole) {
+        // Enables users to create and manage virtual machines (VMs) on a physical host machine,
+        // but doesn't mean we are running in virtual.
+        return "none";
+    }
+
+    return "none";
+}
+
+void Arguments::post_init_system_properties() {
+    const char *virtualization_type = get_virtualization_type();
+    PropertyList_add(&_system_properties, new SystemProperty("intellij.os.virtualization", virtualization_type, false));
+}
+
 // Update/Initialize System properties after JDK version number is known
 void Arguments::init_version_specific_system_properties() {
   enum { bufsz = 16 };
diff --git a/src/hotspot/share/runtime/arguments.hpp b/src/hotspot/share/runtime/arguments.hpp
index 2f65f54..476551d 100644
--- a/src/hotspot/share/runtime/arguments.hpp
+++ b/src/hotspot/share/runtime/arguments.hpp
@@ -568,6 +568,8 @@
   // System properties
   static void init_system_properties();
 
+  static void post_init_system_properties();
+
   // Update/Initialize System properties after JDK version number is known
   static void init_version_specific_system_properties();
 
diff --git a/src/hotspot/share/runtime/atomic.hpp b/src/hotspot/share/runtime/atomic.hpp
index 7a71b6c..df23967 100644
--- a/src/hotspot/share/runtime/atomic.hpp
+++ b/src/hotspot/share/runtime/atomic.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -165,6 +165,82 @@
   inline static bool replace_if_null(D* volatile* dest, T* value,
                                      atomic_memory_order order = memory_order_conservative);
 
+  // Bitwise logical operations (and, or, xor)
+  //
+  // All operations apply the corresponding operation to the value in dest and
+  // bits, storing the result in dest. They return either the old value
+  // (fetch_then_BITOP) or the newly updated value (BITOP_then_fetch).
+  //
+  // Requirements:
+  // - T is an integral type
+  // - sizeof(T) == 1 || sizeof(T) == sizeof(int) || sizeof(T) == sizeof(void*)
+
+  // Performs atomic bitwise-and of *dest and bits, storing the result in
+  // *dest.  Returns the prior value of *dest.  That is, atomically performs
+  // this sequence of operations:
+  // { tmp = *dest; *dest &= bits; return tmp; }
+  template<typename T>
+  static T fetch_then_and(volatile T* dest, T bits,
+                          atomic_memory_order order = memory_order_conservative) {
+    static_assert(std::is_integral<T>::value, "bitop with non-integral type");
+    return PlatformBitops<sizeof(T)>().fetch_then_and(dest, bits, order);
+  }
+
+  // Performs atomic bitwise-or of *dest and bits, storing the result in
+  // *dest.  Returns the prior value of *dest.  That is, atomically performs
+  // this sequence of operations:
+  // { tmp = *dest; *dest |= bits; return tmp; }
+  template<typename T>
+  static T fetch_then_or(volatile T* dest, T bits,
+                         atomic_memory_order order = memory_order_conservative) {
+    static_assert(std::is_integral<T>::value, "bitop with non-integral type");
+    return PlatformBitops<sizeof(T)>().fetch_then_or(dest, bits, order);
+  }
+
+  // Performs atomic bitwise-xor of *dest and bits, storing the result in
+  // *dest.  Returns the prior value of *dest.  That is, atomically performs
+  // this sequence of operations:
+  // { tmp = *dest; *dest ^= bits; return tmp; }
+  template<typename T>
+  static T fetch_then_xor(volatile T* dest, T bits,
+                          atomic_memory_order order = memory_order_conservative) {
+    static_assert(std::is_integral<T>::value, "bitop with non-integral type");
+    return PlatformBitops<sizeof(T)>().fetch_then_xor(dest, bits, order);
+  }
+
+  // Performs atomic bitwise-and of *dest and bits, storing the result in
+  // *dest.  Returns the new value of *dest.  That is, atomically performs
+  // this operation:
+  // { return *dest &= bits; }
+  template<typename T>
+  static T and_then_fetch(volatile T* dest, T bits,
+                          atomic_memory_order order = memory_order_conservative) {
+    static_assert(std::is_integral<T>::value, "bitop with non-integral type");
+    return PlatformBitops<sizeof(T)>().and_then_fetch(dest, bits, order);
+  }
+
+  // Performs atomic bitwise-or of *dest and bits, storing the result in
+  // *dest.  Returns the new value of *dest.  That is, atomically performs
+  // this operation:
+  // { return *dest |= bits; }
+  template<typename T>
+  static T or_then_fetch(volatile T* dest, T bits,
+                         atomic_memory_order order = memory_order_conservative) {
+    static_assert(std::is_integral<T>::value, "bitop with non-integral type");
+    return PlatformBitops<sizeof(T)>().or_then_fetch(dest, bits, order);
+  }
+
+  // Performs atomic bitwise-xor of *dest and bits, storing the result in
+  // *dest.  Returns the new value of *dest.  That is, atomically performs
+  // this operation:
+  // { return *dest ^= bits; }
+  template<typename T>
+  static T xor_then_fetch(volatile T* dest, T bits,
+                          atomic_memory_order order = memory_order_conservative) {
+    static_assert(std::is_integral<T>::value, "bitop with non-integral type");
+    return PlatformBitops<sizeof(T)>().xor_then_fetch(dest, bits, order);
+  }
+
 private:
 WINDOWS_ONLY(public:) // VS2017 warns (C2027) use of undefined type if IsPointerConvertible is declared private
   // Test whether From is implicitly convertible to To.
@@ -240,10 +316,11 @@
   // bytes and (if different) pointer size bytes are required.  The
   // class must be default constructable, with these requirements:
   //
-  // - dest is of type D*, an integral or pointer type.
+  // - dest is of type D*, where D is an integral or pointer type.
   // - add_value is of type I, an integral type.
   // - sizeof(I) == sizeof(D).
   // - if D is an integral type, I == D.
+  // - if D is a pointer type P*, sizeof(P) == 1.
   // - order is of type atomic_memory_order.
   // - platform_add is an object of type PlatformAdd<sizeof(D)>.
   //
@@ -258,9 +335,17 @@
   // fetch_and_add atomically adds add_value to the value of dest,
   // returning the old value.
   //
-  // When D is a pointer type P*, both add_and_fetch and fetch_and_add
-  // treat it as if it were an uintptr_t; they do not perform any
-  // scaling of add_value, as that has already been done by the caller.
+  // When the destination type D of the Atomic operation is a pointer type P*,
+  // the addition must scale the add_value by sizeof(P) to add that many bytes
+  // to the destination value.  Rather than requiring each platform deal with
+  // this, the shared part of the implementation performs some adjustments
+  // before and after calling the platform operation.  It ensures the pointee
+  // type of the destination value passed to the platform operation has size
+  // 1, casting if needed.  It also scales add_value by sizeof(P).  The result
+  // of the platform operation is cast back to P*.  This means the platform
+  // operation does not need to account for the scaling.  It also makes it
+  // easy for the platform to implement one of add_and_fetch or fetch_and_add
+  // in terms of the other (which is a common approach).
   //
   // No definition is provided; all platforms must explicitly define
   // this class and any needed specializations.
@@ -364,6 +449,44 @@
   static T xchg_using_helper(Fn fn,
                              T volatile* dest,
                              T exchange_value);
+
+  // Platform-specific implementation of the bitops (and, or, xor).  Support
+  // for sizes of 4 bytes and (if different) pointer size bytes are required.
+  // The class is a function object that must be default constructable, with
+  // these requirements:
+  //
+  // - T is an integral type.
+  // - dest is of type T*.
+  // - bits is of type T.
+  // - order is of type atomic_memory_order.
+  // - platform_bitops is an object of type PlatformBitops<sizeof(T)>.
+  //
+  // Then
+  //  platform_bitops.fetch_then_and(dest, bits, order)
+  //  platform_bitops.fetch_then_or(dest, bits, order)
+  //  platform_bitops.fetch_then_xor(dest, bits, order)
+  //  platform_bitops.and_then_fetch(dest, bits, order)
+  //  platform_bitops.or_then_fetch(dest, bits, order)
+  //  platform_bitops.xor_then_fetch(dest, bits, order)
+  // must all be valid expressions, returning a result convertible to T.
+  //
+  // A default definition is provided, which implements all of the operations
+  // using cmpxchg.
+  //
+  // For each required size, a platform must either use the default or
+  // entirely specialize the class for that size by providing all of the
+  // required operations.
+  //
+  // The second (bool) template parameter allows platforms to provide a
+  // partial specialization with a parameterized size, and is otherwise
+  // unused.  The default value for that bool parameter means specializations
+  // don't need to mention it.
+  template<size_t size, bool = true> class PlatformBitops;
+
+  // Helper base classes that may be used to implement PlatformBitops.
+  class PrefetchBitopsUsingCmpxchg;
+  class PostfetchBitopsUsingCmpxchg;
+  class PostfetchBitopsUsingPrefetch;
 };
 
 template<typename From, typename To>
@@ -380,12 +503,12 @@
   static const bool value = (sizeof(yes) == sizeof(test(test_value)));
 };
 
-// Handle load for pointer, integral and enum types.
+// Handle load for pointer and integral types.
 template<typename T, typename PlatformOp>
 struct Atomic::LoadImpl<
   T,
   PlatformOp,
-  typename EnableIf<IsIntegral<T>::value || std::is_enum<T>::value || IsPointer<T>::value>::type>
+  typename EnableIf<IsIntegral<T>::value || IsPointer<T>::value>::type>
 {
   T operator()(T const volatile* dest) const {
     // Forward to the platform handler for the size of T.
@@ -430,14 +553,14 @@
   }
 };
 
-// Handle store for integral and enum types.
+// Handle store for integral types.
 //
 // All the involved types must be identical.
 template<typename T, typename PlatformOp>
 struct Atomic::StoreImpl<
   T, T,
   PlatformOp,
-  typename EnableIf<IsIntegral<T>::value || std::is_enum<T>::value>::type>
+  typename EnableIf<IsIntegral<T>::value>::type>
 {
   void operator()(T volatile* dest, T new_value) const {
     // Forward to the platform handler for the size of T.
@@ -573,6 +696,99 @@
                atomic_memory_order order) const;
 };
 
+// Implement fetch_then_bitop operations using a CAS loop.
+class Atomic::PrefetchBitopsUsingCmpxchg {
+  template<typename T, typename Op>
+  T bitop(T volatile* dest, atomic_memory_order order, Op operation) const {
+    T old_value;
+    T new_value;
+    T fetched_value = Atomic::load(dest);
+    do {
+      old_value = fetched_value;
+      new_value = operation(old_value);
+      fetched_value = Atomic::cmpxchg(dest, old_value, new_value, order);
+    } while (old_value != fetched_value);
+    return fetched_value;
+  }
+
+public:
+  template<typename T>
+  T fetch_then_and(T volatile* dest, T bits, atomic_memory_order order) const {
+    return bitop(dest, order, [&](T value) -> T { return value & bits; });
+  }
+
+  template<typename T>
+  T fetch_then_or(T volatile* dest, T bits, atomic_memory_order order) const {
+    return bitop(dest, order, [&](T value) -> T { return value | bits; });
+  }
+
+  template<typename T>
+  T fetch_then_xor(T volatile* dest, T bits, atomic_memory_order order) const {
+    return bitop(dest, order, [&](T value) -> T { return value ^ bits; });
+  }
+};
+
+// Implement bitop_then_fetch operations using a CAS loop.
+class Atomic::PostfetchBitopsUsingCmpxchg {
+  template<typename T, typename Op>
+  T bitop(T volatile* dest, atomic_memory_order order, Op operation) const {
+    T old_value;
+    T new_value;
+    T fetched_value = Atomic::load(dest);
+    do {
+      old_value = fetched_value;
+      new_value = operation(old_value);
+      fetched_value = Atomic::cmpxchg(dest, old_value, new_value, order);
+    } while (old_value != fetched_value);
+    return new_value;
+  }
+
+public:
+  template<typename T>
+  T and_then_fetch(T volatile* dest, T bits, atomic_memory_order order) const {
+    return bitop(dest, order, [&](T value) -> T { return value & bits; });
+  }
+
+  template<typename T>
+  T or_then_fetch(T volatile* dest, T bits, atomic_memory_order order) const {
+    return bitop(dest, order, [&](T value) -> T { return value | bits; });
+  }
+
+  template<typename T>
+  T xor_then_fetch(T volatile* dest, T bits, atomic_memory_order order) const {
+    return bitop(dest, order, [&](T value) -> T { return value ^ bits; });
+  }
+};
+
+// Implement bitop_then_fetch operations by calling fetch_then_bitop and
+// applying the operation to the result and the bits argument.
+class Atomic::PostfetchBitopsUsingPrefetch {
+public:
+  template<typename T>
+  T and_then_fetch(T volatile* dest, T bits, atomic_memory_order order) const {
+    return bits & Atomic::fetch_then_and(dest, bits, order);
+  }
+
+  template<typename T>
+  T or_then_fetch(T volatile* dest, T bits, atomic_memory_order order) const {
+    return bits | Atomic::fetch_then_or(dest, bits, order);
+  }
+
+  template<typename T>
+  T xor_then_fetch(T volatile* dest, T bits, atomic_memory_order order) const {
+    return bits ^ Atomic::fetch_then_xor(dest, bits, order);
+  }
+};
+
+// The default definition uses cmpxchg.  Platforms can override by defining a
+// partial specialization providing size, either as a template parameter or as
+// a specific value.
+template<size_t size, bool>
+class Atomic::PlatformBitops
+  : public PrefetchBitopsUsingCmpxchg,
+    public PostfetchBitopsUsingCmpxchg
+{};
+
 template <ScopedFenceType T>
 class ScopedFenceGeneral: public StackObj {
  public:
@@ -690,21 +906,43 @@
 {
   STATIC_ASSERT(sizeof(intptr_t) == sizeof(P*));
   STATIC_ASSERT(sizeof(uintptr_t) == sizeof(P*));
-  typedef typename Conditional<IsSigned<I>::value,
-                               intptr_t,
-                               uintptr_t>::type CI;
 
-  static CI scale_addend(CI add_value) {
-    return add_value * sizeof(P);
+  // Type of the scaled addend.  An integral type of the same size as a
+  // pointer, and the same signedness as I.
+  using SI = typename Conditional<IsSigned<I>::value, intptr_t, uintptr_t>::type;
+
+  // Type of the unscaled destination.  A pointer type with pointee size == 1.
+  using UP = const char*;
+
+  // Scale add_value by the size of the pointee.
+  static SI scale_addend(SI add_value) {
+    return add_value * SI(sizeof(P));
   }
 
-  static P* add_and_fetch(P* volatile* dest, I add_value, atomic_memory_order order) {
-    CI addend = add_value;
-    return PlatformAdd<sizeof(P*)>().add_and_fetch(dest, scale_addend(addend), order);
+  // Casting between P* and UP* here intentionally uses C-style casts,
+  // because reinterpret_cast can't cast away cv qualifiers.  Using copy_cv
+  // would be an alternative if it existed.
+
+  // Unscale dest to a char* pointee for consistency with scaled addend.
+  static UP volatile* unscale_dest(P* volatile* dest) {
+    return (UP volatile*) dest;
   }
-  static P* fetch_and_add(P* volatile* dest, I add_value, atomic_memory_order order) {
-    CI addend = add_value;
-    return PlatformAdd<sizeof(P*)>().fetch_and_add(dest, scale_addend(addend), order);
+
+  // Convert the unscaled char* result to a P*.
+  static P* scale_result(UP result) {
+    return (P*) result;
+  }
+
+  static P* add_and_fetch(P* volatile* dest, I addend, atomic_memory_order order) {
+    return scale_result(PlatformAdd<sizeof(P*)>().add_and_fetch(unscale_dest(dest),
+                                                                scale_addend(addend),
+                                                                order));
+  }
+
+  static P* fetch_and_add(P* volatile* dest, I addend, atomic_memory_order order) {
+    return scale_result(PlatformAdd<sizeof(P*)>().fetch_and_add(unscale_dest(dest),
+                                                                scale_addend(addend),
+                                                                order));
   }
 };
 
@@ -733,13 +971,13 @@
   return expected_null == cmpxchg(dest, expected_null, value, order);
 }
 
-// Handle cmpxchg for integral and enum types.
+// Handle cmpxchg for integral types.
 //
 // All the involved types must be identical.
 template<typename T>
 struct Atomic::CmpxchgImpl<
   T, T, T,
-  typename EnableIf<IsIntegral<T>::value || std::is_enum<T>::value>::type>
+  typename EnableIf<IsIntegral<T>::value>::type>
 {
   T operator()(T volatile* dest, T compare_value, T exchange_value,
                atomic_memory_order order) const {
@@ -818,14 +1056,14 @@
 inline uint32_t Atomic::CmpxchgByteUsingInt::set_byte_in_int(uint32_t n,
                                                              uint8_t b,
                                                              uint32_t idx) {
-  int bitsIdx = BitsPerByte * idx;
+  uint32_t bitsIdx = BitsPerByte * idx;
   return (n & ~(static_cast<uint32_t>(0xff) << bitsIdx))
           | (static_cast<uint32_t>(b) << bitsIdx);
 }
 
 inline uint8_t Atomic::CmpxchgByteUsingInt::get_byte_in_int(uint32_t n,
                                                             uint32_t idx) {
-  int bitsIdx = BitsPerByte * idx;
+  uint32_t bitsIdx = BitsPerByte * idx;
   return (uint8_t)(n >> bitsIdx);
 }
 
@@ -868,13 +1106,13 @@
   return PrimitiveConversions::cast<T>(get_byte_in_int(cur, idx));
 }
 
-// Handle xchg for integral and enum types.
+// Handle xchg for integral types.
 //
 // All the involved types must be identical.
 template<typename T>
 struct Atomic::XchgImpl<
   T, T,
-  typename EnableIf<IsIntegral<T>::value || std::is_enum<T>::value>::type>
+  typename EnableIf<IsIntegral<T>::value>::type>
 {
   T operator()(T volatile* dest, T exchange_value, atomic_memory_order order) const {
     // Forward to the platform handler for the size of T.
diff --git a/src/hotspot/share/runtime/globals.hpp b/src/hotspot/share/runtime/globals.hpp
index 2de46d0..3456889 100644
--- a/src/hotspot/share/runtime/globals.hpp
+++ b/src/hotspot/share/runtime/globals.hpp
@@ -292,6 +292,9 @@
   product(bool, UseInlineCaches, true,                                      \
           "Use Inline Caches for virtual calls ")                           \
                                                                             \
+  product(size_t, InlineCacheBufferSize, 10*K, EXPERIMENTAL,                \
+          "InlineCacheBuffer size")                                         \
+                                                                            \
   product(bool, InlineArrayCopy, true, DIAGNOSTIC,                          \
           "Inline arraycopy native that is known to be part of "            \
           "base library DLL")                                               \
@@ -2094,6 +2097,14 @@
   develop(bool, TraceOptimizedUpcallStubs, false,                              \
                 "Trace optimized upcall stub generation")                      \
                                                                             \
+  product(bool, ProfileExceptionHandlers, true,                             \
+          "Profile exception handlers")                                     \
+                                                                            \
+  product(bool, AlwaysRecordEvolDependencies, true, EXPERIMENTAL,           \
+                "Unconditionally record nmethod dependencies on class "     \
+                "rewriting/transformation independently of the JVMTI "      \
+                "can_{retransform/redefine}_classes capabilities.")         \
+                                                                            \
   product(bool, AllowEnhancedClassRedefinition, false,                      \
              "Allow enhanced class redefinition beyond swapping method "    \
              "bodies")                                                      \
diff --git a/src/hotspot/share/runtime/init.cpp b/src/hotspot/share/runtime/init.cpp
index 06974b8..c68fa08 100644
--- a/src/hotspot/share/runtime/init.cpp
+++ b/src/hotspot/share/runtime/init.cpp
@@ -39,6 +39,7 @@
 #include "prims/jvmtiExport.hpp"
 #include "prims/methodHandles.hpp"
 #include "prims/universalNativeInvoker.hpp"
+#include "runtime/arguments.hpp"
 #include "runtime/globals.hpp"
 #include "runtime/atomic.hpp"
 #include "runtime/flags/jvmFlag.hpp"
@@ -113,6 +114,12 @@
 jint init_globals() {
   management_init();
   JvmtiExport::initialize_oop_storage();
+#if INCLUDE_JVMTI
+  if (AlwaysRecordEvolDependencies) {
+    JvmtiExport::set_can_hotswap_or_post_breakpoint(true);
+    JvmtiExport::set_all_dependencies_are_recorded(true);
+  }
+#endif
   bytecodes_init();
   classLoader_init1();
   compilationPolicy_init();
@@ -124,6 +131,7 @@
   if (status != JNI_OK)
     return status;
 
+  Arguments::post_init_system_properties();
   AsyncLogWriter::initialize();
   gc_barrier_stubs_init();  // depends on universe_init, must be before interpreter_init
   interpreter_init_stub();  // before methods get loaded
diff --git a/src/hotspot/share/runtime/interfaceSupport.inline.hpp b/src/hotspot/share/runtime/interfaceSupport.inline.hpp
index ffc940e..844e0cb 100644
--- a/src/hotspot/share/runtime/interfaceSupport.inline.hpp
+++ b/src/hotspot/share/runtime/interfaceSupport.inline.hpp
@@ -464,6 +464,7 @@
 #define JVM_ENTRY_FROM_LEAF(env, result_type, header)                \
   { {                                                                \
     JavaThread* thread=JavaThread::thread_from_jni_environment(env); \
+    MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, thread));        \
     ThreadInVMfromNative __tiv(thread);                              \
     debug_only(VMNativeEntryWrapper __vew;)                          \
     VM_ENTRY_BASE_FROM_LEAF(result_type, header, thread)
diff --git a/src/hotspot/share/runtime/mutexLocker.cpp b/src/hotspot/share/runtime/mutexLocker.cpp
index 85ea69e..447af14 100644
--- a/src/hotspot/share/runtime/mutexLocker.cpp
+++ b/src/hotspot/share/runtime/mutexLocker.cpp
@@ -231,9 +231,9 @@
 
     def(MarkStackFreeList_lock     , PaddedMutex  , leaf     ,   true,  _safepoint_check_never);
     def(MarkStackChunkList_lock    , PaddedMutex  , leaf     ,   true,  _safepoint_check_never);
-
-    def(MonitoringSupport_lock     , PaddedMutex  , native   ,   true,  _safepoint_check_never);      // used for serviceability monitoring support
   }
+  def(MonitoringSupport_lock       , PaddedMutex  , native   ,   true,  _safepoint_check_never);      // used for serviceability monitoring support
+
   def(StringDedup_lock             , PaddedMonitor, leaf,        true,  _safepoint_check_never);
   def(StringDedupIntern_lock       , PaddedMutex  , leaf,        true,  _safepoint_check_never);
   def(ParGCRareEvent_lock          , PaddedMutex  , leaf,        true,  _safepoint_check_always);
diff --git a/src/hotspot/share/runtime/mutexLocker.hpp b/src/hotspot/share/runtime/mutexLocker.hpp
index d16d587..7c724eb 100644
--- a/src/hotspot/share/runtime/mutexLocker.hpp
+++ b/src/hotspot/share/runtime/mutexLocker.hpp
@@ -74,7 +74,7 @@
 extern Mutex*   G1DetachedRefinementStats_lock;  // Lock protecting detached refinement stats
 extern Mutex*   MarkStackFreeList_lock;          // Protects access to the global mark stack free list.
 extern Mutex*   MarkStackChunkList_lock;         // Protects access to the global mark stack chunk list.
-extern Mutex*   MonitoringSupport_lock;          // Protects updates to the serviceability memory pools.
+extern Mutex*   MonitoringSupport_lock;          // Protects updates to the serviceability memory pools and allocated memory high water mark.
 extern Mutex*   ParGCRareEvent_lock;             // Synchronizes various (rare) parallel GC ops.
 extern Monitor* ConcurrentGCBreakpoints_lock;    // Protects concurrent GC breakpoint management
 extern Mutex*   Compile_lock;                    // a lock held when Compilation is updating code (used to block CodeCache traversal, CHA updates, etc)
diff --git a/src/hotspot/share/runtime/synchronizer.cpp b/src/hotspot/share/runtime/synchronizer.cpp
index bf278ea..5be659e 100644
--- a/src/hotspot/share/runtime/synchronizer.cpp
+++ b/src/hotspot/share/runtime/synchronizer.cpp
@@ -1224,7 +1224,6 @@
                                        const oop obj,
                                        ObjectSynchronizer::InflateCause cause) {
   assert(event != NULL, "invariant");
-  assert(event->should_commit(), "invariant");
   event->set_monitorClass(obj->klass());
   event->set_address((uintptr_t)(void*)obj);
   event->set_cause((u1)cause);
diff --git a/src/hotspot/share/runtime/vmThread.cpp b/src/hotspot/share/runtime/vmThread.cpp
index 0422a00..6939208 100644
--- a/src/hotspot/share/runtime/vmThread.cpp
+++ b/src/hotspot/share/runtime/vmThread.cpp
@@ -245,7 +245,6 @@
 
 static void post_vm_operation_event(EventExecuteVMOperation* event, VM_Operation* op) {
   assert(event != NULL, "invariant");
-  assert(event->should_commit(), "invariant");
   assert(op != NULL, "invariant");
   const bool evaluate_at_safepoint = op->evaluate_at_safepoint();
   event->set_operation(op->type());
diff --git a/src/hotspot/share/services/dtraceAttacher.hpp b/src/hotspot/share/services/dtraceAttacher.hpp
deleted file mode 100644
index 1faf1ad..0000000
--- a/src/hotspot/share/services/dtraceAttacher.hpp
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2006, 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_SERVICES_DTRACEATTACHER_HPP
-#define SHARE_SERVICES_DTRACEATTACHER_HPP
-
-#define DTRACE_ALLOC_PROBES    0x1
-#define DTRACE_METHOD_PROBES   0x2
-#define DTRACE_MONITOR_PROBES  0x4
-#define DTRACE_ALL_PROBES      (DTRACE_ALLOC_PROBES  | \
-                                DTRACE_METHOD_PROBES | \
-                                DTRACE_MONITOR_PROBES)
-
-class DTrace : public AllStatic {
- private:
-  // disable one or more probes - OR above constants
-  static void disable_dprobes(int probe_types);
-
- public:
-  // enable one or more probes - OR above constants
-  static void enable_dprobes(int probe_types);
-  // all clients detached, do any clean-up
-  static void detach_all_clients();
-  // set ExtendedDTraceProbes flag
-  static void set_extended_dprobes(bool value);
-  // set DTraceMonitorProbes flag
-  static void set_monitor_dprobes(bool value);
-};
-
-#endif // SHARE_SERVICES_DTRACEATTACHER_HPP
diff --git a/src/hotspot/share/services/management.cpp b/src/hotspot/share/services/management.cpp
index a6c1efe..bce504c 100644
--- a/src/hotspot/share/services/management.cpp
+++ b/src/hotspot/share/services/management.cpp
@@ -47,6 +47,7 @@
 #include "runtime/interfaceSupport.inline.hpp"
 #include "runtime/javaCalls.hpp"
 #include "runtime/jniHandles.inline.hpp"
+#include "runtime/mutexLocker.hpp"
 #include "runtime/notificationThread.hpp"
 #include "runtime/os.hpp"
 #include "runtime/thread.inline.hpp"
@@ -413,8 +414,6 @@
   return MemoryService::get_memory_pool(ph);
 }
 
-#endif // INCLUDE_MANAGEMENT
-
 static void validate_thread_id_array(typeArrayHandle ids_ah, TRAPS) {
   int num_threads = ids_ah->length();
 
@@ -430,8 +429,6 @@
   }
 }
 
-#if INCLUDE_MANAGEMENT
-
 static void validate_thread_info_array(objArrayHandle infoArray_h, TRAPS) {
   // check if the element of infoArray is of type ThreadInfo class
   Klass* threadinfo_klass = Management::java_lang_management_ThreadInfo_klass(CHECK);
@@ -2065,7 +2062,42 @@
   return (jlong)(((double)ticks / (double)os::elapsed_frequency())
                  * (double)1000.0);
 }
-#endif // INCLUDE_MANAGEMENT
+
+// Gets the amount of memory allocated on the Java heap since JVM launch.
+JVM_ENTRY(jlong, jmm_GetTotalThreadAllocatedMemory(JNIEnv *env))
+    // A thread increments exited_allocated_bytes in ThreadService::remove_thread
+    // only after it removes itself from the threads list, and once a TLH is
+    // created, no thread it references can remove itself from the threads
+    // list, so none can update exited_allocated_bytes. We therefore initialize
+    // result with exited_allocated_bytes after after we create the TLH so that
+    // the final result can only be short due to (1) threads that start after
+    // the TLH is created, or (2) terminating threads that escape TLH creation
+    // and don't update exited_allocated_bytes before we initialize result.
+
+    // We keep a high water mark to ensure monotonicity in case threads counted
+    // on a previous call end up in state (2).
+    static jlong high_water_result = 0;
+
+    JavaThreadIteratorWithHandle jtiwh;
+    jlong result = ThreadService::exited_allocated_bytes();
+    for (; JavaThread* thread = jtiwh.next();) {
+      jlong size = thread->cooked_allocated_bytes();
+      result += size;
+    }
+
+    {
+      assert(MonitoringSupport_lock != nullptr, "Must be");
+      MutexLocker ml(MonitoringSupport_lock, Mutex::_no_safepoint_check_flag);
+      if (result < high_water_result) {
+        // Encountered (2) above, or result wrapped to a negative value. In
+        // the latter case, it's pegged at the last positive value.
+        result = high_water_result;
+      } else {
+        high_water_result = result;
+      }
+    }
+    return result;
+JVM_END
 
 // Gets the amount of memory allocated on the Java heap for a single thread.
 // Returns -1 if the thread does not exist or has terminated.
@@ -2199,9 +2231,6 @@
   }
 JVM_END
 
-
-
-#if INCLUDE_MANAGEMENT
 const struct jmmInterface_1_ jmm_interface = {
   NULL,
   NULL,
@@ -2235,7 +2264,7 @@
   jmm_DumpHeap0,
   jmm_FindDeadlockedThreads,
   jmm_SetVMGlobal,
-  NULL,
+  jmm_GetTotalThreadAllocatedMemory,
   jmm_DumpThreads,
   jmm_SetGCNotificationEnabled,
   jmm_GetDiagnosticCommands,
diff --git a/src/hotspot/share/services/threadService.cpp b/src/hotspot/share/services/threadService.cpp
index 7a143db..51db7f1 100644
--- a/src/hotspot/share/services/threadService.cpp
+++ b/src/hotspot/share/services/threadService.cpp
@@ -68,6 +68,8 @@
 volatile int ThreadService::_atomic_threads_count = 0;
 volatile int ThreadService::_atomic_daemon_threads_count = 0;
 
+volatile jlong ThreadService::_exited_allocated_bytes = 0;
+
 ThreadDumpResult* ThreadService::_threaddump_list = NULL;
 
 static const int INITIAL_ARRAY_SIZE = 10;
@@ -155,6 +157,9 @@
 void ThreadService::remove_thread(JavaThread* thread, bool daemon) {
   assert(Threads_lock->owned_by_self(), "must have threads lock");
 
+  // Include hidden thread allcations in exited_allocated_bytes
+  ThreadService::incr_exited_allocated_bytes(thread->cooked_allocated_bytes());
+
   // Do not count hidden threads
   if (is_hidden_thread(thread)) {
     return;
diff --git a/src/hotspot/share/services/threadService.hpp b/src/hotspot/share/services/threadService.hpp
index be16a96..bda5982 100644
--- a/src/hotspot/share/services/threadService.hpp
+++ b/src/hotspot/share/services/threadService.hpp
@@ -60,6 +60,10 @@
   static PerfVariable* _peak_threads_count;
   static PerfVariable* _daemon_threads_count;
 
+  // As could this...
+  // Number of heap bytes allocated by terminated threads.
+  static volatile jlong _exited_allocated_bytes;
+
   // These 2 counters are like the above thread counts, but are
   // atomically decremented in ThreadService::current_thread_exiting instead of
   // ThreadService::remove_thread, so that the thread count is updated before
@@ -98,6 +102,14 @@
   static jlong get_live_thread_count()        { return _atomic_threads_count; }
   static jlong get_daemon_thread_count()      { return _atomic_daemon_threads_count; }
 
+  static jlong exited_allocated_bytes()       { return Atomic::load(&_exited_allocated_bytes); }
+  static void incr_exited_allocated_bytes(jlong size) {
+    // No need for an atomic add because called under the Threads_lock,
+    // but because _exited_allocated_bytes is read concurrently, need
+    // atomic store to avoid readers seeing a partial update.
+    Atomic::store(&_exited_allocated_bytes, _exited_allocated_bytes + size);
+  }
+
   // Support for thread dump
   static void   add_thread_dump(ThreadDumpResult* dump);
   static void   remove_thread_dump(ThreadDumpResult* dump);
diff --git a/src/hotspot/share/utilities/exceptions.cpp b/src/hotspot/share/utilities/exceptions.cpp
index bd95b83..d65f5bc 100644
--- a/src/hotspot/share/utilities/exceptions.cpp
+++ b/src/hotspot/share/utilities/exceptions.cpp
@@ -563,11 +563,11 @@
 // for logging exceptions
 void Exceptions::log_exception(Handle exception, const char* message) {
   ResourceMark rm;
-  Symbol* detail_message = java_lang_Throwable::detail_message(exception());
-  if (detail_message != NULL) {
+  const char* detail_message = java_lang_Throwable::message_as_utf8(exception());
+  if (detail_message != nullptr) {
     log_info(exceptions)("Exception <%s: %s>\n thrown in %s",
                          exception->print_value_string(),
-                         detail_message->as_C_string(),
+                         detail_message,
                          message);
   } else {
     log_info(exceptions)("Exception <%s>\n thrown in %s",
diff --git a/src/hotspot/share/utilities/vmError.cpp b/src/hotspot/share/utilities/vmError.cpp
index 5d60eee..81c33aa 100644
--- a/src/hotspot/share/utilities/vmError.cpp
+++ b/src/hotspot/share/utilities/vmError.cpp
@@ -74,6 +74,18 @@
 #include <signal.h>
 #endif // PRODUCT
 
+#ifdef LINUX
+#include "os_linux.hpp"
+#endif
+
+#ifdef _WINDOWS
+#include <psapi.h>
+#endif
+
+#ifdef __APPLE__
+#include <mach/mach.h>
+#endif
+
 bool              VMError::coredump_status;
 char              VMError::coredump_message[O_BUFLEN];
 int               VMError::_current_step;
@@ -406,7 +418,7 @@
   st->print_cr("# Possible reasons:");
   st->print_cr("#   The system is out of physical RAM or swap space");
   if (UseCompressedOops) {
-    st->print_cr("#   The process is running with CompressedOops enabled, and the Java Heap may be blocking the growth of the native heap");
+    st->print_cr("#   This process is running with CompressedOops enabled, and the Java Heap may be blocking the growth of the native heap");
   }
   if (LogBytesPerWord == 2) {
     st->print_cr("#   In 32 bit mode, the process size limit was hit");
@@ -643,9 +655,9 @@
                                                       "(mprotect) failed to protect ");
            jio_snprintf(buf, sizeof(buf), SIZE_FORMAT, _size);
            st->print("%s", buf);
-           st->print(" bytes");
+           st->print(" bytes.");
            if (strlen(_detail_msg) > 0) {
-             st->print(" for ");
+             st->print(" Error detail: ");
              st->print("%s", _detail_msg);
            }
            st->cr();
@@ -1223,6 +1235,9 @@
   JNIHandles::print_on_unsafe(st);
   JNIHandles::print_memory_usage_on(st);
 
+  STEP("Process memory usage")
+  print_process_memory_usage(st);
+
   STEP("OOME stack traces")
   st->print_cr("OOME stack traces (most recent first):");
   print_oome_stacks(st);
@@ -1423,6 +1438,7 @@
   NativeHeapTrimmer::print_state(st);
   st->cr();
 
+  print_process_memory_usage(st);
 
   // STEP("printing system")
   st->print_cr("---------------  S Y S T E M  ---------------");
@@ -2224,3 +2240,73 @@
     }
   }
 }
+
+#ifdef LINUX
+static void print_process_memory_usage_platform(outputStream *st)
+{
+  // See also os::Linux::print_process_memory_info()
+  os::Linux::meminfo_t info;
+  if (os::Linux::query_process_memory_info(&info)) {
+    ssize_t phys_total_kb = os::physical_memory() / K;
+    ssize_t phys_avail_kb = os::available_memory() / K;
+    int rss_percentile = (int)(info.vmrss * 100.0 / phys_total_kb);
+    st->print_cr("Resident Set Size: " SSIZE_FORMAT "K (%d%% of "
+                 SSIZE_FORMAT "K total physical memory with " SSIZE_FORMAT "K free physical memory)",
+                 info.vmrss, rss_percentile, phys_total_kb, phys_avail_kb);
+  } else {
+    st->print_cr("Could not open /proc/self/status to get process memory related information");
+  }
+}
+#endif
+
+#ifdef _WINDOWS
+static void print_process_memory_usage_platform(outputStream *st)
+{
+  // See os::jfr_report_memory_info() in os_windows.cpp
+  PROCESS_MEMORY_COUNTERS_EX pmex;
+  ZeroMemory(&pmex, sizeof(PROCESS_MEMORY_COUNTERS_EX));
+  pmex.cb = sizeof(pmex);
+
+  BOOL ret = GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*) &pmex, sizeof(pmex));
+  if (ret != 0) {
+    ssize_t rss_kb = pmex.WorkingSetSize / K;
+    ssize_t phys_total_kb = os::physical_memory() / K;
+    ssize_t phys_avail_kb = os::available_memory() / K;
+    int rss_percentile = (int)(rss_kb * 100.0 / phys_total_kb);
+    st->print_cr("Resident Set Size: " SSIZE_FORMAT "K (%d%% of "
+                 SSIZE_FORMAT "K total physical memory with " SSIZE_FORMAT "K free physical memory)",
+                 rss_kb, rss_percentile, phys_total_kb, phys_avail_kb);
+  } else {
+    st->print_cr("GetProcessMemoryInfo() call did not succeed");
+  }
+}
+#endif
+
+#ifdef __APPLE__
+static void print_process_memory_usage_platform(outputStream *st)
+{
+  // See os::jfr_report_memory_info() in os_bsd.cpp
+  mach_task_basic_info info;
+  mach_msg_type_number_t count = MACH_TASK_BASIC_INFO_COUNT;
+
+  kern_return_t ret = task_info(mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t)&info, &count);
+  if (ret == KERN_SUCCESS) {
+    ssize_t rss_kb = info.resident_size / K;
+    ssize_t phys_total_kb = os::physical_memory() / K;
+    ssize_t phys_avail_kb = os::available_memory() / K;
+    int rss_percentile = (int)(rss_kb * 100.0 / phys_total_kb);
+    st->print_cr("Resident Set Size: " SSIZE_FORMAT "K (%d%% of "
+                 SSIZE_FORMAT "K total physical memory with " SSIZE_FORMAT "K free physical memory)",
+                 rss_kb, rss_percentile, phys_total_kb, phys_avail_kb);
+  } else {
+    st->print_cr("task_info() call did not succeed");
+  }
+}
+#endif
+
+void VMError::print_process_memory_usage(outputStream *st)
+{
+  st->print_cr("Process memory usage:");
+  print_process_memory_usage_platform(st);
+  st->cr();
+}
diff --git a/src/hotspot/share/utilities/vmError.hpp b/src/hotspot/share/utilities/vmError.hpp
index 1fa9671..955451d 100644
--- a/src/hotspot/share/utilities/vmError.hpp
+++ b/src/hotspot/share/utilities/vmError.hpp
@@ -203,5 +203,6 @@
   static void print_oome_stacks(outputStream *st);
   static void print_classloaders_stats(outputStream *st);
   static void print_dup_classes(outputStream *st);
+  static void print_process_memory_usage(outputStream *st);
 };
 #endif // SHARE_UTILITIES_VMERROR_HPP
diff --git a/src/java.base/share/classes/java/io/Console.java b/src/java.base/share/classes/java/io/Console.java
index d3c1f61..92e2399 100644
--- a/src/java.base/share/classes/java/io/Console.java
+++ b/src/java.base/share/classes/java/io/Console.java
@@ -335,8 +335,17 @@
                         else
                             ioe.addSuppressed(x);
                     }
-                    if (ioe != null)
+                    if (ioe != null) {
+                        Arrays.fill(passwd, ' ');
+                        try {
+                            if (reader instanceof LineReader lr) {
+                                lr.zeroOut();
+                            }
+                        } catch (IOException x) {
+                            // ignore
+                        }
                         throw ioe;
+                    }
                 }
                 pw.println();
             }
@@ -445,6 +454,9 @@
             System.arraycopy(rcb, 0, b, 0, len);
             if (zeroOut) {
                 Arrays.fill(rcb, 0, len, ' ');
+                if (reader instanceof LineReader lr) {
+                    lr.zeroOut();
+                }
             }
         }
         return b;
@@ -469,6 +481,11 @@
             nextChar = nChars = 0;
             leftoverLF = false;
         }
+        public void zeroOut() throws IOException {
+            if (in instanceof StreamDecoder sd) {
+                sd.fillZeroToPosition();
+            }
+        }
         public void close () {}
         public boolean ready() throws IOException {
             //in.ready synchronizes on readLock already
diff --git a/src/java.base/share/classes/java/lang/Class.java b/src/java.base/share/classes/java/lang/Class.java
index b8bf7de..61cbc42 100644
--- a/src/java.base/share/classes/java/lang/Class.java
+++ b/src/java.base/share/classes/java/lang/Class.java
@@ -3788,12 +3788,13 @@
     // Fetches the factory for reflective objects
     @SuppressWarnings("removal")
     private static ReflectionFactory getReflectionFactory() {
-        if (reflectionFactory == null) {
-            reflectionFactory =
-                java.security.AccessController.doPrivileged
-                    (new ReflectionFactory.GetReflectionFactoryAction());
+        var factory = reflectionFactory;
+        if (factory != null) {
+            return factory;
         }
-        return reflectionFactory;
+        return reflectionFactory =
+                java.security.AccessController.doPrivileged
+                        (new ReflectionFactory.GetReflectionFactoryAction());
     }
     private static ReflectionFactory reflectionFactory;
 
diff --git a/src/java.base/share/classes/java/lang/System.java b/src/java.base/share/classes/java/lang/System.java
index c31da48..c77a626 100644
--- a/src/java.base/share/classes/java/lang/System.java
+++ b/src/java.base/share/classes/java/lang/System.java
@@ -2457,7 +2457,7 @@
             }
 
             public String getLoaderNameID(ClassLoader loader) {
-                return loader.nameAndId();
+                return loader != null ? loader.nameAndId() : "null";
             }
         });
     }
diff --git a/src/java.base/share/classes/java/lang/constant/MethodTypeDesc.java b/src/java.base/share/classes/java/lang/constant/MethodTypeDesc.java
index 4750231..24d5107 100644
--- a/src/java.base/share/classes/java/lang/constant/MethodTypeDesc.java
+++ b/src/java.base/share/classes/java/lang/constant/MethodTypeDesc.java
@@ -90,7 +90,7 @@
      * @param index the index of the parameter to retrieve
      * @return a {@link ClassDesc} describing the desired parameter type
      * @throws IndexOutOfBoundsException if the index is outside the half-open
-     * range {[0, parameterCount())}
+     * range {@code [0, parameterCount())}
      */
     ClassDesc parameterType(int index);
 
@@ -127,7 +127,7 @@
      * @return a {@linkplain MethodTypeDesc} describing the desired method type
      * @throws NullPointerException if any argument is {@code null}
      * @throws IndexOutOfBoundsException if the index is outside the half-open
-     * range {[0, parameterCount)}
+     * range {@code [0, parameterCount)}
      */
     MethodTypeDesc changeParameterType(int index, ClassDesc paramType);
 
@@ -154,7 +154,7 @@
      * @return a {@linkplain MethodTypeDesc} describing the desired method type
      * @throws NullPointerException if any argument or its contents are {@code null}
      * @throws IndexOutOfBoundsException if {@code pos} is outside the closed
-     * range {[0, parameterCount]}
+     * range {@code [0, parameterCount]}
      * @throws IllegalArgumentException if any element of {@code paramTypes}
      * is a {@link ClassDesc} for {@code void}
      */
diff --git a/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java b/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java
index 39f68ac..9353c51 100644
--- a/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java
+++ b/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java
@@ -2553,7 +2553,7 @@
     private static int modsHashCode(Iterable<? extends Enum<?>> enums) {
         int h = 0;
         for (Enum<?> e : enums) {
-            h = h * 43 + Objects.hashCode(e.name());
+            h += e.name().hashCode();
         }
         return h;
     }
diff --git a/src/java.base/share/classes/java/math/MutableBigInteger.java b/src/java.base/share/classes/java/math/MutableBigInteger.java
index f0dae7a..7d0ccbf 100644
--- a/src/java.base/share/classes/java/math/MutableBigInteger.java
+++ b/src/java.base/share/classes/java/math/MutableBigInteger.java
@@ -2106,6 +2106,7 @@
 
         oddPart.leftShift(powersOf2);
         oddPart.multiply(y1, result);
+        oddPart.clear();
 
         evenPart.multiply(oddMod, temp1);
         temp1.multiply(y2, temp2);
diff --git a/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java b/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java
index c506210..9a18002 100644
--- a/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java
+++ b/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedLongSynchronizer.java
@@ -1156,7 +1156,9 @@
          */
         private boolean canReacquire(ConditionNode node) {
             // check links, not status to avoid enqueue race
-            return node != null && node.prev != null && isEnqueued(node);
+            Node p; // traverse unless known to be bidirectionally linked
+            return node != null && (p = node.prev) != null &&
+                (p.next == node || isEnqueued(node));
         }
 
         /**
diff --git a/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java b/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java
index 921150f..618ba7b 100644
--- a/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java
+++ b/src/java.base/share/classes/java/util/concurrent/locks/AbstractQueuedSynchronizer.java
@@ -1524,7 +1524,9 @@
          */
         private boolean canReacquire(ConditionNode node) {
             // check links, not status to avoid enqueue race
-            return node != null && node.prev != null && isEnqueued(node);
+            Node p; // traverse unless known to be bidirectionally linked
+            return node != null && (p = node.prev) != null &&
+                (p.next == node || isEnqueued(node));
         }
 
         /**
diff --git a/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java b/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java
index 9654328..cbe4275 100644
--- a/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java
+++ b/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java
@@ -1317,53 +1317,74 @@
     }
 
     private void expect100Continue() throws IOException {
-            // Expect: 100-Continue was set, so check the return code for
-            // Acceptance
-            int oldTimeout = http.getReadTimeout();
-            boolean enforceTimeOut = false;
-            boolean timedOut = false;
-            if (oldTimeout <= 0) {
-                // 5s read timeout in case the server doesn't understand
-                // Expect: 100-Continue
-                http.setReadTimeout(5000);
-                enforceTimeOut = true;
+        // Expect: 100-Continue was set, so check the return code for
+        // Acceptance
+        int oldTimeout = http.getReadTimeout();
+        boolean timedOut = false;
+        boolean tempTimeOutSet = false;
+        if (oldTimeout <= 0 || oldTimeout > 5000) {
+            if (logger.isLoggable(PlatformLogger.Level.FINE)) {
+                logger.fine("Timeout currently set to " +
+                        oldTimeout + " temporarily setting it to 5 seconds");
             }
+            // 5s read timeout in case the server doesn't understand
+            // Expect: 100-Continue
+            http.setReadTimeout(5000);
+            tempTimeOutSet = true;
+        }
 
-            try {
-                http.parseHTTP(responses, pi, this);
-            } catch (SocketTimeoutException se) {
-                if (!enforceTimeOut) {
-                    throw se;
-                }
-                timedOut = true;
-                http.setIgnoreContinue(true);
+        try {
+            http.parseHTTP(responses, pi, this);
+        } catch (SocketTimeoutException se) {
+            if (logger.isLoggable(PlatformLogger.Level.FINE)) {
+                logger.fine("SocketTimeoutException caught," +
+                        " will attempt to send body regardless");
             }
-            if (!timedOut) {
-                // Can't use getResponseCode() yet
-                String resp = responses.getValue(0);
-                // Parse the response which is of the form:
-                // HTTP/1.1 417 Expectation Failed
-                // HTTP/1.1 100 Continue
-                if (resp != null && resp.startsWith("HTTP/")) {
-                    String[] sa = resp.split("\\s+");
-                    responseCode = -1;
-                    try {
-                        // Response code is 2nd token on the line
-                        if (sa.length > 1)
-                            responseCode = Integer.parseInt(sa[1]);
-                    } catch (NumberFormatException numberFormatException) {
+            timedOut = true;
+        }
+
+        if (!timedOut) {
+            // Can't use getResponseCode() yet
+            String resp = responses.getValue(0);
+            // Parse the response which is of the form:
+            // HTTP/1.1 417 Expectation Failed
+            // HTTP/1.1 100 Continue
+            if (resp != null && resp.startsWith("HTTP/")) {
+                String[] sa = resp.split("\\s+");
+                responseCode = -1;
+                try {
+                    // Response code is 2nd token on the line
+                    if (sa.length > 1)
+                        responseCode = Integer.parseInt(sa[1]);
+                    if (logger.isLoggable(PlatformLogger.Level.FINE)) {
+                        logger.fine("response code received " + responseCode);
                     }
-                }
-                if (responseCode != 100) {
-                    throw new ProtocolException("Server rejected operation");
+                } catch (NumberFormatException numberFormatException) {
                 }
             }
+            if (responseCode != 100) {
+                // responseCode will be returned to caller
+                throw new ProtocolException("Server rejected operation");
+            }
+        }
 
+        // If timeout was changed, restore to original value
+        if (tempTimeOutSet) {
+            if (logger.isLoggable(PlatformLogger.Level.FINE)) {
+                logger.fine("Restoring original timeout : " + oldTimeout);
+            }
             http.setReadTimeout(oldTimeout);
+        }
 
-            responseCode = -1;
-            responses.reset();
-            // Proceed
+        // Ignore any future 100 continue messages
+        http.setIgnoreContinue(true);
+        if (logger.isLoggable(PlatformLogger.Level.FINE)) {
+            logger.fine("Set Ignore Continue to true");
+        }
+
+        responseCode = -1;
+        responses.reset();
+        // Proceed
     }
 
     /*
@@ -1432,7 +1453,6 @@
             boolean expectContinue = false;
             String expects = requests.findValue("Expect");
             if ("100-Continue".equalsIgnoreCase(expects) && streaming()) {
-                http.setIgnoreContinue(false);
                 expectContinue = true;
             }
 
@@ -1441,6 +1461,7 @@
             }
 
             if (expectContinue) {
+                http.setIgnoreContinue(false);
                 expect100Continue();
             }
             ps = (PrintStream)http.getOutputStream();
@@ -1482,6 +1503,7 @@
         }
     }
 
+    // Streaming returns true if there is a request body to send
     public boolean streaming () {
         return (fixedContentLength != -1) || (fixedContentLengthLong != -1) ||
                (chunkLength != -1);
diff --git a/src/java.base/share/classes/sun/nio/cs/StreamDecoder.java b/src/java.base/share/classes/sun/nio/cs/StreamDecoder.java
index 38275fd..15cdaed 100644
--- a/src/java.base/share/classes/sun/nio/cs/StreamDecoder.java
+++ b/src/java.base/share/classes/sun/nio/cs/StreamDecoder.java
@@ -42,6 +42,7 @@
 import java.nio.charset.CodingErrorAction;
 import java.nio.charset.IllegalCharsetNameException;
 import java.nio.charset.UnsupportedCharsetException;
+import java.util.Arrays;
 
 public class StreamDecoder extends Reader {
 
@@ -212,6 +213,16 @@
         return !closed;
     }
 
+    public void fillZeroToPosition() throws IOException {
+        Object lock = this.lock;
+        synchronized (lock) {
+            lockedFillZeroToPosition();
+        }
+    }
+
+    private void lockedFillZeroToPosition() {
+        Arrays.fill(bb.array(), bb.arrayOffset(), bb.arrayOffset() + bb.position(), (byte)0);
+    }
 
     // -- Charset-based stream decoder impl --
 
diff --git a/src/java.base/share/classes/sun/security/pkcs/PKCS7.java b/src/java.base/share/classes/sun/security/pkcs/PKCS7.java
index f7df993..d5f4b35 100644
--- a/src/java.base/share/classes/sun/security/pkcs/PKCS7.java
+++ b/src/java.base/share/classes/sun/security/pkcs/PKCS7.java
@@ -154,6 +154,10 @@
         contentType = block.contentType;
         DerValue content = block.getContent();
 
+        if (content == null) {
+            throw new ParsingException("content is null");
+        }
+
         if (contentType.equals(ContentInfo.SIGNED_DATA_OID)) {
             parseSignedData(content);
         } else if (contentType.equals(ContentInfo.OLD_SIGNED_DATA_OID)) {
diff --git a/src/java.base/share/classes/sun/security/rsa/RSAPrivateCrtKeyImpl.java b/src/java.base/share/classes/sun/security/rsa/RSAPrivateCrtKeyImpl.java
index 4c5af4b..dca389e 100644
--- a/src/java.base/share/classes/sun/security/rsa/RSAPrivateCrtKeyImpl.java
+++ b/src/java.base/share/classes/sun/security/rsa/RSAPrivateCrtKeyImpl.java
@@ -306,14 +306,6 @@
         return keyParams;
     }
 
-    // return a string representation of this key for debugging
-    @Override
-    public String toString() {
-        return "SunRsaSign " + type.keyAlgo + " private CRT key, "
-               + n.bitLength() + " bits" + "\n  params: " + keyParams
-               + "\n  modulus: " + n + "\n  private exponent: " + d;
-    }
-
     // utility method for parsing DER encoding of RSA private keys in PKCS#1
     // format as defined in RFC 8017 Appendix A.1.2, i.e. SEQ of version, n,
     // e, d, p, q, pe, qe, and coeff, and return the parsed components.
diff --git a/src/java.base/share/classes/sun/security/rsa/RSAPrivateKeyImpl.java b/src/java.base/share/classes/sun/security/rsa/RSAPrivateKeyImpl.java
index 5a645c7..a79b014 100644
--- a/src/java.base/share/classes/sun/security/rsa/RSAPrivateKeyImpl.java
+++ b/src/java.base/share/classes/sun/security/rsa/RSAPrivateKeyImpl.java
@@ -143,14 +143,6 @@
         return keyParams;
     }
 
-    // return a string representation of this key for debugging
-    @Override
-    public String toString() {
-        return "Sun " + type.keyAlgo + " private key, " + n.bitLength()
-               + " bits" + "\n  params: " + keyParams + "\n  modulus: " + n
-               + "\n  private exponent: " + d;
-    }
-
     /**
      * Restores the state of this object from the stream.
      * <p>
diff --git a/src/java.base/share/classes/sun/security/ssl/CertificateRequest.java b/src/java.base/share/classes/sun/security/ssl/CertificateRequest.java
index e13fcd6..2134506 100644
--- a/src/java.base/share/classes/sun/security/ssl/CertificateRequest.java
+++ b/src/java.base/share/classes/sun/security/ssl/CertificateRequest.java
@@ -135,7 +135,7 @@
             ArrayList<String> keyTypes = new ArrayList<>(3);
             for (byte id : ids) {
                 ClientCertificateType cct = ClientCertificateType.valueOf(id);
-                if (cct.isAvailable) {
+                if (cct != null && cct.isAvailable) {
                     cct.keyAlgorithm.forEach(key -> {
                         if (!keyTypes.contains(key)) {
                             keyTypes.add(key);
diff --git a/src/java.base/share/classes/sun/security/ssl/SSLHandshake.java b/src/java.base/share/classes/sun/security/ssl/SSLHandshake.java
index db68eb2..12ef8ba 100644
--- a/src/java.base/share/classes/sun/security/ssl/SSLHandshake.java
+++ b/src/java.base/share/classes/sun/security/ssl/SSLHandshake.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -446,7 +446,7 @@
 
     private HandshakeProducer getHandshakeProducer(
             ConnectionContext context) {
-        if (handshakeConsumers.length == 0) {
+        if (handshakeProducers.length == 0) {
             return null;
         }
 
diff --git a/src/java.base/share/classes/sun/security/ssl/SunJSSE.java b/src/java.base/share/classes/sun/security/ssl/SunJSSE.java
index 894e26d..dce2aad 100644
--- a/src/java.base/share/classes/sun/security/ssl/SunJSSE.java
+++ b/src/java.base/share/classes/sun/security/ssl/SunJSSE.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,25 +31,6 @@
 
 /**
  * The JSSE provider.
- *
- * SunJSSE now supports an experimental FIPS compliant mode when used with an
- * appropriate FIPS certified crypto provider. In FIPS mode, we:
- *  . allow only TLS 1.0 or later
- *  . allow only FIPS approved ciphersuites
- *  . perform all crypto in the FIPS crypto provider
- *
- * It is currently not possible to use both FIPS compliant SunJSSE and
- * standard JSSE at the same time because of the various static data structures
- * we use.
- *
- * However, we do want to allow FIPS mode to be enabled at runtime and without
- * editing the java.security file. That means we need to allow
- * Security.removeProvider("SunJSSE") to work, which creates an instance of
- * this class in non-FIPS mode. That is why we delay the selection of the mode
- * as long as possible. This is until we open an SSL/TLS connection and the
- * data structures need to be initialized or until SunJSSE is initialized in
- * FIPS mode.
- *
  */
 public class SunJSSE extends java.security.Provider {
 
diff --git a/src/java.base/share/classes/sun/util/resources/CurrencyNames.properties b/src/java.base/share/classes/sun/util/resources/CurrencyNames.properties
index 53bf1d8..c231cad 100644
--- a/src/java.base/share/classes/sun/util/resources/CurrencyNames.properties
+++ b/src/java.base/share/classes/sun/util/resources/CurrencyNames.properties
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -266,6 +266,7 @@
 XBC=XBC
 XBD=XBD
 XCD=XCD
+XCG=XCG
 XDR=XDR
 XFO=XFO
 XFU=XFU
@@ -491,6 +492,7 @@
 xbc=European Unit of Account (XBC)
 xbd=European Unit of Account (XBD)
 xcd=East Caribbean Dollar
+xcg=Caribbean Guilder
 xdr=Special Drawing Rights
 xfo=French Gold Franc
 xfu=French UIC-Franc
diff --git a/src/java.base/share/conf/security/java.security b/src/java.base/share/conf/security/java.security
index 9be0203..78faaf1 100644
--- a/src/java.base/share/conf/security/java.security
+++ b/src/java.base/share/conf/security/java.security
@@ -983,6 +983,23 @@
     noDuplicateIds,\
     noRetrievalMethodLoops
 
+#
+# Support for the here() function
+#
+# This security property determines whether the here() XPath function is
+# supported in XML Signature generation and verification.
+#
+# If this property is set to false, the here() function is not supported.
+# Generating an XML Signature that uses the here() function will throw an
+# XMLSignatureException. Validating an existing XML Signature that uses the
+# here() function will also throw an XMLSignatureException.
+#
+# The default value for this property is true.
+#
+# Note: This property is currently used by the JDK Reference implementation.
+# It is not guaranteed to be examined and used by other implementations.
+#
+#jdk.xml.dsig.hereFunctionSupported=true
 
 #
 # Deserialization JVM-wide filter factory
diff --git a/src/java.base/share/legal/public_suffix.md b/src/java.base/share/legal/public_suffix.md
index d228ac2..2c8c971 100644
--- a/src/java.base/share/legal/public_suffix.md
+++ b/src/java.base/share/legal/public_suffix.md
@@ -11,7 +11,7 @@
 
 The Source Code of this file is available under the
 Mozilla Public License, v. 2.0 and is located at
-https://raw.githubusercontent.com/publicsuffix/list/88467c960d6cdad2ca1623e892e5e17506bc269f/public_suffix_list.dat.
+https://raw.githubusercontent.com/publicsuffix/list/b5bf572c52988dbe9d865b8f090ea819024a9936/public_suffix_list.dat.
 If a copy of the MPL was not distributed with this file, you can obtain one
 at https://mozilla.org/MPL/2.0/.
 
diff --git a/src/java.base/share/lib/security/default.policy b/src/java.base/share/lib/security/default.policy
index b22f269..4e3c326 100644
--- a/src/java.base/share/lib/security/default.policy
+++ b/src/java.base/share/lib/security/default.policy
@@ -92,6 +92,8 @@
     permission java.security.SecurityPermission
                    "com.sun.org.apache.xml.internal.security.register";
     permission java.security.SecurityPermission
+                   "getProperty.jdk.xml.dsig.hereFunctionSupported";
+    permission java.security.SecurityPermission
                    "getProperty.jdk.xml.dsig.secureValidationPolicy";
     permission java.lang.RuntimePermission
                    "accessClassInPackage.com.sun.org.apache.xml.internal.*";
diff --git a/src/java.base/share/man/java.1 b/src/java.base/share/man/java.1
index e867e29..3039c21 100644
--- a/src/java.base/share/man/java.1
+++ b/src/java.base/share/man/java.1
@@ -1642,6 +1642,15 @@
 See \f[B]Application Class Data Sharing\f[R].
 .RE
 .TP
+\f[V]-XX:+VerifySharedSpaces\f[R]
+If this option is specified, the JVM will load a CDS archive file only
+if it passes an integrity check based on CRC32 checksums.
+The purpose of this flag is to check for unintentional damage to CDS
+archive files in transmission or storage.
+To guarantee the security and proper operation of CDS, the user must
+ensure that the CDS archive files used by Java applications cannot be
+modified without proper authorization.
+.TP
 .B \f[CB]\-XX:SharedArchiveConfigFile\f[R]=\f[I]shared_config_file\f[R]
 Specifies additional shared data added to the archive file.
 .RS
diff --git a/src/java.base/share/native/libverify/check_code.c b/src/java.base/share/native/libverify/check_code.c
index 126ff76..6956be9 100644
--- a/src/java.base/share/native/libverify/check_code.c
+++ b/src/java.base/share/native/libverify/check_code.c
@@ -1678,12 +1678,13 @@
     switch (instruction) {
         case JVM_OPC_tableswitch: {
             int *lpc = (int *)UCALIGN(iptr + 1);
+            int64_t low, high, index;
             if (lpc + 2 >= (int *)end) {
                 return -1; /* do not read pass the end */
             }
-            int64_t low  = _ck_ntohl(lpc[1]);
-            int64_t high = _ck_ntohl(lpc[2]);
-            int64_t index = high - low;
+            low  = _ck_ntohl(lpc[1]);
+            high = _ck_ntohl(lpc[2]);
+            index = high - low;
             // The value of low must be less than or equal to high - i.e. index >= 0
             if ((index < 0) || (index > 65535)) {
                 return -1;      /* illegal */
diff --git a/src/java.base/unix/classes/sun/nio/fs/UnixFileAttributes.java b/src/java.base/unix/classes/sun/nio/fs/UnixFileAttributes.java
index 4f0b159..188cfdd 100644
--- a/src/java.base/unix/classes/sun/nio/fs/UnixFileAttributes.java
+++ b/src/java.base/unix/classes/sun/nio/fs/UnixFileAttributes.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,10 +25,15 @@
 
 package sun.nio.fs;
 
-import java.nio.file.attribute.*;
-import java.util.concurrent.TimeUnit;
-import java.util.Set;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.nio.file.attribute.FileTime;
+import java.nio.file.attribute.GroupPrincipal;
+import java.nio.file.attribute.PosixFileAttributes;
+import java.nio.file.attribute.PosixFilePermission;
+import java.nio.file.attribute.UserPrincipal;
 import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
 
 /**
  * Unix implementation of PosixFileAttributes.
@@ -52,6 +57,7 @@
     private long    st_ctime_sec;
     private long    st_ctime_nsec;
     private long    st_birthtime_sec;
+    private long    st_birthtime_nsec;
 
     // created lazily
     private volatile UserPrincipal owner;
@@ -145,7 +151,7 @@
     @Override
     public FileTime creationTime() {
         if (UnixNativeDispatcher.birthtimeSupported()) {
-            return FileTime.from(st_birthtime_sec, TimeUnit.SECONDS);
+            return toFileTime(st_birthtime_sec, st_birthtime_nsec);
         } else {
             // return last modified when birth time not supported
             return lastModifiedTime();
diff --git a/src/java.base/unix/native/jspawnhelper/jspawnhelper.c b/src/java.base/unix/native/jspawnhelper/jspawnhelper.c
index dec17f0..7f86826 100644
--- a/src/java.base/unix/native/jspawnhelper/jspawnhelper.c
+++ b/src/java.base/unix/native/jspawnhelper/jspawnhelper.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
  * questions.
  */
 
+#include <assert.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <stdio.h>
@@ -85,11 +86,15 @@
         error (fdout, ERR_PIPE);
     }
 
-    if (readFully (fdin, c, sizeof(*c)) == -1) {
+#ifdef DEBUG
+    jtregSimulateCrash(0, 5);
+#endif
+
+    if (readFully (fdin, c, sizeof(*c)) != sizeof(*c)) {
         error (fdout, ERR_PIPE);
     }
 
-    if (readFully (fdin, &sp, sizeof(sp)) == -1) {
+    if (readFully (fdin, &sp, sizeof(sp)) != sizeof(sp)) {
         error (fdout, ERR_PIPE);
     }
 
@@ -98,7 +103,7 @@
 
     ALLOC(buf, bufsize);
 
-    if (readFully (fdin, buf, bufsize) == -1) {
+    if (readFully (fdin, buf, bufsize) != bufsize) {
         error (fdout, ERR_PIPE);
     }
 
@@ -135,17 +140,31 @@
     int t;
     struct stat buf;
     /* argv[1] contains the fd number to read all the child info */
-    int r, fdin, fdout;
+    int r, fdinr, fdinw, fdout;
 
-    r = sscanf (argv[1], "%d:%d", &fdin, &fdout);
-    if (r == 2 && fcntl(fdin, F_GETFD) != -1) {
-        fstat(fdin, &buf);
+#ifdef DEBUG
+    jtregSimulateCrash(0, 4);
+#endif
+    r = sscanf (argv[1], "%d:%d:%d", &fdinr, &fdinw, &fdout);
+    if (r == 3 && fcntl(fdinr, F_GETFD) != -1 && fcntl(fdinw, F_GETFD) != -1) {
+        fstat(fdinr, &buf);
         if (!S_ISFIFO(buf.st_mode))
             shutItDown();
     } else {
         shutItDown();
     }
-    initChildStuff (fdin, fdout, &c);
+    // Close the writing end of the pipe we use for reading from the parent.
+    // We have to do this before we start reading from the parent to avoid
+    // blocking in the case the parent exits before we finished reading from it.
+    close(fdinw); // Deliberately ignore errors (see https://lwn.net/Articles/576478/).
+    initChildStuff (fdinr, fdout, &c);
+    // Now set the file descriptor for the pipe's writing end to -1
+    // for the case that somebody tries to close it again.
+    assert(c.childenv[1] == fdinw);
+    c.childenv[1] = -1;
+    // The file descriptor for reporting errors back to our parent we got on the command
+    // line should be the same like the one in the ChildStuff struct we've just read.
+    assert(c.fail[1] == fdout);
 
     childProcess (&c);
     return 0; /* NOT REACHED */
diff --git a/src/java.base/unix/native/libjava/ProcessImpl_md.c b/src/java.base/unix/native/libjava/ProcessImpl_md.c
index 35a949d..bb340a8 100644
--- a/src/java.base/unix/native/libjava/ProcessImpl_md.c
+++ b/src/java.base/unix/native/libjava/ProcessImpl_md.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1995, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -490,14 +490,14 @@
     pid_t resultPid;
     jboolean isCopy;
     int i, offset, rval, bufsize, magic;
-    char *buf, buf1[16];
+    char *buf, buf1[(3 * 11) + 3]; // "%d:%d:%d\0"
     char *hlpargs[3];
     SpawnInfo sp;
 
     /* need to tell helper which fd is for receiving the childstuff
      * and which fd to send response back on
      */
-    snprintf(buf1, sizeof(buf1), "%d:%d", c->childenv[0], c->fail[1]);
+    snprintf(buf1, sizeof(buf1), "%d:%d:%d", c->childenv[0], c->childenv[1], c->fail[1]);
     /* NULL-terminated argv array.
      * argv[0] contains path to jspawnhelper, to follow conventions.
      * argv[1] contains the fd string as argument to jspawnhelper
@@ -534,7 +534,7 @@
         if (c->fds[i] != -1) {
             int flags = fcntl(c->fds[i], F_GETFD);
             if (flags & FD_CLOEXEC) {
-                fcntl(c->fds[i], F_SETFD, flags & (~1));
+                fcntl(c->fds[i], F_SETFD, flags & (~FD_CLOEXEC));
             }
         }
     }
@@ -545,6 +545,10 @@
         return -1;
     }
 
+#ifdef DEBUG
+    jtregSimulateCrash(resultPid, 1);
+#endif
+
     /* now the lengths are known, copy the data */
     buf = NEW(char, bufsize);
     if (buf == 0) {
@@ -560,11 +564,26 @@
     magic = magicNumber();
 
     /* write the two structs and the data buffer */
-    write(c->childenv[1], (char *)&magic, sizeof(magic)); // magic number first
-    write(c->childenv[1], (char *)c, sizeof(*c));
-    write(c->childenv[1], (char *)&sp, sizeof(sp));
-    write(c->childenv[1], buf, bufsize);
+    if (writeFully(c->childenv[1], (char *)&magic, sizeof(magic)) != sizeof(magic)) { // magic number first
+        free(buf);
+        return -1;
+    }
+#ifdef DEBUG
+    jtregSimulateCrash(resultPid, 2);
+#endif
+    if (writeFully(c->childenv[1], (char *)c, sizeof(*c)) != sizeof(*c) ||
+        writeFully(c->childenv[1], (char *)&sp, sizeof(sp)) != sizeof(sp) ||
+        writeFully(c->childenv[1], buf, bufsize) != bufsize) {
+        free(buf);
+        return -1;
+    }
+    /* We're done. Let jspwanhelper know he can't expect any more data from us. */
+    close(c->childenv[1]);
+    c->childenv[1] = -1;
     free(buf);
+#ifdef DEBUG
+    jtregSimulateCrash(resultPid, 3);
+#endif
 
     /* In this mode an external main() in invoked which calls back into
      * childProcess() in this file, rather than directly
@@ -617,6 +636,8 @@
 
     in[0] = in[1] = out[0] = out[1] = err[0] = err[1] = fail[0] = fail[1] = -1;
     childenv[0] = childenv[1] = -1;
+    // Reset errno to protect against bogus error messages
+    errno = 0;
 
     if ((c = NEW(ChildStuff, 1)) == NULL) return -1;
     c->argv = NULL;
@@ -715,11 +736,9 @@
                 goto Catch;
             }
         case sizeof(errnum):
-            assert(errnum == CHILD_IS_ALIVE);
             if (errnum != CHILD_IS_ALIVE) {
-                /* Should never happen since the first thing the spawn
-                 * helper should do is to send an alive ping to the parent,
-                 * before doing any subsequent work. */
+                /* This can happen if the spawn helper encounters an error
+                 * before or during the handshake with the parent. */
                 throwIOException(env, 0, "Bad code from spawn helper "
                                          "(Failed to exec spawn helper)");
                 goto Catch;
@@ -755,8 +774,12 @@
     /* Always clean up fail and childEnv descriptors */
     closeSafely(fail[0]);
     closeSafely(fail[1]);
-    closeSafely(childenv[0]);
-    closeSafely(childenv[1]);
+    /* We use 'c->childenv' here rather than 'childenv' because 'spawnChild()' might have
+     * already closed 'c->childenv[1]' and signaled this by setting 'c->childenv[1]' to '-1'.
+     * Otherwise 'c->childenv' and 'childenv' are the same because we just copied 'childenv'
+     * to 'c->childenv' (with 'copyPipe()') before calling 'startChild()'. */
+    closeSafely(c->childenv[0]);
+    closeSafely(c->childenv[1]);
 
     releaseBytes(env, helperpath, phelperpath);
     releaseBytes(env, prog,       pprog);
diff --git a/src/java.base/unix/native/libjava/childproc.c b/src/java.base/unix/native/libjava/childproc.c
index 1044b8e..c5dc6d3 100644
--- a/src/java.base/unix/native/libjava/childproc.c
+++ b/src/java.base/unix/native/libjava/childproc.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -36,14 +36,6 @@
 
 const char * const *parentPathv;
 
-ssize_t
-restartableWrite(int fd, const void *buf, size_t count)
-{
-    ssize_t result;
-    RESTARTABLE(write(fd, buf, count), result);
-    return result;
-}
-
 int
 restartableDup2(int fd_from, int fd_to)
 {
@@ -163,6 +155,46 @@
     }
 }
 
+/*
+ * Writes nbyte bytes from buf into file descriptor fd,
+ * The write operation is retried in case of EINTR or partial writes.
+ *
+ * Returns number of bytes written (normally nbyte).
+ * In case of write errors, returns -1 and sets errno.
+ */
+ssize_t
+writeFully(int fd, const void *buf, size_t nbyte)
+{
+#ifdef DEBUG
+/* This code is only used in debug builds for testing truncated writes
+ * during the handshake with the spawn helper for MODE_POSIX_SPAWN.
+ * See: test/jdk/java/lang/ProcessBuilder/JspawnhelperProtocol.java
+ */
+    const char* env = getenv("JTREG_JSPAWNHELPER_PROTOCOL_TEST");
+    if (env != NULL && atoi(env) == 99 && nbyte == sizeof(ChildStuff)) {
+        printf("posix_spawn: truncating write of ChildStuff struct\n");
+        fflush(stdout);
+        nbyte = nbyte / 2;
+    }
+#endif
+    ssize_t remaining = nbyte;
+    for (;;) {
+        ssize_t n = write(fd, buf, remaining);
+        if (n > 0) {
+            remaining -= n;
+            if (remaining <= 0)
+                return nbyte;
+            /* We were interrupted in the middle of writing the bytes.
+             * Unlikely, but possible. */
+            buf = (void *) (((char *)buf) + n);
+        } else if (n == -1 && errno == EINTR) {
+            /* Retry */
+        } else {
+            return -1;
+        }
+    }
+}
+
 void
 initVectorFromBlock(const char**vector, const char* block, int count)
 {
@@ -210,7 +242,7 @@
                            const char *argv[],
                            const char *const envp[])
 {
-    if (mode == MODE_CLONE || mode == MODE_VFORK) {
+    if (mode == MODE_VFORK) {
         /* shared address space; be very careful. */
         execve(file, (char **) argv, (char **) envp);
         if (errno == ENOEXEC)
@@ -321,9 +353,14 @@
         /* Child shall signal aliveness to parent at the very first
          * moment. */
         int code = CHILD_IS_ALIVE;
-        restartableWrite(fail_pipe_fd, &code, sizeof(code));
+        if (writeFully(fail_pipe_fd, &code, sizeof(code)) != sizeof(code)) {
+            goto WhyCantJohnnyExec;
+        }
     }
 
+#ifdef DEBUG
+    jtregSimulateCrash(0, 6);
+#endif
     /* Close the parent sides of the pipes.
        Closing pipe fds here is redundant, since closeDescriptors()
        would do it anyways, but a little paranoia is a good thing. */
@@ -390,9 +427,26 @@
      */
     {
         int errnum = errno;
-        restartableWrite(fail_pipe_fd, &errnum, sizeof(errnum));
+        writeFully(fail_pipe_fd, &errnum, sizeof(errnum));
     }
     close(fail_pipe_fd);
     _exit(-1);
     return 0;  /* Suppress warning "no return value from function" */
 }
+
+#ifdef DEBUG
+/* This method is only used in debug builds for testing MODE_POSIX_SPAWN
+ * in the light of abnormal program termination of either the parent JVM
+ * or the newly created jspawnhelper child process during the execution of
+ * Java_java_lang_ProcessImpl_forkAndExec().
+ * See: test/jdk/java/lang/ProcessBuilder/JspawnhelperProtocol.java
+ */
+void jtregSimulateCrash(pid_t child, int stage) {
+    const char* env = getenv("JTREG_JSPAWNHELPER_PROTOCOL_TEST");
+    if (env != NULL && atoi(env) == stage) {
+        printf("posix_spawn:%d\n", child);
+        fflush(stdout);
+        _exit(stage);
+    }
+}
+#endif
diff --git a/src/java.base/unix/native/libjava/childproc.h b/src/java.base/unix/native/libjava/childproc.h
index 2190dd1..e39126a 100644
--- a/src/java.base/unix/native/libjava/childproc.h
+++ b/src/java.base/unix/native/libjava/childproc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -85,7 +85,6 @@
 #define MODE_FORK 1
 #define MODE_POSIX_SPAWN 2
 #define MODE_VFORK 3
-#define MODE_CLONE 4
 
 typedef struct _ChildStuff
 {
@@ -128,7 +127,7 @@
  */
 extern const char * const *parentPathv;
 
-ssize_t restartableWrite(int fd, const void *buf, size_t count);
+ssize_t writeFully(int fd, const void *buf, size_t count);
 int restartableDup2(int fd_from, int fd_to);
 int closeSafely(int fd);
 int isAsciiDigit(char c);
@@ -149,4 +148,14 @@
                  const char *const envp[]);
 int childProcess(void *arg);
 
+#ifdef DEBUG
+/* This method is only used in debug builds for testing MODE_POSIX_SPAWN
+ * in the light of abnormal program termination of either the parent JVM
+ * or the newly created jspawnhelper child process during the execution of
+ * Java_java_lang_ProcessImpl_forkAndExec().
+ * See: test/jdk/java/lang/ProcessBuilder/JspawnhelperProtocol.java
+ */
+void jtregSimulateCrash(pid_t child, int stage);
+#endif
+
 #endif
diff --git a/src/java.base/unix/native/libnet/Inet4AddressImpl.c b/src/java.base/unix/native/libnet/Inet4AddressImpl.c
index 8cde515..5b8f38b 100644
--- a/src/java.base/unix/native/libnet/Inet4AddressImpl.c
+++ b/src/java.base/unix/native/libnet/Inet4AddressImpl.c
@@ -259,7 +259,11 @@
 
     // set TTL
     if (ttl > 0) {
-        setsockopt(fd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));
+        if (setsockopt(fd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl)) < 0) {
+            NET_ThrowNew(env, errno, "setsockopt IP_TTL failed");
+            close(fd);
+            return JNI_FALSE;
+        }
     }
 
     // A network interface was specified, so let's bind to it.
@@ -345,11 +349,19 @@
     struct timeval tv = { 0, 0 };
     const size_t plen = ICMP_MINLEN + sizeof(tv);
 
-    setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
+    if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)) < 0) {
+        NET_ThrowNew(env, errno, "setsockopt SO_RCVBUF failed");
+        close(fd);
+        return JNI_FALSE;
+    }
 
     // sets the ttl (max number of hops)
     if (ttl > 0) {
-        setsockopt(fd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));
+        if (setsockopt(fd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl)) < 0) {
+            NET_ThrowNew(env, errno, "setsockopt IP_TTL failed");
+            close(fd);
+            return JNI_FALSE;
+        }
     }
 
     // a specific interface was specified, so let's bind the socket
diff --git a/src/java.base/unix/native/libnet/Inet6AddressImpl.c b/src/java.base/unix/native/libnet/Inet6AddressImpl.c
index b5c4288..e9e7adb 100644
--- a/src/java.base/unix/native/libnet/Inet6AddressImpl.c
+++ b/src/java.base/unix/native/libnet/Inet6AddressImpl.c
@@ -151,7 +151,7 @@
     result = (*env)->NewObjectArray(env, arraySize, ia_class, NULL);
     if (!result) goto done;
 
-    if ((*env)->GetStaticBooleanField(env, ia_class, ia_preferIPv6AddressID)) {
+    if ((*env)->GetStaticIntField(env, ia_class, ia_preferIPv6AddressID) == java_net_InetAddress_PREFER_IPV6_VALUE) {
         i = includeLoopback ? addrs6 : (addrs6 - numV6Loopbacks);
         j = 0;
     } else {
@@ -463,12 +463,16 @@
 
     // set TTL
     if (ttl > 0) {
-        setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl));
+        if (setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl)) < 0) {
+            NET_ThrowNew(env, errno, "setsockopt IPV6_UNICAST_HOPS failed");
+            close(fd);
+            return JNI_FALSE;
+        }
     }
 
     // A network interface was specified, so let's bind to it.
     if (netif != NULL) {
-        if (bind(fd, &netif->sa, sizeof(struct sockaddr_in6)) <0) {
+        if (bind(fd, &netif->sa, sizeof(struct sockaddr_in6)) < 0) {
             NET_ThrowNew(env, errno, "Can't bind socket");
             close(fd);
             return JNI_FALSE;
@@ -557,11 +561,19 @@
     setsockopt(fd, SOL_RAW, IPV6_CHECKSUM, &csum_offset, sizeof(int));
 #endif
 
-    setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size));
+    if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)) < 0) {
+        NET_ThrowNew(env, errno, "setsockopt SO_RCVBUF failed");
+        close(fd);
+        return JNI_FALSE;
+    }
 
     // sets the ttl (max number of hops)
     if (ttl > 0) {
-        setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl));
+        if (setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl)) < 0) {
+            NET_ThrowNew(env, errno, "setsockopt IPV6_UNICAST_HOPS failed");
+            close(fd);
+            return JNI_FALSE;
+        }
     }
 
     // a specific interface was specified, so let's bind the socket
diff --git a/src/java.base/unix/native/libnet/net_util_md.c b/src/java.base/unix/native/libnet/net_util_md.c
index 7c939e8..4ec11a1 100644
--- a/src/java.base/unix/native/libnet/net_util_md.c
+++ b/src/java.base/unix/native/libnet/net_util_md.c
@@ -661,7 +661,9 @@
         }
 
         if (sotype == SOCK_DGRAM) {
-            setsockopt(fd, level, SO_REUSEPORT, arg, len);
+            if (setsockopt(fd, level, SO_REUSEPORT, arg, len) < 0) {
+                return -1;
+            }
         }
     }
 #endif
diff --git a/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c b/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c
index ad36e6a..be578a0 100644
--- a/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c
+++ b/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c
@@ -51,6 +51,7 @@
 
 #ifdef __linux__
 #include <sys/syscall.h>
+#include <sys/sysmacros.h> // makedev macros
 #endif
 
 #if defined(__linux__) || defined(_AIX)
@@ -71,6 +72,106 @@
 #define readdir64 readdir
 #endif
 
+#if defined(__linux__)
+// Account for the case where we compile on a system without statx
+// support. We still want to ensure we can call statx at runtime
+// if the runtime glibc version supports it (>= 2.28). We do this
+// by defining binary compatible statx structs in this file and
+// not relying on included headers.
+
+#ifndef __GLIBC__
+// Alpine doesn't know these types, define them
+typedef unsigned int       __uint32_t;
+typedef unsigned short     __uint16_t;
+typedef unsigned long int  __uint64_t;
+#endif
+
+/*
+ * Timestamp structure for the timestamps in struct statx.
+ */
+struct my_statx_timestamp {
+        int64_t   tv_sec;
+        __uint32_t  tv_nsec;
+        int32_t   __reserved;
+};
+
+/*
+ * struct statx used by statx system call on >= glibc 2.28
+ * systems
+ */
+struct my_statx
+{
+  __uint32_t stx_mask;
+  __uint32_t stx_blksize;
+  __uint64_t stx_attributes;
+  __uint32_t stx_nlink;
+  __uint32_t stx_uid;
+  __uint32_t stx_gid;
+  __uint16_t stx_mode;
+  __uint16_t __statx_pad1[1];
+  __uint64_t stx_ino;
+  __uint64_t stx_size;
+  __uint64_t stx_blocks;
+  __uint64_t stx_attributes_mask;
+  struct my_statx_timestamp stx_atime;
+  struct my_statx_timestamp stx_btime;
+  struct my_statx_timestamp stx_ctime;
+  struct my_statx_timestamp stx_mtime;
+  __uint32_t stx_rdev_major;
+  __uint32_t stx_rdev_minor;
+  __uint32_t stx_dev_major;
+  __uint32_t stx_dev_minor;
+  __uint64_t __statx_pad2[14];
+};
+
+// statx masks, flags, constants
+
+#ifndef AT_SYMLINK_NOFOLLOW
+#define AT_SYMLINK_NOFOLLOW 0x100
+#endif
+
+#ifndef AT_STATX_SYNC_AS_STAT
+#define AT_STATX_SYNC_AS_STAT 0x0000
+#endif
+
+#ifndef AT_EMPTY_PATH
+#define AT_EMPTY_PATH 0x1000
+#endif
+
+#ifndef STATX_BASIC_STATS
+#define STATX_BASIC_STATS 0x000007ffU
+#endif
+
+#ifndef STATX_BTIME
+#define STATX_BTIME 0x00000800U
+#endif
+
+#ifndef STATX_TYPE
+#define STATX_TYPE 0x00000001U
+#endif
+
+#ifndef STATX_MODE
+#define STATX_MODE 0x00000002U
+#endif
+
+#ifndef STATX_ALL
+#define STATX_ALL (STATX_BTIME | STATX_BASIC_STATS)
+#endif
+
+#ifndef AT_FDCWD
+#define AT_FDCWD -100
+#endif
+
+#ifndef RTLD_DEFAULT
+#define RTLD_DEFAULT RTLD_LOCAL
+#endif
+
+#define NO_FOLLOW_SYMLINK 1
+#define FOLLOW_SYMLINK 0
+
+#endif // __linux__
+
+
 #include "jni.h"
 #include "jni_util.h"
 #include "jlong.h"
@@ -117,9 +218,12 @@
 static jfieldID attrs_st_ctime_sec;
 static jfieldID attrs_st_ctime_nsec;
 
-#ifdef _DARWIN_FEATURE_64_BIT_INODE
+#if defined(_DARWIN_FEATURE_64_BIT_INODE) || defined(__linux__)
 static jfieldID attrs_st_birthtime_sec;
 #endif
+#if defined(__linux__) // Linux has nsec granularity if supported
+static jfieldID attrs_st_birthtime_nsec;
+#endif
 
 static jfieldID attrs_f_frsize;
 static jfieldID attrs_f_blocks;
@@ -143,6 +247,10 @@
 typedef int futimens_func(int, const struct timespec *);
 typedef int lutimes_func(const char *, const struct timeval *);
 typedef DIR* fdopendir_func(int);
+#if defined(__linux__)
+typedef int statx_func(int dirfd, const char *restrict pathname, int flags,
+                       unsigned int mask, struct my_statx *restrict statxbuf);
+#endif
 
 static openat64_func* my_openat64_func = NULL;
 static fstatat64_func* my_fstatat64_func = NULL;
@@ -152,6 +260,9 @@
 static futimens_func* my_futimens_func = NULL;
 static lutimes_func* my_lutimes_func = NULL;
 static fdopendir_func* my_fdopendir_func = NULL;
+#if defined(__linux__)
+static statx_func* my_statx_func = NULL;
+#endif
 
 /**
  * fstatat missing from glibc on Linux.
@@ -177,6 +288,13 @@
 }
 #endif
 
+#if defined(__linux__)
+static int statx_wrapper(int dirfd, const char *restrict pathname, int flags,
+                         unsigned int mask, struct my_statx *restrict statxbuf) {
+    return (*my_statx_func)(dirfd, pathname, flags, mask, statxbuf);
+}
+#endif
+
 /**
  * Call this to throw an internal UnixException when a system/library
  * call fails
@@ -229,10 +347,14 @@
     attrs_st_ctime_nsec = (*env)->GetFieldID(env, clazz, "st_ctime_nsec", "J");
     CHECK_NULL_RETURN(attrs_st_ctime_nsec, 0);
 
-#ifdef _DARWIN_FEATURE_64_BIT_INODE
+#if defined(_DARWIN_FEATURE_64_BIT_INODE) || defined(__linux__)
     attrs_st_birthtime_sec = (*env)->GetFieldID(env, clazz, "st_birthtime_sec", "J");
     CHECK_NULL_RETURN(attrs_st_birthtime_sec, 0);
 #endif
+#if defined (__linux__) // Linux has nsec granularity
+    attrs_st_birthtime_nsec = (*env)->GetFieldID(env, clazz, "st_birthtime_nsec", "J");
+    CHECK_NULL_RETURN(attrs_st_birthtime_nsec, 0);
+#endif
 
     clazz = (*env)->FindClass(env, "sun/nio/fs/UnixFileStoreAttributes");
     CHECK_NULL_RETURN(clazz, 0);
@@ -314,6 +436,12 @@
 #ifdef _DARWIN_FEATURE_64_BIT_INODE
     capabilities |= sun_nio_fs_UnixNativeDispatcher_SUPPORTS_BIRTHTIME;
 #endif
+#if defined(__linux__)
+    my_statx_func = (statx_func*) dlsym(RTLD_DEFAULT, "statx");
+    if (my_statx_func != NULL) {
+        capabilities |= sun_nio_fs_UnixNativeDispatcher_SUPPORTS_BIRTHTIME;
+    }
+#endif
 
     /* supports extended attributes */
 
@@ -490,10 +618,37 @@
     return (jint)n;
 }
 
+#if defined(__linux__)
+/**
+ * Copy statx members into sun.nio.fs.UnixFileAttributes
+ */
+static void copy_statx_attributes(JNIEnv* env, struct my_statx* buf, jobject attrs) {
+    (*env)->SetIntField(env, attrs, attrs_st_mode, (jint)buf->stx_mode);
+    (*env)->SetLongField(env, attrs, attrs_st_ino, (jlong)buf->stx_ino);
+    (*env)->SetIntField(env, attrs, attrs_st_nlink, (jint)buf->stx_nlink);
+    (*env)->SetIntField(env, attrs, attrs_st_uid, (jint)buf->stx_uid);
+    (*env)->SetIntField(env, attrs, attrs_st_gid, (jint)buf->stx_gid);
+    (*env)->SetLongField(env, attrs, attrs_st_size, (jlong)buf->stx_size);
+    (*env)->SetLongField(env, attrs, attrs_st_atime_sec, (jlong)buf->stx_atime.tv_sec);
+    (*env)->SetLongField(env, attrs, attrs_st_mtime_sec, (jlong)buf->stx_mtime.tv_sec);
+    (*env)->SetLongField(env, attrs, attrs_st_ctime_sec, (jlong)buf->stx_ctime.tv_sec);
+    (*env)->SetLongField(env, attrs, attrs_st_birthtime_sec, (jlong)buf->stx_btime.tv_sec);
+    (*env)->SetLongField(env, attrs, attrs_st_birthtime_nsec, (jlong)buf->stx_btime.tv_nsec);
+    (*env)->SetLongField(env, attrs, attrs_st_atime_nsec, (jlong)buf->stx_atime.tv_nsec);
+    (*env)->SetLongField(env, attrs, attrs_st_mtime_nsec, (jlong)buf->stx_mtime.tv_nsec);
+    (*env)->SetLongField(env, attrs, attrs_st_ctime_nsec, (jlong)buf->stx_ctime.tv_nsec);
+    // convert statx major:minor to dev_t using makedev
+    dev_t dev = makedev(buf->stx_dev_major, buf->stx_dev_minor);
+    dev_t rdev = makedev(buf->stx_rdev_major, buf->stx_rdev_minor);
+    (*env)->SetLongField(env, attrs, attrs_st_dev, (jlong)dev);
+    (*env)->SetLongField(env, attrs, attrs_st_rdev, (jlong)rdev);
+}
+#endif
+
 /**
  * Copy stat64 members into sun.nio.fs.UnixFileAttributes
  */
-static void prepAttributes(JNIEnv* env, struct stat64* buf, jobject attrs) {
+static void copy_stat64_attributes(JNIEnv* env, struct stat64* buf, jobject attrs) {
     (*env)->SetIntField(env, attrs, attrs_st_mode, (jint)buf->st_mode);
     (*env)->SetLongField(env, attrs, attrs_st_ino, (jlong)buf->st_ino);
     (*env)->SetLongField(env, attrs, attrs_st_dev, (jlong)buf->st_dev);
@@ -508,6 +663,7 @@
 
 #ifdef _DARWIN_FEATURE_64_BIT_INODE
     (*env)->SetLongField(env, attrs, attrs_st_birthtime_sec, (jlong)buf->st_birthtime);
+    // rely on default value of 0 for st_birthtime_nsec field on Darwin
 #endif
 
 #ifndef MACOSX
@@ -528,12 +684,28 @@
     int err;
     struct stat64 buf;
     const char* path = (const char*)jlong_to_ptr(pathAddress);
+#if defined(__linux__)
+    struct my_statx statx_buf;
+    int flags = AT_STATX_SYNC_AS_STAT;
+    unsigned int mask = STATX_ALL;
 
+    if (my_statx_func != NULL) {
+        // Prefer statx over stat64 on Linux if it's available
+        RESTARTABLE(statx_wrapper(AT_FDCWD, path, flags, mask, &statx_buf), err);
+        if (err == 0) {
+            copy_statx_attributes(env, &statx_buf, attrs);
+        } else {
+            throwUnixException(env, errno);
+        }
+        // statx was available, so return now
+        return;
+    }
+#endif
     RESTARTABLE(stat64(path, &buf), err);
     if (err == -1) {
         throwUnixException(env, errno);
     } else {
-        prepAttributes(env, &buf, attrs);
+        copy_stat64_attributes(env, &buf, attrs);
     }
 }
 
@@ -543,6 +715,21 @@
     struct stat64 buf;
     const char* path = (const char*)jlong_to_ptr(pathAddress);
 
+#if defined(__linux__)
+    struct my_statx statx_buf;
+    int flags = AT_STATX_SYNC_AS_STAT;
+    unsigned int mask = STATX_TYPE | STATX_MODE; // only want stx.mode
+
+    if (my_statx_func != NULL) {
+        // Prefer statx over stat64 on Linux if it's available
+        RESTARTABLE(statx_wrapper(AT_FDCWD, path, flags, mask, &statx_buf), err);
+        if (err == 0) {
+            return (jint)statx_buf.stx_mode;
+        } else {
+            return 0;
+        }
+    }
+#endif
     RESTARTABLE(stat64(path, &buf), err);
     if (err == -1) {
         return 0;
@@ -558,12 +745,28 @@
     int err;
     struct stat64 buf;
     const char* path = (const char*)jlong_to_ptr(pathAddress);
+#if defined(__linux__)
+    struct my_statx statx_buf;
+    int flags = AT_STATX_SYNC_AS_STAT | AT_SYMLINK_NOFOLLOW;
+    unsigned int mask = STATX_ALL;
 
+    if (my_statx_func != NULL) {
+        // Prefer statx over stat64 on Linux if it's available
+        RESTARTABLE(statx_wrapper(AT_FDCWD, path, flags, mask, &statx_buf), err);
+        if (err == 0) {
+            copy_statx_attributes(env, &statx_buf, attrs);
+        } else {
+            throwUnixException(env, errno);
+        }
+        // statx was available, so return now
+        return;
+    }
+#endif
     RESTARTABLE(lstat64(path, &buf), err);
     if (err == -1) {
         throwUnixException(env, errno);
     } else {
-        prepAttributes(env, &buf, attrs);
+        copy_stat64_attributes(env, &buf, attrs);
     }
 }
 
@@ -573,12 +776,29 @@
 {
     int err;
     struct stat64 buf;
+#if defined(__linux__)
+    struct my_statx statx_buf;
+    int flags = AT_EMPTY_PATH | AT_STATX_SYNC_AS_STAT;
+    unsigned int mask = STATX_ALL;
 
+    if (my_statx_func != NULL) {
+        // statx supports FD use via dirfd iff pathname is an empty string and the
+        // AT_EMPTY_PATH flag is specified in flags
+        RESTARTABLE(statx_wrapper((int)fd, "", flags, mask, &statx_buf), err);
+        if (err == 0) {
+            copy_statx_attributes(env, &statx_buf, attrs);
+        } else {
+            throwUnixException(env, errno);
+        }
+        // statx was available, so return now
+        return;
+    }
+#endif
     RESTARTABLE(fstat64((int)fd, &buf), err);
     if (err == -1) {
         throwUnixException(env, errno);
     } else {
-        prepAttributes(env, &buf, attrs);
+        copy_stat64_attributes(env, &buf, attrs);
     }
 }
 
@@ -589,6 +809,26 @@
     int err;
     struct stat64 buf;
     const char* path = (const char*)jlong_to_ptr(pathAddress);
+#if defined(__linux__)
+    struct my_statx statx_buf;
+    int flags = AT_STATX_SYNC_AS_STAT;
+    unsigned int mask = STATX_ALL;
+
+    if (my_statx_func != NULL) {
+        // Prefer statx over stat64 on Linux if it's available
+        if (((int)flag & AT_SYMLINK_NOFOLLOW) > 0) { // flag set in java code
+            flags |= AT_SYMLINK_NOFOLLOW;
+        }
+        RESTARTABLE(statx_wrapper((int)dfd, path, flags, mask, &statx_buf), err);
+        if (err == 0) {
+            copy_statx_attributes(env, &statx_buf, attrs);
+        } else {
+            throwUnixException(env, errno);
+        }
+        // statx was available, so return now
+        return;
+    }
+#endif
 
     if (my_fstatat64_func == NULL) {
         JNU_ThrowInternalError(env, "should not reach here");
@@ -598,7 +838,7 @@
     if (err == -1) {
         throwUnixException(env, errno);
     } else {
-        prepAttributes(env, &buf, attrs);
+        copy_stat64_attributes(env, &buf, attrs);
     }
 }
 
diff --git a/src/java.base/windows/native/libjava/canonicalize_md.c b/src/java.base/windows/native/libjava/canonicalize_md.c
index 1ec990f..ecfdf63 100644
--- a/src/java.base/windows/native/libjava/canonicalize_md.c
+++ b/src/java.base/windows/native/libjava/canonicalize_md.c
@@ -138,7 +138,8 @@
         || (errval == ERROR_BAD_NET_NAME)
         || (errval == ERROR_ACCESS_DENIED)
         || (errval == ERROR_NETWORK_UNREACHABLE)
-        || (errval == ERROR_NETWORK_ACCESS_DENIED)) {
+        || (errval == ERROR_NETWORK_ACCESS_DENIED)
+        || (errval == ERROR_NO_MORE_FILES)) {
         return 0;
     }
     return 1;
diff --git a/src/java.base/windows/native/libnet/Inet4AddressImpl.c b/src/java.base/windows/native/libnet/Inet4AddressImpl.c
index 75dfb57..56adec2 100644
--- a/src/java.base/windows/native/libnet/Inet4AddressImpl.c
+++ b/src/java.base/windows/native/libnet/Inet4AddressImpl.c
@@ -232,7 +232,11 @@
 
     // set TTL
     if (ttl > 0) {
-        setsockopt(fd, IPPROTO_IP, IP_TTL, (const char *)&ttl, sizeof(ttl));
+        if (setsockopt(fd, IPPROTO_IP, IP_TTL, (const char *)&ttl, sizeof(ttl)) == SOCKET_ERROR) {
+            NET_ThrowNew(env, WSAGetLastError(), "setsockopt IP_TTL failed");
+            closesocket(fd);
+            return JNI_FALSE;
+        }
     }
 
     // A network interface was specified, so let's bind to it.
diff --git a/src/java.base/windows/native/libnet/Inet6AddressImpl.c b/src/java.base/windows/native/libnet/Inet6AddressImpl.c
index cc2b8d5..8941506 100644
--- a/src/java.base/windows/native/libnet/Inet6AddressImpl.c
+++ b/src/java.base/windows/native/libnet/Inet6AddressImpl.c
@@ -310,7 +310,11 @@
 
     // set TTL
     if (ttl > 0) {
-        setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, (const char *)&ttl, sizeof(ttl));
+        if (setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, (const char *)&ttl, sizeof(ttl)) == SOCKET_ERROR) {
+            NET_ThrowNew(env, WSAGetLastError(), "setsockopt IPV6_UNICAST_HOPS failed");
+            closesocket(fd);
+            return JNI_FALSE;
+        }
     }
 
     // A network interface was specified, so let's bind to it.
diff --git a/src/java.base/windows/native/libnio/ch/DatagramChannelImpl.c b/src/java.base/windows/native/libnio/ch/DatagramChannelImpl.c
index 25c0370f..54a4133 100644
--- a/src/java.base/windows/native/libnio/ch/DatagramChannelImpl.c
+++ b/src/java.base/windows/native/libnio/ch/DatagramChannelImpl.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -89,7 +89,7 @@
 
     rv = connect((SOCKET)fd, &sa.sa, sa_len);
     if (rv == SOCKET_ERROR) {
-        handleSocketError(env, WSAGetLastError());
+        NET_ThrowNew(env, WSAGetLastError(), "connect");
     } else {
         /* Disable WSAECONNRESET errors as socket is no longer connected */
         BOOL enable = FALSE;
@@ -136,7 +136,10 @@
                 }
             } else if (theErr == WSAEWOULDBLOCK) {
                 return IOS_UNAVAILABLE;
-            } else return handleSocketError(env, theErr);
+            } else {
+                NET_ThrowNew(env, theErr, "recvfrom");
+                return IOS_THROWN;
+            }
         }
     } while (retry);
 
@@ -160,7 +163,8 @@
         if (theErr == WSAEWOULDBLOCK) {
             return IOS_UNAVAILABLE;
         }
-        return handleSocketError(env, (jint)WSAGetLastError());
+        NET_ThrowNew(env, (jint)WSAGetLastError(), "sendto");
+        return IOS_THROWN;
     }
     return rv;
 }
diff --git a/src/java.base/windows/native/libnio/ch/IOUtil.c b/src/java.base/windows/native/libnio/ch/IOUtil.c
index ff581f0..e670983 100644
--- a/src/java.base/windows/native/libnio/ch/IOUtil.c
+++ b/src/java.base/windows/native/libnio/ch/IOUtil.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -143,8 +143,7 @@
     }
     result = ioctlsocket(fd, FIONBIO, &argp);
     if (result == SOCKET_ERROR) {
-        int error = WSAGetLastError();
-        handleSocketError(env, (jint)error);
+        NET_ThrowNew(env, WSAGetLastError(), "ioctlsocket");
     }
 }
 
diff --git a/src/java.base/windows/native/libnio/ch/Net.c b/src/java.base/windows/native/libnio/ch/Net.c
index c6c110d..d4410c0 100644
--- a/src/java.base/windows/native/libnio/ch/Net.c
+++ b/src/java.base/windows/native/libnio/ch/Net.c
@@ -77,12 +77,6 @@
              NULL, 0, &bytesReturned, NULL, NULL);
 }
 
-jint handleSocketError(JNIEnv *env, int errorValue)
-{
-    NET_ThrowNew(env, errorValue, NULL);
-    return IOS_THROWN;
-}
-
 static jclass isa_class;        /* java.net.InetSocketAddress */
 static jmethodID isa_ctorID;    /* InetSocketAddress(InetAddress, int) */
 
@@ -162,7 +156,7 @@
     if (s != INVALID_SOCKET) {
         SetHandleInformation((HANDLE)s, HANDLE_FLAG_INHERIT, 0);
 
-        /* IPV6_V6ONLY is true by default */
+        /* Attempt to disable IPV6_V6ONLY to ensure dual-socket support; ignore errors */
         if (domain == AF_INET6) {
             int opt = 0;
             setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY,
@@ -392,7 +386,7 @@
         n = getsockopt(fdval(env, fdo), level, opt, arg, &arglen);
     }
     if (n == SOCKET_ERROR) {
-        handleSocketError(env, WSAGetLastError());
+        NET_ThrowNew(env, WSAGetLastError(), "getsockopt");
         return IOS_THROWN;
     }
 
@@ -436,7 +430,7 @@
         n = setsockopt(fdval(env, fdo), level, opt, parg, arglen);
     }
     if (n == SOCKET_ERROR)
-        handleSocketError(env, WSAGetLastError());
+        NET_ThrowNew(env, WSAGetLastError(), "setsocketopt");
 }
 
 JNIEXPORT jint JNICALL
@@ -467,7 +461,7 @@
     if (n == SOCKET_ERROR) {
         if (join && (WSAGetLastError() == WSAENOPROTOOPT))
             return IOS_UNAVAILABLE;
-        handleSocketError(env, WSAGetLastError());
+        NET_ThrowNew(env, WSAGetLastError(), "setsocketopt");
     }
     return 0;
 }
@@ -489,7 +483,7 @@
     if (n == SOCKET_ERROR) {
         if (block && (WSAGetLastError() == WSAENOPROTOOPT))
             return IOS_UNAVAILABLE;
-        handleSocketError(env, WSAGetLastError());
+        NET_ThrowNew(env, WSAGetLastError(), "setsockopt");
     }
     return 0;
 }
@@ -542,7 +536,7 @@
     }
 
     if (n == SOCKET_ERROR) {
-        handleSocketError(env, WSAGetLastError());
+        NET_ThrowNew(env, WSAGetLastError(), "setsockopt");
     }
     return 0;
 }
@@ -554,7 +548,7 @@
     int opt = (block) ? MCAST_BLOCK_SOURCE : MCAST_UNBLOCK_SOURCE;
     int n = setGroupSourceReqOption(env, fdo, opt, group, index, source);
     if (n == SOCKET_ERROR) {
-        handleSocketError(env, WSAGetLastError());
+        NET_ThrowNew(env, WSAGetLastError(), "setsocketopt to block or unblock source");
     }
     return 0;
 }
@@ -571,7 +565,7 @@
     n = setsockopt(fdval(env, fdo), IPPROTO_IP, IP_MULTICAST_IF,
                    (void*)&(in.s_addr), arglen);
     if (n == SOCKET_ERROR) {
-        handleSocketError(env, WSAGetLastError());
+        NET_ThrowNew(env, WSAGetLastError(), "setsockopt");
     }
 }
 
@@ -584,7 +578,7 @@
 
     n = getsockopt(fdval(env, fdo), IPPROTO_IP, IP_MULTICAST_IF, (void*)&in, &arglen);
     if (n == SOCKET_ERROR) {
-        handleSocketError(env, WSAGetLastError());
+        NET_ThrowNew(env, WSAGetLastError(), "getsockopt");
         return IOS_THROWN;
     }
     return ntohl(in.s_addr);
@@ -600,7 +594,7 @@
     n = setsockopt(fdval(env, fdo), IPPROTO_IPV6, IPV6_MULTICAST_IF,
                    (void*)&(index), arglen);
     if (n == SOCKET_ERROR) {
-        handleSocketError(env, WSAGetLastError());
+        NET_ThrowNew(env, WSAGetLastError(), "setsockopt");
     }
 }
 
@@ -613,7 +607,7 @@
 
     n = getsockopt(fdval(env, fdo), IPPROTO_IPV6, IPV6_MULTICAST_IF, (void*)&index, &arglen);
     if (n == SOCKET_ERROR) {
-        handleSocketError(env, WSAGetLastError());
+        NET_ThrowNew(env, WSAGetLastError(), "getsockopt");
         return -1;
     }
     return (jint)index;
@@ -631,12 +625,12 @@
 JNIEXPORT jint JNICALL
 Java_sun_nio_ch_Net_available(JNIEnv *env, jclass cl, jobject fdo)
 {
-    int count = 0;
-    if (NET_SocketAvailable(fdval(env, fdo), &count) != 0) {
-        handleSocketError(env, WSAGetLastError());
+    u_long arg;
+    if (ioctlsocket((SOCKET) fdval(env, fdo), FIONREAD, &arg) == SOCKET_ERROR) {
+        NET_ThrowNew(env, WSAGetLastError(), "ioctlsocket");
         return IOS_THROWN;
     }
-    return (jint) count;
+    return (jint) arg;
 }
 
 JNIEXPORT jint JNICALL
@@ -668,7 +662,7 @@
 
     /* save last winsock error */
     if (rv == SOCKET_ERROR) {
-        handleSocketError(env, WSAGetLastError());
+        NET_ThrowNew(env, WSAGetLastError(), "select");
         return IOS_THROWN;
     } else if (rv >= 0) {
         rv = 0;
@@ -708,7 +702,7 @@
     result = select(fd+1, 0, &wr, &ex, (timeout >= 0) ? &t : NULL);
 
     if (result == SOCKET_ERROR) {
-        handleSocketError(env, WSAGetLastError());
+        NET_ThrowNew(env, WSAGetLastError(), "select");
         return JNI_FALSE;
     } else if (result == 0) {
         return JNI_FALSE;
@@ -728,7 +722,7 @@
                 NET_ThrowNew(env, lastError, "getsockopt");
             }
         } else if (optError != NO_ERROR) {
-            handleSocketError(env, optError);
+            NET_ThrowNew(env, optError, "getsockopt");
         }
         return JNI_FALSE;
     }
diff --git a/src/java.base/windows/native/libnio/ch/UnixDomainSockets.c b/src/java.base/windows/native/libnio/ch/UnixDomainSockets.c
index aaf8996..209c30f 100644
--- a/src/java.base/windows/native/libnio/ch/UnixDomainSockets.c
+++ b/src/java.base/windows/native/libnio/ch/UnixDomainSockets.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -158,7 +158,8 @@
 {
     SOCKET s = WSASocketW(PF_UNIX, SOCK_STREAM, 0, &provider, 0, WSA_FLAG_OVERLAPPED);
     if (s == INVALID_SOCKET) {
-        return handleSocketError(env, WSAGetLastError());
+        NET_ThrowNew(env, WSAGetLastError(), "WSASocketW");
+        return IOS_THROWN;
     }
     SetHandleInformation((HANDLE)s, HANDLE_FLAG_INHERIT, 0);
     return (int)s;
diff --git a/src/java.base/windows/native/libnio/ch/WindowsAsynchronousServerSocketChannelImpl.c b/src/java.base/windows/native/libnio/ch/WindowsAsynchronousServerSocketChannelImpl.c
index a08f3a3..2c6de95 100644
--- a/src/java.base/windows/native/libnio/ch/WindowsAsynchronousServerSocketChannelImpl.c
+++ b/src/java.base/windows/native/libnio/ch/WindowsAsynchronousServerSocketChannelImpl.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -69,6 +69,10 @@
     DWORD dwBytes;
 
     s = socket(AF_INET, SOCK_STREAM, 0);
+    if (s == INVALID_SOCKET && WSAGetLastError() == WSAEAFNOSUPPORT) {
+        /* IPv4 unavailable... try IPv6 instead */
+        s = socket(AF_INET6, SOCK_STREAM, 0);
+    }
     if (s == INVALID_SOCKET) {
         JNU_ThrowIOExceptionWithLastError(env, "socket failed");
         return;
@@ -127,7 +131,9 @@
     SOCKET s1 = (SOCKET)jlong_to_ptr(listenSocket);
     SOCKET s2 = (SOCKET)jlong_to_ptr(acceptSocket);
 
-    setsockopt(s2, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, (char *)&s1, sizeof(s1));
+    if (setsockopt(s2, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, (char *)&s1, sizeof(s1)) == SOCKET_ERROR) {
+        JNU_ThrowIOExceptionWithLastError(env, "setsockopt failed");
+    }
 }
 
 
diff --git a/src/java.base/windows/native/libnio/ch/WindowsAsynchronousSocketChannelImpl.c b/src/java.base/windows/native/libnio/ch/WindowsAsynchronousSocketChannelImpl.c
index 40b8d8b..b325c34 100644
--- a/src/java.base/windows/native/libnio/ch/WindowsAsynchronousSocketChannelImpl.c
+++ b/src/java.base/windows/native/libnio/ch/WindowsAsynchronousSocketChannelImpl.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -66,6 +66,10 @@
     DWORD dwBytes;
 
     s = socket(AF_INET, SOCK_STREAM, 0);
+    if (s == INVALID_SOCKET && WSAGetLastError() == WSAEAFNOSUPPORT) {
+        /* IPv4 unavailable... try IPv6 instead */
+        s = socket(AF_INET6, SOCK_STREAM, 0);
+    }
     if (s == INVALID_SOCKET) {
         JNU_ThrowIOExceptionWithLastError(env, "socket failed");
         return;
@@ -119,7 +123,9 @@
     jlong socket)
 {
     SOCKET s = (SOCKET)jlong_to_ptr(socket);
-    setsockopt(s, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0);
+    if (setsockopt(s, SOL_SOCKET, SO_UPDATE_CONNECT_CONTEXT, NULL, 0) == SOCKET_ERROR) {
+        JNU_ThrowIOExceptionWithLastError(env, "setsockopt failed");
+    }
 }
 
 
diff --git a/src/java.base/windows/native/libnio/ch/nio_util.h b/src/java.base/windows/native/libnio/ch/nio_util.h
index a4506d9..b90e0ac6 100644
--- a/src/java.base/windows/native/libnio/ch/nio_util.h
+++ b/src/java.base/windows/native/libnio/ch/nio_util.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -46,7 +46,6 @@
 jint convertReturnVal(JNIEnv *env, jint n, jboolean r);
 jlong convertLongReturnVal(JNIEnv *env, jlong n, jboolean r);
 jboolean purgeOutstandingICMP(JNIEnv *env, jclass clazz, jint fd);
-jint handleSocketError(JNIEnv *env, int errorValue);
 
 #ifdef _WIN64
 
diff --git a/src/java.desktop/macosx/classes/com/apple/laf/AquaComboBoxUI.java b/src/java.desktop/macosx/classes/com/apple/laf/AquaComboBoxUI.java
index 06f84d0..a7e3991 100644
--- a/src/java.desktop/macosx/classes/com/apple/laf/AquaComboBoxUI.java
+++ b/src/java.desktop/macosx/classes/com/apple/laf/AquaComboBoxUI.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -252,9 +252,8 @@
                         if (editor instanceof AquaCustomComboTextField) {
                             ((AquaCustomComboTextField)editor).selectAll();
                         }
-                    } else {
-                        action.actionPerformed(e);
                     }
+                    action.actionPerformed(e);
                 }
             });
         }
@@ -324,6 +323,8 @@
         actionMap.put("aquaSelectPageDown", highlightPageDownAction);
 
         actionMap.put("aquaHidePopup", hideAction);
+        actionMap.put("aquaOpenPopupOrhighlightLast", openPopupOrHighlightLast);
+        actionMap.put("aquaOpenPopupOrhighlightFirst", openPopupOrHighlightFirst);
 
         SwingUtilities.replaceUIActionMap(comboBox, actionMap);
     }
@@ -454,6 +455,31 @@
     }
 
     class AquaComboBoxLayoutManager extends BasicComboBoxUI.ComboBoxLayoutManager {
+        protected Rectangle rectangleForCurrentValue() {
+            int width = comboBox.getWidth();
+            int height = comboBox.getBorder() == null ? 22 : comboBox.getHeight();
+            Insets insets = getInsets();
+            int buttonSize = height - (insets.top + insets.bottom);
+            if ( arrowButton != null )  {
+                buttonSize = arrowButton.getWidth();
+            }
+            int midHeight = (comboBox.getHeight() - height - (insets.top + insets.bottom)) / 2 - 1;
+            if (midHeight < 0) {
+                midHeight = 0;
+            }
+
+            if (comboBox.getComponentOrientation().isLeftToRight()) {
+                return new Rectangle(insets.left, insets.top + midHeight,
+                        width - (insets.left + insets.right + buttonSize) + 3,
+                        height - (insets.top + insets.bottom));
+            }
+            else {
+                return new Rectangle(insets.left + buttonSize, insets.top + midHeight,
+                        width - (insets.left + insets.right + buttonSize) + 3,
+                        height - (insets.top + insets.bottom));
+            }
+        }
+
         public void layoutContainer(final Container parent) {
             if (arrowButton != null && !comboBox.isEditable()) {
                 final Insets insets = comboBox.getInsets();
@@ -477,8 +503,6 @@
 
             if (editor != null) {
                 final Rectangle editorRect = rectangleForCurrentValue();
-                editorRect.width += 4;
-                editorRect.height += 1;
                 editor.setBounds(editorRect);
             }
         }
@@ -582,6 +606,27 @@
         }
     };
 
+    @SuppressWarnings("serial") // anonymous class
+    private final Action openPopupOrHighlightLast = new ComboBoxAction() {
+        @Override
+        void performComboBoxAction(final AquaComboBoxUI ui) {
+            final int size = listBox.getModel().getSize();
+            listBox.setSelectedIndex(size - 1);
+            listBox.ensureIndexIsVisible(size - 1);
+            comboBox.setSelectedIndex(ui.getPopup().getList().getSelectedIndex());
+        }
+    };
+
+    @SuppressWarnings("serial") // anonymous class
+    private final Action openPopupOrHighlightFirst = new ComboBoxAction() {
+        @Override
+        void performComboBoxAction(final AquaComboBoxUI ui) {
+           listBox.setSelectedIndex(0);
+           listBox.ensureIndexIsVisible(0);
+           comboBox.setSelectedIndex(ui.getPopup().getList().getSelectedIndex());
+        }
+    };
+
     public void applySizeFor(final JComponent c, final Size size) {
         if (arrowButton == null) return;
         final Border border = arrowButton.getBorder();
@@ -620,13 +665,6 @@
             size = super.getMinimumSize(c);
         }
 
-        final Border border = c.getBorder();
-        if (border != null) {
-            final Insets insets = border.getBorderInsets(c);
-            size.height += insets.top + insets.bottom;
-            size.width += insets.left + insets.right;
-        }
-
         cachedMinimumSize.setSize(size.width, size.height);
         isMinimumSizeDirty = false;
 
diff --git a/src/java.desktop/macosx/classes/com/apple/laf/AquaKeyBindings.java b/src/java.desktop/macosx/classes/com/apple/laf/AquaKeyBindings.java
index e8e84f4..81b87f5 100644
--- a/src/java.desktop/macosx/classes/com/apple/laf/AquaKeyBindings.java
+++ b/src/java.desktop/macosx/classes/com/apple/laf/AquaKeyBindings.java
@@ -220,6 +220,10 @@
             "KP_UP", "aquaSelectPrevious",
             "DOWN", "aquaSelectNext",
             "KP_DOWN", "aquaSelectNext",
+            "alt DOWN", "aquaOpenPopupOrhighlightLast",
+            "alt KP_DOWN", "aquaOpenPopupOrhighlightLast",
+            "alt UP", "aquaOpenPopupOrhighlightFirst",
+            "alt KP_UP", "aquaOpenPopupOrhighlightFirst",
             "SPACE", "aquaSpacePressed" // "spacePopup"
         }));
     }
diff --git a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessible.java b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessible.java
index af38932..b25e37c 100644
--- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessible.java
+++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessible.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -170,7 +170,7 @@
                             }
                         }
                     }
-                } else if (name.compareTo(ACCESSIBLE_STATE_PROPERTY) == 0) {
+                } else if (name.equals(ACCESSIBLE_STATE_PROPERTY)) {
                     AccessibleContext thisAC = accessible.getAccessibleContext();
                     AccessibleRole thisRole = thisAC.getAccessibleRole();
                     Accessible parentAccessible = thisAC.getAccessibleParent();
@@ -224,14 +224,42 @@
 
                     // Do send check box state changes to native side
                     if (thisRole == AccessibleRole.CHECK_BOX) {
-                        execute(ptr -> valueChanged(ptr));
+                        if (newValue != null && !newValue.equals(oldValue)) {
+                            execute(ptr -> valueChanged(ptr));
+                        }
+
+                        // Notify native side to handle check box style menuitem
+                        if (parentRole == AccessibleRole.POPUP_MENU && newValue != null
+                                && ((AccessibleState)newValue) == AccessibleState.FOCUSED) {
+                            menuItemSelected(ptr);
+                        }
                     }
-                } else if (name.compareTo(ACCESSIBLE_NAME_PROPERTY) == 0) {
+
+                    // Do send radio button state changes to native side
+                    if (thisRole == AccessibleRole.RADIO_BUTTON) {
+                        if (newValue != null && !newValue.equals(oldValue)) {
+                            valueChanged(ptr);
+                        }
+
+                        // Notify native side to handle radio button style menuitem
+                        if (parentRole == AccessibleRole.POPUP_MENU && newValue != null
+                            && ((AccessibleState)newValue) == AccessibleState.FOCUSED) {
+                            menuItemSelected(ptr);
+                        }
+                    }
+
+                    // Do send toggle button state changes to native side
+                    if (thisRole == AccessibleRole.TOGGLE_BUTTON) {
+                        if (newValue != null && !newValue.equals(oldValue)) {
+                            valueChanged(ptr);
+                        }
+                    }
+                } else if (name.equals(ACCESSIBLE_NAME_PROPERTY)) {
                     //for now trigger only for JTabbedPane.
                     if (e.getSource() instanceof JTabbedPane) {
                         execute(ptr -> titleChanged(ptr));
                     }
-                } else if (name.compareTo(ACCESSIBLE_VALUE_PROPERTY) == 0) {
+                } else if (name.equals(ACCESSIBLE_VALUE_PROPERTY)) {
                     AccessibleRole thisRole = accessible.getAccessibleContext()
                                                         .getAccessibleRole();
                     if (thisRole == AccessibleRole.SLIDER ||
diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLGlyphCache.m b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLGlyphCache.m
index 7ff7410..4808092 100644
--- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLGlyphCache.m
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLGlyphCache.m
@@ -215,37 +215,6 @@
     }
     return JNI_FALSE;
 }
-/**
- * Invalidates all cells in the cache.  Note that this method does not
- * attempt to compact the cache in any way; it just invalidates any cells
- * that already exist.
- */
-- (void) invalidate
-{
-    MTLCacheCellInfo *cellinfo;
-
-    J2dTraceLn(J2D_TRACE_INFO, "MTLGlyphCache.invalidate");
-
-    if (_cacheInfo == NULL) {
-        return;
-    }
-
-    // flush any pending vertices that may be depending on the current
-    // glyph cache layout
-    if (_cacheInfo->Flush != NULL) {
-        _cacheInfo->Flush(_cacheInfo->mtlc);
-    }
-
-    cellinfo = _cacheInfo->head;
-    while (cellinfo != NULL) {
-        if (cellinfo->glyphInfo != NULL) {
-            // if the cell is occupied, notify the base glyph that its
-            // cached version for this cache is about to be invalidated
-            MTLGlyphCache_RemoveCellInfo(cellinfo->glyphInfo, cellinfo);
-        }
-        cellinfo = cellinfo->next;
-    }
-}
 
 /**
  * Invalidates and frees all cells and the cache itself. The "cache" pointer
diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLGraphicsConfig.m b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLGraphicsConfig.m
index 586e824..88298ce 100644
--- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLGraphicsConfig.m
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLGraphicsConfig.m
@@ -38,19 +38,17 @@
 {
     J2dTraceLn(J2D_TRACE_INFO, "MTLGC_DestroyMTLGraphicsConfig");
     JNI_COCOA_ENTER(env);
+    __block MTLGraphicsConfigInfo *mtlinfo = (MTLGraphicsConfigInfo *)jlong_to_ptr(pConfigInfo);
+    if (mtlinfo == NULL) {
+        J2dRlsTraceLn(J2D_TRACE_ERROR,
+                      "MTLGC_DestroyMTLGraphicsConfig: info is null");
+        return;
+    }
+    __block MTLContext *mtlc = (MTLContext*)mtlinfo->context;
+    mtlinfo->context = nil;
     [ThreadUtilities performOnMainThreadWaiting:NO block:^() {
-        MTLGraphicsConfigInfo *mtlinfo =
-            (MTLGraphicsConfigInfo *)jlong_to_ptr(pConfigInfo);
-        if (mtlinfo == NULL) {
-            J2dRlsTraceLn(J2D_TRACE_ERROR,
-                          "MTLGC_DestroyMTLGraphicsConfig: info is null");
-            return;
-        }
-
-        MTLContext *mtlc = (MTLContext*)mtlinfo->context;
         if (mtlc != NULL) {
-            [mtlinfo->context release];
-            mtlinfo->context = nil;
+            [mtlc release];
         }
         free(mtlinfo);
     }];
diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLPipelineStatesStorage.m b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLPipelineStatesStorage.m
index 9a7862e..27b3507 100644
--- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLPipelineStatesStorage.m
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLPipelineStatesStorage.m
@@ -255,8 +255,11 @@
 }
 
 - (void) dealloc {
-    [super dealloc];
     [computeStates release];
+    self.library = nil;
+    self.shaders = nil;
+    self.states = nil;
+    [super dealloc];
 }
 @end
 
diff --git a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLTextRenderer.m b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLTextRenderer.m
index cef4063..5829548 100644
--- a/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLTextRenderer.m
+++ b/src/java.desktop/macosx/native/libawt_lwawt/java2d/metal/MTLTextRenderer.m
@@ -372,17 +372,17 @@
             DisableColorGlyphPainting(mtlc);
         }
 
-        if (!MTLTR_ValidateGlyphCache(mtlc, dstOps, JNI_TRUE)) {
-            return JNI_FALSE;
-        }
-
         if (rgbOrder != lastRGBOrder) {
             // need to invalidate the cache in this case; see comments
             // for lastRGBOrder above
-            [mtlc.glyphCacheLCD invalidate];
+            [mtlc.glyphCacheLCD free];
             lastRGBOrder = rgbOrder;
         }
 
+        if (!MTLTR_ValidateGlyphCache(mtlc, dstOps, JNI_TRUE)) {
+            return JNI_FALSE;
+        }
+
         glyphMode = MODE_USE_CACHE_LCD;
     }
 
@@ -605,10 +605,6 @@
     return JNI_TRUE;
 }
 
-// see DrawGlyphList.c for more on this macro...
-#define FLOOR_ASSIGN(l, r) \
-    if ((r)<0) (l) = ((int)floor(r)); else (l) = ((int)(r))
-
 #define ADJUST_SUBPIXEL_GLYPH_POSITION(coord, res) \
     if ((res) > 1) (coord) += 0.5f / ((float)(res)) - 0.5f
 
@@ -653,21 +649,30 @@
             jfloat posy = NEXT_FLOAT(positions);
             glyphx = glyphListOrigX + posx + ginfo->topLeftX;
             glyphy = glyphListOrigY + posy + ginfo->topLeftY;
-            ADJUST_SUBPIXEL_GLYPH_POSITION(glyphx, ginfo->subpixelResolutionX);
-            ADJUST_SUBPIXEL_GLYPH_POSITION(glyphy, ginfo->subpixelResolutionY);
-            FLOOR_ASSIGN(x, glyphx);
-            FLOOR_ASSIGN(y, glyphy);
         } else {
             glyphx = glyphListOrigX + ginfo->topLeftX;
             glyphy = glyphListOrigY + ginfo->topLeftY;
-            ADJUST_SUBPIXEL_GLYPH_POSITION(glyphx, ginfo->subpixelResolutionX);
-            ADJUST_SUBPIXEL_GLYPH_POSITION(glyphy, ginfo->subpixelResolutionY);
-            FLOOR_ASSIGN(x, glyphx);
-            FLOOR_ASSIGN(y, glyphy);
             glyphListOrigX += ginfo->advanceX;
             glyphListOrigY += ginfo->advanceY;
         }
 
+        int rx = ginfo->subpixelResolutionX;
+        int ry = ginfo->subpixelResolutionY;
+        ADJUST_SUBPIXEL_GLYPH_POSITION(glyphx, rx);
+        ADJUST_SUBPIXEL_GLYPH_POSITION(glyphy, ry);
+        float fx = floor(glyphx);
+        float fy = floor(glyphy);
+        x = (int) fx;
+        y = (int) fy;
+        int subimage;
+        if ((rx == 1 && ry == 1) || rx <= 0 || ry <= 0) {
+            subimage = 0;
+        } else {
+            int subx = (int) ((glyphx - fx) * (float) rx);
+            int suby = (int) ((glyphy - fy) * (float) ry);
+            subimage = subx + suby * rx;
+        }
+
         if (ginfo->image == NULL) {
             J2dTraceLn(J2D_TRACE_INFO, "Glyph image is null");
             continue;
@@ -677,14 +682,6 @@
         J2dTraceLn1(J2D_TRACE_INFO, "rowBytes = %d", ginfo->rowBytes);
         if (ginfo->format == sun_font_StrikeCache_PIXEL_FORMAT_GREYSCALE) {
             // grayscale or monochrome glyph data
-            int rx = ginfo->subpixelResolutionX;
-            int ry = ginfo->subpixelResolutionY;
-            int subimage;
-            if ((rx == 1 && ry == 1) || rx <= 0 || ry <= 0) {
-                subimage = 0;
-            } else {
-                subimage = (jint)((glyphx - x) * rx) + (jint)((glyphy - y) * ry) * rx;
-            }
             if (ginfo->width <= MTLTR_CACHE_CELL_WIDTH &&
                 ginfo->height <= MTLTR_CACHE_CELL_HEIGHT)
             {
diff --git a/src/java.desktop/share/classes/javax/swing/BoxLayout.java b/src/java.desktop/share/classes/javax/swing/BoxLayout.java
index bc84a4fa..2a0f586 100644
--- a/src/java.desktop/share/classes/javax/swing/BoxLayout.java
+++ b/src/java.desktop/share/classes/javax/swing/BoxLayout.java
@@ -459,7 +459,8 @@
     }
 
     void checkRequests() {
-        if (xChildren == null || yChildren == null) {
+        // check yTotal, as it's assigned the last, to ensure initialization completed without exceptions:
+        if (yTotal == null) {
             // The requests have been invalidated... recalculate
             // the request information.
             int n = target.getComponentCount();
diff --git a/src/java.desktop/share/classes/javax/swing/JList.java b/src/java.desktop/share/classes/javax/swing/JList.java
index 83b6cbe..7932209 100644
--- a/src/java.desktop/share/classes/javax/swing/JList.java
+++ b/src/java.desktop/share/classes/javax/swing/JList.java
@@ -2947,7 +2947,7 @@
             Object newValue = e.getNewValue();
 
                 // re-set listData listeners
-            if (name.compareTo("model") == 0) {
+            if (name.equals("model")) {
 
                 if (oldValue != null && oldValue instanceof ListModel) {
                     ((ListModel) oldValue).removeListDataListener(this);
@@ -2957,7 +2957,7 @@
                 }
 
                 // re-set listSelectionModel listeners
-            } else if (name.compareTo("selectionModel") == 0) {
+            } else if (name.equals("selectionModel")) {
 
                 if (oldValue != null && oldValue instanceof ListSelectionModel) {
                     ((ListSelectionModel) oldValue).removeListSelectionListener(this);
diff --git a/src/java.desktop/share/classes/javax/swing/JTable.java b/src/java.desktop/share/classes/javax/swing/JTable.java
index ee65ce9..a0d74a3 100644
--- a/src/java.desktop/share/classes/javax/swing/JTable.java
+++ b/src/java.desktop/share/classes/javax/swing/JTable.java
@@ -6771,7 +6771,7 @@
             Object newValue = e.getNewValue();
 
                 // re-set tableModel listeners
-            if (name.compareTo("model") == 0) {
+            if (name.equals("model")) {
 
                 if (oldValue != null && oldValue instanceof TableModel) {
                     ((TableModel) oldValue).removeTableModelListener(this);
@@ -6781,7 +6781,7 @@
                 }
 
                 // re-set selectionModel listeners
-            } else if (name.compareTo("selectionModel") == 0) {
+            } else if (name.equals("selectionModel")) {
 
                 Object source = e.getSource();
                 if (source == JTable.this) {    // row selection model
@@ -6812,7 +6812,7 @@
 
                 // re-set columnModel listeners
                 // and column's selection property listener as well
-            } else if (name.compareTo("columnModel") == 0) {
+            } else if (name.equals("columnModel")) {
 
                 if (oldValue != null && oldValue instanceof TableColumnModel) {
                     TableColumnModel tcm = (TableColumnModel) oldValue;
@@ -6826,7 +6826,7 @@
                 }
 
                 // re-se cellEditor listeners
-            } else if (name.compareTo("tableCellEditor") == 0) {
+            } else if (name.equals("tableCellEditor")) {
 
                 if (oldValue != null && oldValue instanceof TableCellEditor) {
                     ((TableCellEditor) oldValue).removeCellEditorListener(this);
diff --git a/src/java.desktop/share/classes/javax/swing/text/rtf/RTFParser.java b/src/java.desktop/share/classes/javax/swing/text/rtf/RTFParser.java
index 259b63e..05f45cc 100644
--- a/src/java.desktop/share/classes/javax/swing/text/rtf/RTFParser.java
+++ b/src/java.desktop/share/classes/javax/swing/text/rtf/RTFParser.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,10 @@
 
 import java.io.*;
 import java.lang.*;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CoderResult;
 
 /**
  * <b>RTFParser</b> is a subclass of <b>AbstractFilter</b> which understands basic RTF syntax
@@ -69,6 +73,11 @@
 
   private final int S_inblob = 6;        // in a \bin blob
 
+    // For fcharset control word
+    protected CharsetDecoder decoder = null;
+    private byte[] ba = new byte[2];
+    protected ByteBuffer decoderBB = ByteBuffer.wrap(ba);
+
   /** Implemented by subclasses to interpret a parameter-less RTF keyword.
    *  The keyword is passed without the leading '/' or any delimiting
    *  whitespace. */
@@ -100,6 +109,9 @@
     rtfSpecialsTable['\\'] = true;
   }
 
+    // Defined for replacement character
+    static final char REPLACEMENT_CHAR = '\uFFFD';
+
   public RTFParser()
   {
     currentCharacters = new StringBuffer();
@@ -109,6 +121,9 @@
     //warnings = System.out;
 
     specialsTable = rtfSpecialsTable;
+    // Initialize byte buffer for CharsetDecoder
+    decoderBB.clear();
+    decoderBB.limit(1);
   }
 
   // TODO: Handle wrapup at end of file correctly.
@@ -182,6 +197,9 @@
           }
           state = S_backslashed;
         } else {
+          // SBCS: ASCII character
+          // DBCS: Non lead byte
+          ch = decode(ch);
           currentCharacters.append(ch);
         }
         break;
@@ -301,7 +319,9 @@
         if (Character.digit(ch, 16) != -1)
         {
           pendingCharacter = pendingCharacter * 16 + Character.digit(ch, 16);
-          ch = translationTable[pendingCharacter];
+          // Use translationTable if decoder is not defined
+          ch = decoder == null ? translationTable[pendingCharacter]
+                               : decode((char)pendingCharacter);
           if (ch != 0)
               handleText(ch);
         }
@@ -360,4 +380,37 @@
     super.close();
   }
 
+    // For fcharset control word
+    private char[] ca = new char[1];
+    private CharBuffer decoderCB = CharBuffer.wrap(ca);
+
+    private char decode(char ch) {
+        if (decoder == null) return ch;
+        decoderBB.put((byte) ch);
+        decoderBB.rewind();
+        decoderCB.clear();
+        CoderResult cr = decoder.decode(decoderBB, decoderCB, false);
+        if (cr.isUnderflow()) {
+            if (decoderCB.position() == 1) {
+                // Converted to Unicode (including replacement character)
+                decoder.reset();
+                decoderBB.clear();
+                decoderBB.limit(1);
+                return ca[0];
+            } else {
+                // Detected lead byte
+                decoder.reset();
+                decoderBB.limit(2);
+                decoderBB.position(1);
+                return 0; // Skip write operation if return value is 0
+            }
+        } else {
+            // Fallback, should not be called
+            decoder.reset();
+            decoderBB.clear();
+            decoderBB.limit(1);
+            return REPLACEMENT_CHAR;
+        }
+    }
+
 }
diff --git a/src/java.desktop/share/classes/javax/swing/text/rtf/RTFReader.java b/src/java.desktop/share/classes/javax/swing/text/rtf/RTFReader.java
index 0388469..e870bb4 100644
--- a/src/java.desktop/share/classes/javax/swing/text/rtf/RTFReader.java
+++ b/src/java.desktop/share/classes/javax/swing/text/rtf/RTFReader.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,10 +28,17 @@
 import java.util.*;
 import java.io.*;
 import java.awt.Color;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CodingErrorAction;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import javax.swing.text.*;
 
+import static java.nio.charset.StandardCharsets.ISO_8859_1;
+
 /**
  * Takes a sequence of RTF tokens and text and appends the text
  * described by the RTF to a <code>StyledDocument</code> (the <em>target</em>).
@@ -64,6 +71,10 @@
 
   /** This Dictionary maps Integer font numbers to String font names. */
   Dictionary<Integer, String> fontTable;
+  /** This Dictionary maps Integer font numbers to Charset font charset. */
+  Dictionary<Integer, Charset> fcharsetTable;
+  /** This Dictionary maps String font charset to String code page. */
+  static Dictionary<String, String> fcharsetToCP = null;
   /** This array maps color indices to Color objects. */
   Color[] colorTable;
   /** This Map maps character style numbers to Style objects. */
@@ -110,6 +121,7 @@
       textKeywords.put("emspace",    "\u2003");
       textKeywords.put("endash",     "\u2013");
       textKeywords.put("enspace",    "\u2002");
+      textKeywords.put("line",       "\n");
       textKeywords.put("ldblquote",  "\u201C");
       textKeywords.put("lquote",     "\u2018");
       textKeywords.put("ltrmark",    "\u200E");
@@ -136,7 +148,50 @@
       defineCharacterSet("ansicpg", latin1TranslationTable);
   }
 
-/* TODO: per-font font encodings ( \fcharset control word ) ? */
+    /**
+     * Windows font charset
+     */
+    private static final int ANSI_CHARSET        = 0;
+    private static final int DEFAULT_CHARSET     = 1;
+    private static final int SYMBOL_CHARSET      = 2;
+    private static final int MAC_CHARSET         = 77;
+    private static final int SHIFTJIS_CHARSET    = 128;
+    private static final int HANGUL_CHARSET      = 129;
+    private static final int JOHAB_CHARSET       = 130;
+    private static final int GB2312_CHARSET      = 134;
+    private static final int CHINESEBIG5_CHARSET = 136;
+    private static final int GREEK_CHARSET       = 161;
+    private static final int TURKISH_CHARSET     = 162;
+    private static final int VIETNAMESE_CHARSET  = 163;
+    private static final int HEBREW_CHARSET      = 177;
+    private static final int ARABIC_CHARSET      = 178;
+    private static final int BALTIC_CHARSET      = 186;
+    private static final int RUSSIAN_CHARSET     = 204;
+    private static final int THAI_CHARSET        = 222;
+    private static final int EASTEUROPE_CHARSET  = 238;
+    private static final int OEM_CHARSET         = 255;
+
+    static {
+        fcharsetToCP = new Hashtable<String, String>();
+        fcharsetToCP.put("fcharset" + ANSI_CHARSET, "windows-1252");
+        fcharsetToCP.put("fcharset" + SHIFTJIS_CHARSET, "ms932");
+        fcharsetToCP.put("fcharset" + HANGUL_CHARSET, "ms949");
+        fcharsetToCP.put("fcharset" + JOHAB_CHARSET, "ms1361");
+        fcharsetToCP.put("fcharset" + GB2312_CHARSET, "ms936");
+        fcharsetToCP.put("fcharset" + CHINESEBIG5_CHARSET, "ms950");
+        fcharsetToCP.put("fcharset" + GREEK_CHARSET, "windows-1253");
+        fcharsetToCP.put("fcharset" + TURKISH_CHARSET, "windows-1254");
+        fcharsetToCP.put("fcharset" + VIETNAMESE_CHARSET, "windows-1258");
+        fcharsetToCP.put("fcharset" + HEBREW_CHARSET, "windows-1255");
+        fcharsetToCP.put("fcharset" + ARABIC_CHARSET, "windows-1256");
+        fcharsetToCP.put("fcharset" + BALTIC_CHARSET, "windows-1257");
+        fcharsetToCP.put("fcharset" + RUSSIAN_CHARSET, "windows-1251");
+        fcharsetToCP.put("fcharset" + THAI_CHARSET, "ms874");
+        fcharsetToCP.put("fcharset" + EASTEUROPE_CHARSET, "windows-1250");
+    }
+
+    // Defined for replacement character
+    private static final String REPLACEMENT_CHAR = "\uFFFD";
 
 /**
  * Creates a new RTFReader instance. Text will be sent to
@@ -151,6 +206,7 @@
     target = destination;
     parserState = new Hashtable<Object, Object>();
     fontTable = new Hashtable<Integer, String>();
+    fcharsetTable = new Hashtable<Integer, Charset>();
 
     rtfversion = -1;
 
@@ -740,6 +796,25 @@
             nextFontNumber = parameter;
             return true;
         }
+        // For fcharset control word
+        if (keyword.equals("fcharset")) {
+            String fcharset = keyword+parameter;
+            String csName = fcharsetToCP.get(fcharset);
+            Charset cs;
+            if (csName != null) {
+                try {
+                    cs = Charset.forName(csName);
+                } catch (IllegalArgumentException iae) {
+                    // Fallback, should not be called
+                    cs = ISO_8859_1;
+                }
+            } else {
+                // Fallback, fcharset control word number is not defined
+                cs = ISO_8859_1;
+            }
+            fcharsetTable.put(nextFontNumber, cs);
+            return true;
+        }
 
         return false;
     }
@@ -1194,6 +1269,25 @@
 
         if (keyword.equals("f")) {
             parserState.put(keyword, Integer.valueOf(parameter));
+
+            // Check lead byte is stored or not
+            if (decoderBB.position() == 1) {
+                handleText(REPLACEMENT_CHAR);
+            }
+            // Reset decoder byte buffer
+            decoderBB.clear();
+            decoderBB.limit(1);
+            // Check fcharset is used or not
+            Charset cs = fcharsetTable.get(parameter);
+            if (cs != null) {
+                decoder = cs.newDecoder();
+                decoder.onMalformedInput(CodingErrorAction.REPLACE)
+                       .onUnmappableCharacter(CodingErrorAction.REPLACE);
+            } else {
+                // fcharset is not used, use translationTable
+                decoder = null;
+            }
+
             return true;
         }
         if (keyword.equals("cf")) {
@@ -1588,6 +1682,12 @@
 
         if (keyword.equals("par")) {
 //          warnings.println("Ending paragraph.");
+            // Check lead byte is stored or not
+            if (decoderBB.position() == 1) {
+                handleText(REPLACEMENT_CHAR);
+                decoderBB.clear();
+                decoderBB.limit(1);
+            }
             endParagraph();
             return true;
         }
diff --git a/src/java.desktop/share/classes/sun/swing/AccessibleAnnouncer.java b/src/java.desktop/share/classes/sun/swing/AccessibleAnnouncer.java
index 34e7e5a..e40082d 100644
--- a/src/java.desktop/share/classes/sun/swing/AccessibleAnnouncer.java
+++ b/src/java.desktop/share/classes/sun/swing/AccessibleAnnouncer.java
@@ -26,10 +26,13 @@
 
 package sun.swing;
 
+import jdk.internal.misc.InnocuousThread;
 import sun.awt.AWTThreading;
 
 import javax.accessibility.Accessible;
 import java.lang.annotation.Native;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
 
 /**
   * This class provides the ability to speak a given string using screen readers.
@@ -48,6 +51,8 @@
      */
     @Native public static final int ANNOUNCE_WITH_INTERRUPTING_CURRENT_OUTPUT = 1;
 
+    private static ExecutorService executor;
+
     private AccessibleAnnouncer() {}
 
     /**
@@ -74,12 +79,20 @@
             throw new IllegalArgumentException("Invalid parameters passed for declaration");
         }
 
-        AWTThreading.executeWaitToolkit(new Runnable() {
-            @Override
-            public void run() {
-                nativeAnnounce(a, str, priority);
+        // On Windows, this doesn't need to run on EDT and may be a long-running operation,
+        // so execute it on a background thread.
+        if (System.getProperty("os.name").startsWith("Windows")) {
+            if (executor == null) {
+                executor = Executors.newSingleThreadExecutor(r -> {
+                    Thread t = InnocuousThread.newSystemThread(AccessibleAnnouncer.class.getSimpleName(), r);
+                    t.setDaemon(true);
+                    return t;
+                });
             }
-        });
+            executor.execute(() -> nativeAnnounce(a, str, priority));
+        } else {
+            AWTThreading.executeWaitToolkit(() -> nativeAnnounce(a, str, priority));
+        }
     }
 
     private static native void nativeAnnounce(Accessible a, final String str, final int priority);
diff --git a/src/java.desktop/share/legal/freetype.md b/src/java.desktop/share/legal/freetype.md
index d602abb..6bcb497 100644
--- a/src/java.desktop/share/legal/freetype.md
+++ b/src/java.desktop/share/legal/freetype.md
@@ -1,4 +1,4 @@
-## The FreeType Project: Freetype v2.13.0
+## The FreeType Project: Freetype v2.13.2
 
 
 ### FreeType Notice
diff --git a/src/java.desktop/share/legal/harfbuzz.md b/src/java.desktop/share/legal/harfbuzz.md
index e2ed76a..3ae73d2 100644
--- a/src/java.desktop/share/legal/harfbuzz.md
+++ b/src/java.desktop/share/legal/harfbuzz.md
@@ -1,9 +1,7 @@
-## Harfbuzz v7.2.0
+## Harfbuzz v8.2.2
 
 ### Harfbuzz License
 
-https://github.com/harfbuzz/harfbuzz/blob/7.2.0/COPYING
-
 <pre>
 
 HarfBuzz is licensed under the so-called "Old MIT" license.  Details follow.
@@ -14,6 +12,7 @@
 Copyright © 2018-2020  Ebrahim Byagowi
 Copyright © 2004-2013  Red Hat, Inc.
 Copyright © 2019  Facebook, Inc.
+Copyright (C) 2012 Zilong Tan (eric.zltan@gmail.com)
 Copyright © 2007  Chris Wilson
 Copyright © 2018-2019 Adobe Inc.
 Copyright © 2006-2023 Behdad Esfahbod
@@ -72,6 +71,15 @@
 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
+---------------------------------
+The below license applies to the following files:
+libharfbuzz/hb-unicode-emoji-table.hh
+
+© 2023 Unicode®, Inc.
+Unicode and the Unicode Logo are registered trademarks of Unicode, Inc.
+in the U.S. and other countries.
+For terms of use, see https://www.unicode.org/terms_of_use.html
+
 </pre>
 
 ### AUTHORS File Information
diff --git a/src/java.desktop/share/legal/libpng.md b/src/java.desktop/share/legal/libpng.md
index f11cfe5..f420ccd 100644
--- a/src/java.desktop/share/legal/libpng.md
+++ b/src/java.desktop/share/legal/libpng.md
@@ -1,4 +1,4 @@
-## libpng v1.6.39
+## libpng v1.6.40
 
 ### libpng License
 <pre>
@@ -9,8 +9,8 @@
 PNG Reference Library License version 2
 ---------------------------------------
 
-Copyright (c) 1995-2022 The PNG Reference Library Authors.
-Copyright (c) 2018-2022 Cosmin Truta
+Copyright (c) 1995-2023 The PNG Reference Library Authors.
+Copyright (c) 2018-2023 Cosmin Truta
 Copyright (c) 1998-2018 Glenn Randers-Pehrson
 Copyright (c) 1996-1997 Andreas Dilger
 Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@@ -175,6 +175,7 @@
  * Mike Klein
  * Pascal Massimino
  * Paul Schmidt
+ * Philippe Antoine
  * Qiang Zhou
  * Sam Bushell
  * Samuel Williams
@@ -193,6 +194,7 @@
    - Matt Sarett
    - Mike Klein
    - Sami Boukortt
+   - Wan-Teh Chang
 
 The build projects, the build scripts, the test scripts, and other
 files in the "ci", "projects", "scripts" and "tests" directories, have
diff --git a/src/java.desktop/share/native/common/java2d/opengl/OGLTextRenderer.c b/src/java.desktop/share/native/common/java2d/opengl/OGLTextRenderer.c
index 2aad612..0cf7db8 100644
--- a/src/java.desktop/share/native/common/java2d/opengl/OGLTextRenderer.c
+++ b/src/java.desktop/share/native/common/java2d/opengl/OGLTextRenderer.c
@@ -1216,10 +1216,6 @@
 extern int useFontSmoothing;
 #endif
 
-// see DrawGlyphList.c for more on this macro...
-#define FLOOR_ASSIGN(l, r) \
-    if ((r)<0) (l) = ((int)floor(r)); else (l) = ((int)(r))
-
 #define ADJUST_SUBPIXEL_GLYPH_POSITION(coord, res) \
     if ((res) > 1) (coord) += 0.5f / ((float)(res)) - 0.5f
 
@@ -1290,21 +1286,30 @@
             jfloat posy = NEXT_FLOAT(positions);
             glyphx = glyphListOrigX + posx + ginfo->topLeftX;
             glyphy = glyphListOrigY + posy + ginfo->topLeftY;
-            ADJUST_SUBPIXEL_GLYPH_POSITION(glyphx, ginfo->subpixelResolutionX);
-            ADJUST_SUBPIXEL_GLYPH_POSITION(glyphy, ginfo->subpixelResolutionY);
-            FLOOR_ASSIGN(x, glyphx);
-            FLOOR_ASSIGN(y, glyphy);
         } else {
             glyphx = glyphListOrigX + ginfo->topLeftX;
             glyphy = glyphListOrigY + ginfo->topLeftY;
-            ADJUST_SUBPIXEL_GLYPH_POSITION(glyphx, ginfo->subpixelResolutionX);
-            ADJUST_SUBPIXEL_GLYPH_POSITION(glyphy, ginfo->subpixelResolutionY);
-            FLOOR_ASSIGN(x, glyphx);
-            FLOOR_ASSIGN(y, glyphy);
             glyphListOrigX += ginfo->advanceX;
             glyphListOrigY += ginfo->advanceY;
         }
 
+        int rx = ginfo->subpixelResolutionX;
+        int ry = ginfo->subpixelResolutionY;
+        ADJUST_SUBPIXEL_GLYPH_POSITION(glyphx, rx);
+        ADJUST_SUBPIXEL_GLYPH_POSITION(glyphy, ry);
+        float fx = floor(glyphx);
+        float fy = floor(glyphy);
+        x = (int) fx;
+        y = (int) fy;
+        int subimage;
+        if ((rx == 1 && ry == 1) || rx <= 0 || ry <= 0) {
+            subimage = 0;
+        } else {
+            int subx = (int) ((glyphx - fx) * (float) rx);
+            int suby = (int) ((glyphy - fy) * (float) ry);
+            subimage = subx + suby * rx;
+        }
+
         if (ginfo->image == NULL) {
             continue;
         }
@@ -1314,14 +1319,6 @@
                 OGLContext_InitGrayRenderHints(env, oglc);
             }
             // grayscale or monochrome glyph data
-            int rx = ginfo->subpixelResolutionX;
-            int ry = ginfo->subpixelResolutionY;
-            int subimage;
-            if ((rx == 1 && ry == 1) || rx <= 0 || ry <= 0) {
-                subimage = 0;
-            } else {
-                subimage = (jint)((glyphx - x) * rx) + (jint)((glyphy - y) * ry) * rx;
-            }
             if (ginfo->width <= OGLTR_CACHE_CELL_WIDTH &&
                 ginfo->height <= OGLTR_CACHE_CELL_HEIGHT)
             {
diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/config/ftoption.h b/src/java.desktop/share/native/libfreetype/include/freetype/config/ftoption.h
index c13a3ef..4375c7a 100644
--- a/src/java.desktop/share/native/libfreetype/include/freetype/config/ftoption.h
+++ b/src/java.desktop/share/native/libfreetype/include/freetype/config/ftoption.h
@@ -661,36 +661,12 @@
    * not) instructions in a certain way so that all TrueType fonts look like
    * they do in a Windows ClearType (DirectWrite) environment.  See [1] for a
    * technical overview on what this means.  See `ttinterp.h` for more
-   * details on the LEAN option.
+   * details on this option.
    *
-   * There are three possible values.
-   *
-   * Value 1:
-   *   This value is associated with the 'Infinality' moniker, contributed by
-   *   an individual nicknamed Infinality with the goal of making TrueType
-   *   fonts render better than on Windows.  A high amount of configurability
-   *   and flexibility, down to rules for single glyphs in fonts, but also
-   *   very slow.  Its experimental and slow nature and the original
-   *   developer losing interest meant that this option was never enabled in
-   *   default builds.
-   *
-   *   The corresponding interpreter version is v38.
-   *
-   * Value 2:
-   *   The new default mode for the TrueType driver.  The Infinality code
-   *   base was stripped to the bare minimum and all configurability removed
-   *   in the name of speed and simplicity.  The configurability was mainly
-   *   aimed at legacy fonts like 'Arial', 'Times New Roman', or 'Courier'.
-   *   Legacy fonts are fonts that modify vertical stems to achieve clean
-   *   black-and-white bitmaps.  The new mode focuses on applying a minimal
-   *   set of rules to all fonts indiscriminately so that modern and web
-   *   fonts render well while legacy fonts render okay.
-   *
-   *   The corresponding interpreter version is v40.
-   *
-   * Value 3:
-   *   Compile both, making both v38 and v40 available (the latter is the
-   *   default).
+   * The new default mode focuses on applying a minimal set of rules to all
+   * fonts indiscriminately so that modern and web fonts render well while
+   * legacy fonts render okay.  The corresponding interpreter version is v40.
+   * The so-called Infinality mode (v38) is no longer available in FreeType.
    *
    * By undefining these, you get rendering behavior like on Windows without
    * ClearType, i.e., Windows XP without ClearType enabled and Win9x
@@ -705,9 +681,7 @@
    * [1]
    * https://www.microsoft.com/typography/cleartype/truetypecleartype.aspx
    */
-/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING  1         */
-#define TT_CONFIG_OPTION_SUBPIXEL_HINTING  2
-/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING  ( 1 | 2 ) */
+#define TT_CONFIG_OPTION_SUBPIXEL_HINTING
 
 
   /**************************************************************************
@@ -977,22 +951,15 @@
 
 
   /*
-   * The next three macros are defined if native TrueType hinting is
+   * The next two macros are defined if native TrueType hinting is
    * requested by the definitions above.  Don't change this.
    */
 #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
 #define  TT_USE_BYTECODE_INTERPRETER
-
 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-#if TT_CONFIG_OPTION_SUBPIXEL_HINTING & 1
-#define  TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-#endif
-
-#if TT_CONFIG_OPTION_SUBPIXEL_HINTING & 2
 #define  TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
 #endif
 #endif
-#endif
 
 
   /*
diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/config/ftstdlib.h b/src/java.desktop/share/native/libfreetype/include/freetype/config/ftstdlib.h
index 3c9d2ae..f65148a 100644
--- a/src/java.desktop/share/native/libfreetype/include/freetype/config/ftstdlib.h
+++ b/src/java.desktop/share/native/libfreetype/include/freetype/config/ftstdlib.h
@@ -111,13 +111,13 @@
 
 #include <stdio.h>
 
-#define FT_FILE     FILE
-#define ft_fclose   fclose
-#define ft_fopen    fopen
-#define ft_fread    fread
-#define ft_fseek    fseek
-#define ft_ftell    ftell
-#define ft_sprintf  sprintf
+#define FT_FILE      FILE
+#define ft_fclose    fclose
+#define ft_fopen     fopen
+#define ft_fread     fread
+#define ft_fseek     fseek
+#define ft_ftell     ftell
+#define ft_snprintf  snprintf
 
 
   /**************************************************************************
diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/freetype.h b/src/java.desktop/share/native/libfreetype/include/freetype/freetype.h
index efff74f..92acf37 100644
--- a/src/java.desktop/share/native/libfreetype/include/freetype/freetype.h
+++ b/src/java.desktop/share/native/libfreetype/include/freetype/freetype.h
@@ -102,61 +102,25 @@
    */
 
 
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /*                                                                       */
-  /*                        B A S I C   T Y P E S                          */
-  /*                                                                       */
-  /*************************************************************************/
-  /*************************************************************************/
-
-
   /**************************************************************************
    *
    * @section:
-   *   base_interface
+   *   font_testing_macros
    *
    * @title:
-   *   Base Interface
+   *   Font Testing Macros
    *
    * @abstract:
-   *   The FreeType~2 base font interface.
+   *   Macros to test various properties of fonts.
    *
    * @description:
-   *   This section describes the most important public high-level API
-   *   functions of FreeType~2.
+   *   Macros to test the most important font properties.
+   *
+   *   It is recommended to use these high-level macros instead of directly
+   *   testing the corresponding flags, which are scattered over various
+   *   structures.
    *
    * @order:
-   *   FT_Library
-   *   FT_Face
-   *   FT_Size
-   *   FT_GlyphSlot
-   *   FT_CharMap
-   *   FT_Encoding
-   *   FT_ENC_TAG
-   *
-   *   FT_FaceRec
-   *
-   *   FT_FACE_FLAG_SCALABLE
-   *   FT_FACE_FLAG_FIXED_SIZES
-   *   FT_FACE_FLAG_FIXED_WIDTH
-   *   FT_FACE_FLAG_HORIZONTAL
-   *   FT_FACE_FLAG_VERTICAL
-   *   FT_FACE_FLAG_COLOR
-   *   FT_FACE_FLAG_SFNT
-   *   FT_FACE_FLAG_CID_KEYED
-   *   FT_FACE_FLAG_TRICKY
-   *   FT_FACE_FLAG_KERNING
-   *   FT_FACE_FLAG_MULTIPLE_MASTERS
-   *   FT_FACE_FLAG_VARIATION
-   *   FT_FACE_FLAG_GLYPH_NAMES
-   *   FT_FACE_FLAG_EXTERNAL_STREAM
-   *   FT_FACE_FLAG_HINTER
-   *   FT_FACE_FLAG_SVG
-   *   FT_FACE_FLAG_SBIX
-   *   FT_FACE_FLAG_SBIX_OVERLAY
-   *
    *   FT_HAS_HORIZONTAL
    *   FT_HAS_VERTICAL
    *   FT_HAS_KERNING
@@ -176,21 +140,59 @@
    *   FT_IS_NAMED_INSTANCE
    *   FT_IS_VARIATION
    *
-   *   FT_STYLE_FLAG_BOLD
-   *   FT_STYLE_FLAG_ITALIC
+   */
+
+
+  /**************************************************************************
    *
-   *   FT_SizeRec
-   *   FT_Size_Metrics
+   * @section:
+   *   library_setup
    *
-   *   FT_GlyphSlotRec
-   *   FT_Glyph_Metrics
-   *   FT_SubGlyph
+   * @title:
+   *   Library Setup
    *
-   *   FT_Bitmap_Size
+   * @abstract:
+   *   Functions to start and end the usage of the FreeType library.
    *
+   * @description:
+   *   Functions to start and end the usage of the FreeType library.
+   *
+   *   Note that @FT_Library_Version and @FREETYPE_XXX are of limited use
+   *   because even a new release of FreeType with only documentation
+   *   changes increases the version number.
+   *
+   * @order:
+   *   FT_Library
    *   FT_Init_FreeType
    *   FT_Done_FreeType
    *
+   *   FT_Library_Version
+   *   FREETYPE_XXX
+   *
+   */
+
+
+  /**************************************************************************
+   *
+   * @section:
+   *   face_creation
+   *
+   * @title:
+   *   Face Creation
+   *
+   * @abstract:
+   *   Functions to manage fonts.
+   *
+   * @description:
+   *   The functions and structures collected in this section operate on
+   *   fonts globally.
+   *
+   * @order:
+   *   FT_Face
+   *   FT_FaceRec
+   *   FT_FACE_FLAG_XXX
+   *   FT_STYLE_FLAG_XXX
+   *
    *   FT_New_Face
    *   FT_Done_Face
    *   FT_Reference_Face
@@ -198,10 +200,36 @@
    *   FT_Face_Properties
    *   FT_Open_Face
    *   FT_Open_Args
+   *   FT_OPEN_XXX
    *   FT_Parameter
    *   FT_Attach_File
    *   FT_Attach_Stream
    *
+   */
+
+
+  /**************************************************************************
+   *
+   * @section:
+   *   sizing_and_scaling
+   *
+   * @title:
+   *   Sizing and Scaling
+   *
+   * @abstract:
+   *   Functions to manage font sizes.
+   *
+   * @description:
+   *   The functions and structures collected in this section are related to
+   *   selecting and manipulating the size of a font globally.
+   *
+   * @order:
+   *   FT_Size
+   *   FT_SizeRec
+   *   FT_Size_Metrics
+   *
+   *   FT_Bitmap_Size
+   *
    *   FT_Set_Char_Size
    *   FT_Set_Pixel_Sizes
    *   FT_Request_Size
@@ -209,44 +237,37 @@
    *   FT_Size_Request_Type
    *   FT_Size_RequestRec
    *   FT_Size_Request
+   *
    *   FT_Set_Transform
    *   FT_Get_Transform
+   *
+   */
+
+
+  /**************************************************************************
+   *
+   * @section:
+   *   glyph_retrieval
+   *
+   * @title:
+   *   Glyph Retrieval
+   *
+   * @abstract:
+   *   Functions to manage glyphs.
+   *
+   * @description:
+   *   The functions and structures collected in this section operate on
+   *   single glyphs, of which @FT_Load_Glyph is most important.
+   *
+   * @order:
+   *   FT_GlyphSlot
+   *   FT_GlyphSlotRec
+   *   FT_Glyph_Metrics
+   *
    *   FT_Load_Glyph
-   *   FT_Get_Char_Index
-   *   FT_Get_First_Char
-   *   FT_Get_Next_Char
-   *   FT_Load_Char
-   *
-   *   FT_OPEN_MEMORY
-   *   FT_OPEN_STREAM
-   *   FT_OPEN_PATHNAME
-   *   FT_OPEN_DRIVER
-   *   FT_OPEN_PARAMS
-   *
-   *   FT_LOAD_DEFAULT
-   *   FT_LOAD_RENDER
-   *   FT_LOAD_MONOCHROME
-   *   FT_LOAD_LINEAR_DESIGN
-   *   FT_LOAD_NO_SCALE
-   *   FT_LOAD_NO_HINTING
-   *   FT_LOAD_NO_BITMAP
-   *   FT_LOAD_SBITS_ONLY
-   *   FT_LOAD_NO_AUTOHINT
-   *   FT_LOAD_COLOR
-   *
-   *   FT_LOAD_VERTICAL_LAYOUT
-   *   FT_LOAD_IGNORE_TRANSFORM
-   *   FT_LOAD_FORCE_AUTOHINT
-   *   FT_LOAD_NO_RECURSE
-   *   FT_LOAD_PEDANTIC
-   *
-   *   FT_LOAD_TARGET_NORMAL
-   *   FT_LOAD_TARGET_LIGHT
-   *   FT_LOAD_TARGET_MONO
-   *   FT_LOAD_TARGET_LCD
-   *   FT_LOAD_TARGET_LCD_V
-   *
+   *   FT_LOAD_XXX
    *   FT_LOAD_TARGET_MODE
+   *   FT_LOAD_TARGET_XXX
    *
    *   FT_Render_Glyph
    *   FT_Render_Mode
@@ -254,34 +275,121 @@
    *   FT_Kerning_Mode
    *   FT_Get_Track_Kerning
    *
+   */
+
+
+  /**************************************************************************
+   *
+   * @section:
+   *   character_mapping
+   *
+   * @title:
+   *   Character Mapping
+   *
+   * @abstract:
+   *   Functions to manage character-to-glyph maps.
+   *
+   * @description:
+   *   This section holds functions and structures that are related to
+   *   mapping character input codes to glyph indices.
+   *
+   *   Note that for many scripts the simplistic approach used by FreeType
+   *   of mapping a single character to a single glyph is not valid or
+   *   possible!  In general, a higher-level library like HarfBuzz or ICU
+   *   should be used for handling text strings.
+   *
+   * @order:
+   *   FT_CharMap
    *   FT_CharMapRec
+   *   FT_Encoding
+   *   FT_ENC_TAG
+   *
    *   FT_Select_Charmap
    *   FT_Set_Charmap
    *   FT_Get_Charmap_Index
    *
+   *   FT_Get_Char_Index
+   *   FT_Get_First_Char
+   *   FT_Get_Next_Char
+   *   FT_Load_Char
+   *
+   */
+
+
+  /**************************************************************************
+   *
+   * @section:
+   *   information_retrieval
+   *
+   * @title:
+   *   Information Retrieval
+   *
+   * @abstract:
+   *   Functions to retrieve font and glyph information.
+   *
+   * @description:
+   *   Functions to retrieve font and glyph information.  Only some very
+   *   basic data is covered; see also the chapter on the format-specific
+   *   API for more.
+   *
+   *
+   * @order:
    *   FT_Get_Name_Index
    *   FT_Get_Glyph_Name
    *   FT_Get_Postscript_Name
    *   FT_Get_FSType_Flags
+   *   FT_FSTYPE_XXX
    *   FT_Get_SubGlyph_Info
+   *   FT_SUBGLYPH_FLAG_XXX
    *
+   */
+
+
+  /**************************************************************************
+   *
+   * @section:
+   *   other_api_data
+   *
+   * @title:
+   *   Other API Data
+   *
+   * @abstract:
+   *   Other structures, enumerations, and macros.
+   *
+   * @description:
+   *   Other structures, enumerations, and macros.  Deprecated functions are
+   *   also listed here.
+   *
+   * @order:
    *   FT_Face_Internal
    *   FT_Size_Internal
    *   FT_Slot_Internal
    *
-   *   FT_FACE_FLAG_XXX
-   *   FT_STYLE_FLAG_XXX
-   *   FT_OPEN_XXX
-   *   FT_LOAD_XXX
-   *   FT_LOAD_TARGET_XXX
-   *   FT_SUBGLYPH_FLAG_XXX
-   *   FT_FSTYPE_XXX
+   *   FT_SubGlyph
    *
    *   FT_HAS_FAST_GLYPHS
+   *   FT_Face_CheckTrueTypePatents
+   *   FT_Face_SetUnpatentedHinting
    *
    */
 
 
+  /*************************************************************************/
+  /*************************************************************************/
+  /*                                                                       */
+  /*                        B A S I C   T Y P E S                          */
+  /*                                                                       */
+  /*************************************************************************/
+  /*************************************************************************/
+
+
+  /**************************************************************************
+   *
+   * @section:
+   *   glyph_retrieval
+   *
+   */
+
   /**************************************************************************
    *
    * @struct:
@@ -351,6 +459,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   sizing_and_scaling
+   *
+   */
+
+  /**************************************************************************
+   *
    * @struct:
    *   FT_Bitmap_Size
    *
@@ -411,6 +526,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   library_setup
+   *
+   */
+
+  /**************************************************************************
+   *
    * @type:
    *   FT_Library
    *
@@ -483,7 +605,7 @@
   /**************************************************************************
    *
    * @section:
-   *   base_interface
+   *   face_creation
    *
    */
 
@@ -521,6 +643,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   sizing_and_scaling
+   *
+   */
+
+  /**************************************************************************
+   *
    * @type:
    *   FT_Size
    *
@@ -553,6 +682,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   glyph_retrieval
+   *
+   */
+
+  /**************************************************************************
+   *
    * @type:
    *   FT_GlyphSlot
    *
@@ -572,6 +708,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   character_mapping
+   *
+   */
+
+  /**************************************************************************
+   *
    * @type:
    *   FT_CharMap
    *
@@ -879,6 +1022,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   other_api_data
+   *
+   */
+
+  /**************************************************************************
+   *
    * @type:
    *   FT_Face_Internal
    *
@@ -894,6 +1044,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   face_creation
+   *
+   */
+
+  /**************************************************************************
+   *
    * @struct:
    *   FT_FaceRec
    *
@@ -918,7 +1075,7 @@
    *     If we have the third named instance of face~4, say, `face_index` is
    *     set to 0x00030004.
    *
-   *     Bit 31 is always zero (this is, `face_index` is always a positive
+   *     Bit 31 is always zero (that is, `face_index` is always a positive
    *     value).
    *
    *     [Since 2.9] Changing the design coordinates with
@@ -936,7 +1093,7 @@
    *
    *     [Since 2.6.1] Bits 16-30 hold the number of named instances
    *     available for the current face if we have a GX or OpenType variation
-   *     (sub)font.  Bit 31 is always zero (this is, `style_flags` is always
+   *     (sub)font.  Bit 31 is always zero (that is, `style_flags` is always
    *     a positive value).  Note that a variation font has always at least
    *     one named instance, namely the default instance.
    *
@@ -1002,7 +1159,7 @@
    *     Note that the bounding box might be off by (at least) one pixel for
    *     hinted fonts.  See @FT_Size_Metrics for further discussion.
    *
-   *     Note that the bounding box does not vary in OpenType variable fonts
+   *     Note that the bounding box does not vary in OpenType variation fonts
    *     and should only be used in relation to the default instance.
    *
    *   units_per_EM ::
@@ -1090,9 +1247,9 @@
 
     FT_Generic        generic;
 
-    /*# The following member variables (down to `underline_thickness`) */
-    /*# are only relevant to scalable outlines; cf. @FT_Bitmap_Size    */
-    /*# for bitmap fonts.                                              */
+    /* The following member variables (down to `underline_thickness`) */
+    /* are only relevant to scalable outlines; cf. @FT_Bitmap_Size    */
+    /* for bitmap fonts.                                              */
     FT_BBox           bbox;
 
     FT_UShort         units_per_EM;
@@ -1110,7 +1267,7 @@
     FT_Size           size;
     FT_CharMap        charmap;
 
-    /*@private begin */
+    /* private fields, internal to FreeType */
 
     FT_Driver         driver;
     FT_Memory         memory;
@@ -1123,8 +1280,6 @@
 
     FT_Face_Internal  internal;
 
-    /*@private end */
-
   } FT_FaceRec;
 
 
@@ -1207,13 +1362,13 @@
    *     successfully; in all other cases you get an
    *     `FT_Err_Invalid_Argument` error.
    *
-   *     Note that CID-keyed fonts that are in an SFNT wrapper (this is, all
+   *     Note that CID-keyed fonts that are in an SFNT wrapper (that is, all
    *     OpenType/CFF fonts) don't have this flag set since the glyphs are
    *     accessed in the normal way (using contiguous indices); the
    *     'CID-ness' isn't visible to the application.
    *
    *   FT_FACE_FLAG_TRICKY ::
-   *     The face is 'tricky', this is, it always needs the font format's
+   *     The face is 'tricky', that is, it always needs the font format's
    *     native hinting engine to get a reasonable result.  A typical example
    *     is the old Chinese font `mingli.ttf` (but not `mingliu.ttc`) that
    *     uses TrueType bytecode instructions to move and scale all of its
@@ -1235,8 +1390,8 @@
    *   FT_FACE_FLAG_VARIATION ::
    *     [Since 2.9] Set if the current face (or named instance) has been
    *     altered with @FT_Set_MM_Design_Coordinates,
-   *     @FT_Set_Var_Design_Coordinates, or @FT_Set_Var_Blend_Coordinates.
-   *     This flag is unset by a call to @FT_Set_Named_Instance.
+   *     @FT_Set_Var_Design_Coordinates, @FT_Set_Var_Blend_Coordinates, or
+   *     @FT_Set_MM_WeightVector to select a non-default instance.
    *
    *   FT_FACE_FLAG_SVG ::
    *     [Since 2.12] The face has an 'SVG~' OpenType table.
@@ -1274,6 +1429,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   font_testing_macros
+   *
+   */
+
+  /**************************************************************************
+   *
    * @macro:
    *   FT_HAS_HORIZONTAL
    *
@@ -1383,6 +1545,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   other_api_data
+   *
+   */
+
+  /**************************************************************************
+   *
    * @macro:
    *   FT_HAS_FAST_GLYPHS
    *
@@ -1395,6 +1564,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   font_testing_macros
+   *
+   */
+
+  /**************************************************************************
+   *
    * @macro:
    *   FT_HAS_GLYPH_NAMES
    *
@@ -1451,8 +1627,8 @@
    *
    * @description:
    *   A macro that returns true whenever a face object has been altered by
-   *   @FT_Set_MM_Design_Coordinates, @FT_Set_Var_Design_Coordinates, or
-   *   @FT_Set_Var_Blend_Coordinates.
+   *   @FT_Set_MM_Design_Coordinates, @FT_Set_Var_Design_Coordinates,
+   *   @FT_Set_Var_Blend_Coordinates, or @FT_Set_MM_WeightVector.
    *
    * @since:
    *   2.9
@@ -1630,6 +1806,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   face_creation
+   *
+   */
+
+  /**************************************************************************
+   *
    * @enum:
    *   FT_STYLE_FLAG_XXX
    *
@@ -1656,6 +1839,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   other_api_data
+   *
+   */
+
+  /**************************************************************************
+   *
    * @type:
    *   FT_Size_Internal
    *
@@ -1668,6 +1858,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   sizing_and_scaling
+   *
+   */
+
+  /**************************************************************************
+   *
    * @struct:
    *   FT_Size_Metrics
    *
@@ -1819,6 +2016,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   other_api_data
+   *
+   */
+
+  /**************************************************************************
+   *
    * @struct:
    *   FT_SubGlyph
    *
@@ -1850,6 +2054,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   glyph_retrieval
+   *
+   */
+
+  /**************************************************************************
+   *
    * @struct:
    *   FT_GlyphSlotRec
    *
@@ -2094,6 +2305,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   library_setup
+   *
+   */
+
+  /**************************************************************************
+   *
    * @function:
    *   FT_Init_FreeType
    *
@@ -2151,6 +2369,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   face_creation
+   *
+   */
+
+  /**************************************************************************
+   *
    * @enum:
    *   FT_OPEN_XXX
    *
@@ -2451,7 +2676,7 @@
    *   Each new face object created with this function also owns a default
    *   @FT_Size object, accessible as `face->size`.
    *
-   *   One @FT_Library instance can have multiple face objects, this is,
+   *   One @FT_Library instance can have multiple face objects, that is,
    *   @FT_Open_Face and its siblings can be called multiple times using the
    *   same `library` argument.
    *
@@ -2652,6 +2877,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   sizing_and_scaling
+   *
+   */
+
+  /**************************************************************************
+   *
    * @function:
    *   FT_Select_Size
    *
@@ -2679,7 +2911,7 @@
    *   silently uses outlines if there is no bitmap for a given glyph index.
    *
    *   For GX and OpenType variation fonts, a bitmap strike makes sense only
-   *   if the default instance is active (this is, no glyph variation takes
+   *   if the default instance is active (that is, no glyph variation takes
    *   place); otherwise, FreeType simply ignores bitmap strikes.  The same
    *   is true for all named instances that are different from the default
    *   instance.
@@ -2944,6 +3176,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   glyph_retrieval
+   *
+   */
+
+  /**************************************************************************
+   *
    * @function:
    *   FT_Load_Glyph
    *
@@ -2976,7 +3215,7 @@
    *   glyph may be transformed.  See @FT_Set_Transform for the details.
    *
    *   For subsetted CID-keyed fonts, `FT_Err_Invalid_Argument` is returned
-   *   for invalid CID values (this is, for CID values that don't have a
+   *   for invalid CID values (that is, for CID values that don't have a
    *   corresponding glyph in the font).  See the discussion of the
    *   @FT_FACE_FLAG_CID_KEYED flag for more details.
    *
@@ -2992,6 +3231,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   character_mapping
+   *
+   */
+
+  /**************************************************************************
+   *
    * @function:
    *   FT_Load_Char
    *
@@ -3035,6 +3281,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   glyph_retrieval
+   *
+   */
+
+  /**************************************************************************
+   *
    * @enum:
    *   FT_LOAD_XXX
    *
@@ -3172,10 +3425,11 @@
    *
    *     [Since 2.12] If the glyph index maps to an entry in the face's
    *     'SVG~' table, load the associated SVG document from this table and
-   *     set the `format` field of @FT_GlyphSlotRec to @FT_GLYPH_FORMAT_SVG.
-   *     Note that FreeType itself can't render SVG documents; however, the
-   *     library provides hooks to seamlessly integrate an external renderer.
-   *     See sections @ot_svg_driver and @svg_fonts for more.
+   *     set the `format` field of @FT_GlyphSlotRec to @FT_GLYPH_FORMAT_SVG
+   *     ([since 2.13.1] provided @FT_LOAD_NO_SVG is not set).  Note that
+   *     FreeType itself can't render SVG documents; however, the library
+   *     provides hooks to seamlessly integrate an external renderer.  See
+   *     sections @ot_svg_driver and @svg_fonts for more.
    *
    *     [Since 2.10, experimental] If the glyph index maps to an entry in
    *     the face's 'COLR' table with a 'CPAL' palette table (as defined in
@@ -3189,6 +3443,9 @@
    *     @FT_Palette_Select instead of setting @FT_LOAD_COLOR for rendering
    *     so that the client application can handle blending by itself.
    *
+   *   FT_LOAD_NO_SVG ::
+   *     [Since 2.13.1] Ignore SVG glyph data when loading.
+   *
    *   FT_LOAD_COMPUTE_METRICS ::
    *     [Since 2.6.1] Compute glyph metrics from the glyph data, without the
    *     use of bundled metrics tables (for example, the 'hdmx' table in
@@ -3254,6 +3511,7 @@
 #define FT_LOAD_COLOR                        ( 1L << 20 )
 #define FT_LOAD_COMPUTE_METRICS              ( 1L << 21 )
 #define FT_LOAD_BITMAP_METRICS_ONLY          ( 1L << 22 )
+#define FT_LOAD_NO_SVG                       ( 1L << 24 )
 
   /* */
 
@@ -3374,6 +3632,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   sizing_and_scaling
+   *
+   */
+
+  /**************************************************************************
+   *
    * @function:
    *   FT_Set_Transform
    *
@@ -3449,6 +3714,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   glyph_retrieval
+   *
+   */
+
+  /**************************************************************************
+   *
    * @enum:
    *   FT_Render_Mode
    *
@@ -3843,6 +4115,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   character_mapping
+   *
+   */
+
+  /**************************************************************************
+   *
    * @function:
    *   FT_Select_Charmap
    *
@@ -4059,6 +4338,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   face_creation
+   *
+   */
+
+  /**************************************************************************
+   *
    * @function:
    *   FT_Face_Properties
    *
@@ -4157,6 +4443,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   information_retrieval
+   *
+   */
+
+  /**************************************************************************
+   *
    * @function:
    *   FT_Get_Name_Index
    *
@@ -4266,9 +4559,10 @@
    *
    *   [Since 2.9] Special PostScript names for named instances are only
    *   returned if the named instance is set with @FT_Set_Named_Instance (and
-   *   the font has corresponding entries in its 'fvar' table).  If
-   *   @FT_IS_VARIATION returns true, the algorithmically derived PostScript
-   *   name is provided, not looking up special entries for named instances.
+   *   the font has corresponding entries in its 'fvar' table or is the
+   *   default named instance).  If @FT_IS_VARIATION returns true, the
+   *   algorithmically derived PostScript name is provided, not looking up
+   *   special entries for named instances.
    */
   FT_EXPORT( const char* )
   FT_Get_Postscript_Name( FT_Face  face );
@@ -4900,32 +5194,10 @@
   /**************************************************************************
    *
    * @section:
-   *   version
-   *
-   * @title:
-   *   FreeType Version
-   *
-   * @abstract:
-   *   Functions and macros related to FreeType versions.
-   *
-   * @description:
-   *   Note that those functions and macros are of limited use because even a
-   *   new release of FreeType with only documentation changes increases the
-   *   version number.
-   *
-   * @order:
-   *   FT_Library_Version
-   *
-   *   FREETYPE_MAJOR
-   *   FREETYPE_MINOR
-   *   FREETYPE_PATCH
-   *
-   *   FT_Face_CheckTrueTypePatents
-   *   FT_Face_SetUnpatentedHinting
+   *   library_setup
    *
    */
 
-
   /**************************************************************************
    *
    * @enum:
@@ -4950,7 +5222,7 @@
    */
 #define FREETYPE_MAJOR  2
 #define FREETYPE_MINOR  13
-#define FREETYPE_PATCH  0
+#define FREETYPE_PATCH  2
 
 
   /**************************************************************************
@@ -4994,6 +5266,13 @@
 
   /**************************************************************************
    *
+   * @section:
+   *   other_api_data
+   *
+   */
+
+  /**************************************************************************
+   *
    * @function:
    *   FT_Face_CheckTrueTypePatents
    *
diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/ftchapters.h b/src/java.desktop/share/native/libfreetype/include/freetype/ftchapters.h
index 6a9733a..7566fbd 100644
--- a/src/java.desktop/share/native/libfreetype/include/freetype/ftchapters.h
+++ b/src/java.desktop/share/native/libfreetype/include/freetype/ftchapters.h
@@ -31,9 +31,28 @@
    *   Core API
    *
    * @sections:
-   *   version
    *   basic_types
-   *   base_interface
+   *   library_setup
+   *   face_creation
+   *   font_testing_macros
+   *   sizing_and_scaling
+   *   glyph_retrieval
+   *   character_mapping
+   *   information_retrieval
+   *   other_api_data
+   *
+   */
+
+
+  /**************************************************************************
+   *
+   * @chapter:
+   *   extended_api
+   *
+   * @title:
+   *   Extended API
+   *
+   * @sections:
    *   glyph_variants
    *   color_management
    *   layer_management
diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/ftdriver.h b/src/java.desktop/share/native/libfreetype/include/freetype/ftdriver.h
index f90946f..7af7465 100644
--- a/src/java.desktop/share/native/libfreetype/include/freetype/ftdriver.h
+++ b/src/java.desktop/share/native/libfreetype/include/freetype/ftdriver.h
@@ -134,7 +134,7 @@
    *   each being rounded to the nearest pixel edge, taking care of overshoot
    *   suppression at small sizes, stem darkening, and scaling.
    *
-   *   Hstems (this is, hint values defined in the font to help align
+   *   Hstems (that is, hint values defined in the font to help align
    *   horizontal features) that fall within a blue zone are said to be
    *   'captured' and are aligned to that zone.  Uncaptured stems are moved
    *   in one of four ways, top edge up or down, bottom edge up or down.
@@ -446,7 +446,7 @@
    *   at smaller sizes.
    *
    *   For the auto-hinter, stem-darkening is experimental currently and thus
-   *   switched off by default (this is, `no-stem-darkening` is set to TRUE
+   *   switched off by default (that is, `no-stem-darkening` is set to TRUE
    *   by default).  Total consistency with the CFF driver is not achieved
    *   right now because the emboldening method differs and glyphs must be
    *   scaled down on the Y-axis to keep outline points inside their
@@ -651,11 +651,8 @@
    *     Windows~98; only grayscale and B/W rasterizing is supported.
    *
    *   TT_INTERPRETER_VERSION_38 ::
-   *     Version~38 corresponds to MS rasterizer v.1.9; it is roughly
-   *     equivalent to the hinting provided by DirectWrite ClearType (as can
-   *     be found, for example, in the Internet Explorer~9 running on
-   *     Windows~7).  It is used in FreeType to select the 'Infinality'
-   *     subpixel hinting code.  The code may be removed in a future version.
+   *     Version~38 is the same Version~40. The original 'Infinality' code is
+   *     no longer available.
    *
    *   TT_INTERPRETER_VERSION_40 ::
    *     Version~40 corresponds to MS rasterizer v.2.1; it is roughly
diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/ftimage.h b/src/java.desktop/share/native/libfreetype/include/freetype/ftimage.h
index 2e8e673..6baa812 100644
--- a/src/java.desktop/share/native/libfreetype/include/freetype/ftimage.h
+++ b/src/java.desktop/share/native/libfreetype/include/freetype/ftimage.h
@@ -19,7 +19,7 @@
   /**************************************************************************
    *
    * Note: A 'raster' is simply a scan-line converter, used to render
-   *       FT_Outlines into FT_Bitmaps.
+   *       `FT_Outline`s into `FT_Bitmap`s.
    *
    */
 
@@ -256,6 +256,12 @@
    *   palette ::
    *     A typeless pointer to the bitmap palette; this field is intended for
    *     paletted pixel modes.  Not used currently.
+   *
+   * @note:
+   *   `width` and `rows` refer to the *physical* size of the bitmap, not the
+   *   *logical* one.  For example, if @FT_Pixel_Mode is set to
+   *   `FT_PIXEL_MODE_LCD`, the logical width is a just a third of the
+   *   physical one.
    */
   typedef struct  FT_Bitmap_
   {
@@ -856,7 +862,7 @@
    *   @FT_SpanFunc that takes the y~coordinate of the span as a parameter.
    *
    *   The anti-aliased rasterizer produces coverage values from 0 to 255,
-   *   this is, from completely transparent to completely opaque.
+   *   that is, from completely transparent to completely opaque.
    */
   typedef struct  FT_Span_
   {
diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/ftlogging.h b/src/java.desktop/share/native/libfreetype/include/freetype/ftlogging.h
index 2246dc8..53b8b89 100644
--- a/src/java.desktop/share/native/libfreetype/include/freetype/ftlogging.h
+++ b/src/java.desktop/share/native/libfreetype/include/freetype/ftlogging.h
@@ -62,7 +62,7 @@
    *   component.
    *
    *   ```
-   *   FT_Trace_Set_Level( "any:7 memory:0 );
+   *   FT_Trace_Set_Level( "any:7 memory:0" );
    *   ```
    *
    * @note:
diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/ftmm.h b/src/java.desktop/share/native/libfreetype/include/freetype/ftmm.h
index e381ef3..d145128 100644
--- a/src/java.desktop/share/native/libfreetype/include/freetype/ftmm.h
+++ b/src/java.desktop/share/native/libfreetype/include/freetype/ftmm.h
@@ -153,7 +153,7 @@
    * @note:
    *   The fields `minimum`, `def`, and `maximum` are 16.16 fractional values
    *   for TrueType GX and OpenType variation fonts.  For Adobe MM fonts, the
-   *   values are integers.
+   *   values are whole numbers (i.e., the fractional part is zero).
    */
   typedef struct  FT_Var_Axis_
   {
@@ -399,8 +399,8 @@
    *
    * @note:
    *   The design coordinates are 16.16 fractional values for TrueType GX and
-   *   OpenType variation fonts.  For Adobe MM fonts, the values are
-   *   integers.
+   *   OpenType variation fonts.  For Adobe MM fonts, the values are supposed
+   *   to be whole numbers (i.e., the fractional part is zero).
    *
    *   [Since 2.8.1] To reset all axes to the default values, call the
    *   function with `num_coords` set to zero and `coords` set to `NULL`.
@@ -446,8 +446,8 @@
    *
    * @note:
    *   The design coordinates are 16.16 fractional values for TrueType GX and
-   *   OpenType variation fonts.  For Adobe MM fonts, the values are
-   *   integers.
+   *   OpenType variation fonts.  For Adobe MM fonts, the values are whole
+   *   numbers (i.e., the fractional part is zero).
    *
    * @since:
    *   2.7.1
@@ -602,10 +602,12 @@
    *
    * @note:
    *   Adobe Multiple Master fonts limit the number of designs, and thus the
-   *   length of the weight vector to~16.
+   *   length of the weight vector to 16~elements.
    *
-   *   If `len` is zero and `weightvector` is `NULL`, the weight vector array
-   *   is reset to the default values.
+   *   If `len` is larger than zero, this function sets the
+   *   @FT_FACE_FLAG_VARIATION bit in @FT_Face's `face_flags` field (i.e.,
+   *   @FT_IS_VARIATION will return true).  If `len` is zero, this bit flag
+   *   is unset and the weight vector array is reset to the default values.
    *
    *   The Adobe documentation also states that the values in the
    *   WeightVector array must total 1.0 +/-~0.001.  In practice this does
@@ -753,6 +755,45 @@
   FT_Set_Named_Instance( FT_Face  face,
                          FT_UInt  instance_index );
 
+
+  /**************************************************************************
+   *
+   * @function:
+   *   FT_Get_Default_Named_Instance
+   *
+   * @description:
+   *   Retrieve the index of the default named instance, to be used with
+   *   @FT_Set_Named_Instance.
+   *
+   *   The default instance of a variation font is that instance for which
+   *   the nth axis coordinate is equal to `axis[n].def` (as specified in the
+   *   @FT_MM_Var structure), with~n covering all axes.
+   *
+   *   FreeType synthesizes a named instance for the default instance if the
+   *   font does not contain such an entry.
+   *
+   * @input:
+   *   face ::
+   *     A handle to the source face.
+   *
+   * @output:
+   *   instance_index ::
+   *     The index of the default named instance.
+   *
+   * @return:
+   *   FreeType error code.  0~means success.
+   *
+   * @note:
+   *   For Adobe MM fonts (which don't have named instances) this function
+   *   always returns zero for `instance_index`.
+   *
+   * @since:
+   *   2.13.1
+   */
+  FT_EXPORT( FT_Error )
+  FT_Get_Default_Named_Instance( FT_Face   face,
+                                 FT_UInt  *instance_index );
+
   /* */
 
 
diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/ftoutln.h b/src/java.desktop/share/native/libfreetype/include/freetype/ftoutln.h
index 54434b2..f9329ca 100644
--- a/src/java.desktop/share/native/libfreetype/include/freetype/ftoutln.h
+++ b/src/java.desktop/share/native/libfreetype/include/freetype/ftoutln.h
@@ -118,7 +118,7 @@
    *   attachement.
    *
    *   Similarly, the function returns success for an empty outline also
-   *   (doing nothing, this is, not calling any emitter); if necessary, you
+   *   (doing nothing, that is, not calling any emitter); if necessary, you
    *   should filter this out, too.
    */
   FT_EXPORT( FT_Error )
diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/ftrender.h b/src/java.desktop/share/native/libfreetype/include/freetype/ftrender.h
index a8576da..0b6fad3 100644
--- a/src/java.desktop/share/native/libfreetype/include/freetype/ftrender.h
+++ b/src/java.desktop/share/native/libfreetype/include/freetype/ftrender.h
@@ -158,7 +158,7 @@
     FT_Renderer_GetCBoxFunc    get_glyph_cbox;
     FT_Renderer_SetModeFunc    set_mode;
 
-    FT_Raster_Funcs*           raster_class;
+    const FT_Raster_Funcs*     raster_class;
 
   } FT_Renderer_Class;
 
diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/ftsynth.h b/src/java.desktop/share/native/libfreetype/include/freetype/ftsynth.h
index 5d19697..af90967 100644
--- a/src/java.desktop/share/native/libfreetype/include/freetype/ftsynth.h
+++ b/src/java.desktop/share/native/libfreetype/include/freetype/ftsynth.h
@@ -68,6 +68,18 @@
   FT_EXPORT( void )
   FT_GlyphSlot_Embolden( FT_GlyphSlot  slot );
 
+  /* Precisely adjust the glyph weight either horizontally or vertically.  */
+  /* The `xdelta` and `ydelta` values are fractions of the face Em size    */
+  /* (in fixed-point format).  Considering that a regular face would have  */
+  /* stem widths on the order of 0.1 Em, a delta of 0.05 (0x0CCC) should   */
+  /* be very noticeable.  To increase or decrease the weight, use positive */
+  /* or negative values, respectively.                                     */
+  FT_EXPORT( void )
+  FT_GlyphSlot_AdjustWeight( FT_GlyphSlot  slot,
+                             FT_Fixed      xdelta,
+                             FT_Fixed      ydelta );
+
+
   /* Slant an outline glyph to the right by about 12 degrees.              */
   FT_EXPORT( void )
   FT_GlyphSlot_Oblique( FT_GlyphSlot  slot );
diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/ftsystem.h b/src/java.desktop/share/native/libfreetype/include/freetype/ftsystem.h
index a995b07..3a08f49 100644
--- a/src/java.desktop/share/native/libfreetype/include/freetype/ftsystem.h
+++ b/src/java.desktop/share/native/libfreetype/include/freetype/ftsystem.h
@@ -229,8 +229,7 @@
    *     A handle to the source stream.
    *
    *   offset ::
-   *     The offset from the start of the stream to seek to if this is a seek
-   *     operation (see note).
+   *     The offset from the start of the stream to seek to.
    *
    *   buffer ::
    *     The address of the read buffer.
@@ -239,16 +238,9 @@
    *     The number of bytes to read from the stream.
    *
    * @return:
-   *   The number of bytes effectively read by the stream.
-   *
-   * @note:
-   *   This function performs a seek *or* a read operation depending on the
-   *   argument values.  If `count` is zero, the operation is a seek to
-   *   `offset` bytes.  If `count` is >~0, the operation is a read of `count`
-   *   bytes from the current position in the stream, and the `offset` value
-   *   should be ignored.
-   *
-   *   For seek operations, a non-zero return value indicates an error.
+   *   If count >~0, return the number of bytes effectively read by the
+   *   stream (after seeking to `offset`).  If count ==~0, return the status
+   *   of the seek operation (non-zero indicates an error).
    *
    */
   typedef unsigned long
diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/compiler-macros.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/compiler-macros.h
index 7883317..6f67650 100644
--- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/compiler-macros.h
+++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/compiler-macros.h
@@ -41,8 +41,11 @@
 #  if ( defined( __STDC_VERSION__ ) && __STDC_VERSION__ > 201710L ) || \
       ( defined( __cplusplus ) && __cplusplus > 201402L )
 #    define FALL_THROUGH  [[__fallthrough__]]
-#  elif ( defined( __GNUC__ ) && __GNUC__ >= 7 )          || \
-        ( defined( __clang__ ) && __clang_major__ >= 10 )
+#  elif ( defined( __GNUC__ ) && __GNUC__ >= 7 )       || \
+        ( defined( __clang__ )                      &&    \
+          ( defined( __apple_build_version__ )            \
+              ? __apple_build_version__ >= 12000000       \
+              : __clang_major__ >= 10 ) )
 #    define FALL_THROUGH  __attribute__(( __fallthrough__ ))
 #  else
 #    define FALL_THROUGH  ( (void)0 )
diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftcalc.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftcalc.h
index d1baa39..d9aea23 100644
--- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftcalc.h
+++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftcalc.h
@@ -332,9 +332,9 @@
    * Based on geometric considerations we use the following inequality to
    * identify a degenerate matrix.
    *
-   *   50 * abs(xx*yy - xy*yx) < xx^2 + xy^2 + yx^2 + yy^2
+   *   32 * abs(xx*yy - xy*yx) < xx^2 + xy^2 + yx^2 + yy^2
    *
-   * Value 50 is heuristic.
+   * Value 32 is heuristic.
    */
   FT_BASE( FT_Bool )
   FT_Matrix_Check( const FT_Matrix*  matrix );
diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftdrv.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftdrv.h
index f78912c..9001c07 100644
--- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftdrv.h
+++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftdrv.h
@@ -157,6 +157,7 @@
    *     A handle to a function used to select a new fixed size.  It is used
    *     only if @FT_FACE_FLAG_FIXED_SIZES is set.  Can be set to 0 if the
    *     scaling done in the base layer suffices.
+   *
    * @note:
    *   Most function pointers, with the exception of `load_glyph`, can be set
    *   to 0 to indicate a default behaviour.
diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftmmtypes.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftmmtypes.h
index b7c66c3..c4b21d6 100644
--- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftmmtypes.h
+++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/ftmmtypes.h
@@ -28,13 +28,19 @@
 
   typedef struct  GX_ItemVarDataRec_
   {
-    FT_UInt            itemCount;       /* number of delta sets per item    */
-    FT_UInt            regionIdxCount;  /* number of region indices         */
-    FT_UInt*           regionIndices;   /* array of `regionCount' indices;  */
-                                        /* these index `varRegionList'      */
-    FT_ItemVarDelta*   deltaSet;        /* array of `itemCount' deltas      */
-                                        /* use `innerIndex' for this array  */
-
+    FT_UInt            itemCount;      /* Number of delta sets per item.   */
+    FT_UInt            regionIdxCount; /* Number of region indices.        */
+    FT_UInt*           regionIndices;  /* Array of `regionCount` indices;  */
+                                       /* these index `varRegionList`.     */
+    FT_Byte*           deltaSet;       /* Array of `itemCount` deltas;     */
+                                       /* use `innerIndex` for this array. */
+    FT_UShort          wordDeltaCount; /* Number of the first 32-bit ints  */
+                                       /* or 16-bit ints of `deltaSet`     */
+                                       /* depending on `longWords`.        */
+    FT_Bool            longWords;      /* If true, `deltaSet` is a 32-bit  */
+                                       /* array followed by a 16-bit       */
+                                       /* array, otherwise a 16-bit array  */
+                                       /* followed by an 8-bit array.      */
   } GX_ItemVarDataRec, *GX_ItemVarData;
 
 
diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svmetric.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svmetric.h
index e588ea4..167617e 100644
--- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svmetric.h
+++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svmetric.h
@@ -77,6 +77,9 @@
   typedef void
   (*FT_Metrics_Adjust_Func)( FT_Face  face );
 
+  typedef FT_Error
+  (*FT_Size_Reset_Func)( FT_Size  size );
+
 
   FT_DEFINE_SERVICE( MetricsVariations )
   {
@@ -90,6 +93,7 @@
     FT_VOrg_Adjust_Func      vorg_adjust;
 
     FT_Metrics_Adjust_Func   metrics_adjust;
+    FT_Size_Reset_Func       size_reset;
   };
 
 
@@ -101,7 +105,8 @@
                                                 tsb_adjust_,       \
                                                 bsb_adjust_,       \
                                                 vorg_adjust_,      \
-                                                metrics_adjust_  ) \
+                                                metrics_adjust_,   \
+                                                size_reset_      ) \
   static const FT_Service_MetricsVariationsRec  class_ =           \
   {                                                                \
     hadvance_adjust_,                                              \
@@ -111,7 +116,8 @@
     tsb_adjust_,                                                   \
     bsb_adjust_,                                                   \
     vorg_adjust_,                                                  \
-    metrics_adjust_                                                \
+    metrics_adjust_,                                               \
+    size_reset_                                                    \
   };
 
   /* */
diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svmm.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svmm.h
index d942042..7e76ab8 100644
--- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svmm.h
+++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svmm.h
@@ -60,9 +60,9 @@
   /* use return value -1 to indicate that the new coordinates  */
   /* are equal to the current ones; no changes are thus needed */
   typedef FT_Error
-  (*FT_Set_MM_Blend_Func)( FT_Face   face,
-                           FT_UInt   num_coords,
-                           FT_Long*  coords );
+  (*FT_Set_MM_Blend_Func)( FT_Face    face,
+                           FT_UInt    num_coords,
+                           FT_Fixed*  coords );
 
   typedef FT_Error
   (*FT_Get_Var_Design_Func)( FT_Face    face,
@@ -70,13 +70,17 @@
                              FT_Fixed*  coords );
 
   typedef FT_Error
-  (*FT_Set_Instance_Func)( FT_Face  face,
-                           FT_UInt  instance_index );
+  (*FT_Set_Named_Instance_Func)( FT_Face  face,
+                                 FT_UInt  instance_index );
 
   typedef FT_Error
-  (*FT_Get_MM_Blend_Func)( FT_Face   face,
-                           FT_UInt   num_coords,
-                           FT_Long*  coords );
+  (*FT_Get_Default_Named_Instance_Func)( FT_Face   face,
+                                         FT_UInt  *instance_index );
+
+  typedef FT_Error
+  (*FT_Get_MM_Blend_Func)( FT_Face    face,
+                           FT_UInt    num_coords,
+                           FT_Fixed*  coords );
 
   typedef FT_Error
   (*FT_Get_Var_Blend_Func)( FT_Face      face,
@@ -86,7 +90,7 @@
                             FT_MM_Var*  *mm_var );
 
   typedef void
-  (*FT_Done_Blend_Func)( FT_Face );
+  (*FT_Done_Blend_Func)( FT_Face  face );
 
   typedef FT_Error
   (*FT_Set_MM_WeightVector_Func)( FT_Face    face,
@@ -98,6 +102,9 @@
                                   FT_UInt*   len,
                                   FT_Fixed*  weight_vector );
 
+  typedef void
+  (*FT_Construct_PS_Name_Func)( FT_Face  face );
+
   typedef FT_Error
   (*FT_Var_Load_Delta_Set_Idx_Map_Func)( FT_Face            face,
                                          FT_ULong           offset,
@@ -134,11 +141,13 @@
     FT_Get_MM_Var_Func                    get_mm_var;
     FT_Set_Var_Design_Func                set_var_design;
     FT_Get_Var_Design_Func                get_var_design;
-    FT_Set_Instance_Func                  set_instance;
+    FT_Set_Named_Instance_Func            set_named_instance;
+    FT_Get_Default_Named_Instance_Func    get_default_named_instance;
     FT_Set_MM_WeightVector_Func           set_mm_weightvector;
     FT_Get_MM_WeightVector_Func           get_mm_weightvector;
 
     /* for internal use; only needed for code sharing between modules */
+    FT_Construct_PS_Name_Func             construct_ps_name;
     FT_Var_Load_Delta_Set_Idx_Map_Func    load_delta_set_idx_map;
     FT_Var_Load_Item_Var_Store_Func       load_item_var_store;
     FT_Var_Get_Item_Delta_Func            get_item_delta;
@@ -149,43 +158,49 @@
   };
 
 
-#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_,                  \
-                                           get_mm_,                 \
-                                           set_mm_design_,          \
-                                           set_mm_blend_,           \
-                                           get_mm_blend_,           \
-                                           get_mm_var_,             \
-                                           set_var_design_,         \
-                                           get_var_design_,         \
-                                           set_instance_,           \
-                                           set_weightvector_,       \
-                                           get_weightvector_,       \
-                                           load_delta_set_idx_map_, \
-                                           load_item_var_store_,    \
-                                           get_item_delta_,         \
-                                           done_item_var_store_,    \
-                                           done_delta_set_idx_map_, \
-                                           get_var_blend_,          \
-                                           done_blend_ )            \
-  static const FT_Service_MultiMastersRec  class_ =                 \
-  {                                                                 \
-    get_mm_,                                                        \
-    set_mm_design_,                                                 \
-    set_mm_blend_,                                                  \
-    get_mm_blend_,                                                  \
-    get_mm_var_,                                                    \
-    set_var_design_,                                                \
-    get_var_design_,                                                \
-    set_instance_,                                                  \
-    set_weightvector_,                                              \
-    get_weightvector_,                                              \
-    load_delta_set_idx_map_,                                        \
-    load_item_var_store_,                                           \
-    get_item_delta_,                                                \
-    done_item_var_store_,                                           \
-    done_delta_set_idx_map_,                                        \
-    get_var_blend_,                                                 \
-    done_blend_                                                     \
+#define FT_DEFINE_SERVICE_MULTIMASTERSREC( class_,                      \
+                                           get_mm_,                     \
+                                           set_mm_design_,              \
+                                           set_mm_blend_,               \
+                                           get_mm_blend_,               \
+                                           get_mm_var_,                 \
+                                           set_var_design_,             \
+                                           get_var_design_,             \
+                                           set_named_instance_,         \
+                                           get_default_named_instance_, \
+                                           set_mm_weightvector_,        \
+                                           get_mm_weightvector_,        \
+                                                                        \
+                                           construct_ps_name_,          \
+                                           load_delta_set_idx_map_,     \
+                                           load_item_var_store_,        \
+                                           get_item_delta_,             \
+                                           done_item_var_store_,        \
+                                           done_delta_set_idx_map_,     \
+                                           get_var_blend_,              \
+                                           done_blend_ )                \
+  static const FT_Service_MultiMastersRec  class_ =                     \
+  {                                                                     \
+    get_mm_,                                                            \
+    set_mm_design_,                                                     \
+    set_mm_blend_,                                                      \
+    get_mm_blend_,                                                      \
+    get_mm_var_,                                                        \
+    set_var_design_,                                                    \
+    get_var_design_,                                                    \
+    set_named_instance_,                                                \
+    get_default_named_instance_,                                        \
+    set_mm_weightvector_,                                               \
+    get_mm_weightvector_,                                               \
+                                                                        \
+    construct_ps_name_,                                                 \
+    load_delta_set_idx_map_,                                            \
+    load_item_var_store_,                                               \
+    get_item_delta_,                                                    \
+    done_item_var_store_,                                               \
+    done_delta_set_idx_map_,                                            \
+    get_var_blend_,                                                     \
+    done_blend_                                                         \
   };
 
   /* */
diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svpscmap.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svpscmap.h
index fd99d85..6e599f3 100644
--- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svpscmap.h
+++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/services/svpscmap.h
@@ -97,7 +97,7 @@
   (*PS_Unicodes_CharIndexFunc)( PS_Unicodes  unicodes,
                                 FT_UInt32    unicode );
 
-  typedef FT_UInt32
+  typedef FT_UInt
   (*PS_Unicodes_CharNextFunc)( PS_Unicodes  unicodes,
                                FT_UInt32   *unicode );
 
diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/t1types.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/t1types.h
index 5a105c5..b9c9439 100644
--- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/t1types.h
+++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/t1types.h
@@ -201,30 +201,30 @@
 
   typedef struct  T1_FaceRec_
   {
-    FT_FaceRec      root;
-    T1_FontRec      type1;
-    const void*     psnames;
-    const void*     psaux;
-    const void*     afm_data;
-    FT_CharMapRec   charmaprecs[2];
-    FT_CharMap      charmaps[2];
+    FT_FaceRec     root;
+    T1_FontRec     type1;
+    const void*    psnames;
+    const void*    psaux;
+    const void*    afm_data;
+    FT_CharMapRec  charmaprecs[2];
+    FT_CharMap     charmaps[2];
 
     /* support for Multiple Masters fonts */
-    PS_Blend        blend;
+    PS_Blend       blend;
 
     /* undocumented, optional: indices of subroutines that express      */
     /* the NormalizeDesignVector and the ConvertDesignVector procedure, */
     /* respectively, as Type 2 charstrings; -1 if keywords not present  */
-    FT_Int           ndv_idx;
-    FT_Int           cdv_idx;
+    FT_Int         ndv_idx;
+    FT_Int         cdv_idx;
 
     /* undocumented, optional: has the same meaning as len_buildchar */
     /* for Type 2 fonts; manipulated by othersubrs 19, 24, and 25    */
-    FT_UInt          len_buildchar;
-    FT_Long*         buildchar;
+    FT_UInt        len_buildchar;
+    FT_Long*       buildchar;
 
     /* since version 2.1 - interface to PostScript hinter */
-    const void*     pshinter;
+    const void*    pshinter;
 
   } T1_FaceRec;
 
diff --git a/src/java.desktop/share/native/libfreetype/include/freetype/internal/tttypes.h b/src/java.desktop/share/native/libfreetype/include/freetype/internal/tttypes.h
index 3b52192..b9788c7 100644
--- a/src/java.desktop/share/native/libfreetype/include/freetype/internal/tttypes.h
+++ b/src/java.desktop/share/native/libfreetype/include/freetype/internal/tttypes.h
@@ -779,13 +779,15 @@
   /**************************************************************************
    *
    * @struct:
-   *   TT_Post_20Rec
+   *   TT_Post_NamesRec
    *
    * @description:
-   *   Postscript names sub-table, format 2.0.  Stores the PS name of each
-   *   glyph in the font face.
+   *   Postscript names table, either format 2.0 or 2.5.
    *
    * @fields:
+   *   loaded ::
+   *     A flag to indicate whether the PS names are loaded.
+   *
    *   num_glyphs ::
    *     The number of named glyphs in the table.
    *
@@ -798,68 +800,13 @@
    *   glyph_names ::
    *     The PS names not in Mac Encoding.
    */
-  typedef struct  TT_Post_20Rec_
+  typedef struct  TT_Post_NamesRec_
   {
+    FT_Bool     loaded;
     FT_UShort   num_glyphs;
     FT_UShort   num_names;
     FT_UShort*  glyph_indices;
-    FT_Char**   glyph_names;
-
-  } TT_Post_20Rec, *TT_Post_20;
-
-
-  /**************************************************************************
-   *
-   * @struct:
-   *   TT_Post_25Rec
-   *
-   * @description:
-   *   Postscript names sub-table, format 2.5.  Stores the PS name of each
-   *   glyph in the font face.
-   *
-   * @fields:
-   *   num_glyphs ::
-   *     The number of glyphs in the table.
-   *
-   *   offsets ::
-   *     An array of signed offsets in a normal Mac Postscript name encoding.
-   */
-  typedef struct  TT_Post_25_
-  {
-    FT_UShort  num_glyphs;
-    FT_Char*   offsets;
-
-  } TT_Post_25Rec, *TT_Post_25;
-
-
-  /**************************************************************************
-   *
-   * @struct:
-   *   TT_Post_NamesRec
-   *
-   * @description:
-   *   Postscript names table, either format 2.0 or 2.5.
-   *
-   * @fields:
-   *   loaded ::
-   *     A flag to indicate whether the PS names are loaded.
-   *
-   *   format_20 ::
-   *     The sub-table used for format 2.0.
-   *
-   *   format_25 ::
-   *     The sub-table used for format 2.5.
-   */
-  typedef struct  TT_Post_NamesRec_
-  {
-    FT_Bool  loaded;
-
-    union
-    {
-      TT_Post_20Rec  format_20;
-      TT_Post_25Rec  format_25;
-
-    } names;
+    FT_Byte**   glyph_names;
 
   } TT_Post_NamesRec, *TT_Post_Names;
 
@@ -1253,12 +1200,16 @@
    *   mm ::
    *     A pointer to the Multiple Masters service.
    *
-   *   var ::
-   *     A pointer to the Metrics Variations service.
+   *   tt_var ::
+   *     A pointer to the Metrics Variations service for the "truetype"
+   *     driver.
    *
-   *   hdmx ::
-   *     The face's horizontal device metrics ('hdmx' table).  This table is
-   *     optional in TrueType/OpenType fonts.
+   *   face_var ::
+   *     A pointer to the Metrics Variations service for this `TT_Face`'s
+   *     driver.
+   *
+   *   psaux ::
+   *     A pointer to the PostScript Auxiliary service.
    *
    *   gasp ::
    *     The grid-fitting and scaling properties table ('gasp').  This table
@@ -1364,6 +1315,12 @@
    *   var_postscript_prefix_len ::
    *     The length of the `var_postscript_prefix` string.
    *
+   *   var_default_named_instance ::
+   *     The index of the default named instance.
+   *
+   *   non_var_style_name ::
+   *     The non-variation style name, used as a backup.
+   *
    *   horz_metrics_size ::
    *     The size of the 'hmtx' table.
    *
@@ -1410,14 +1367,6 @@
    *     A mapping between the strike indices exposed by the API and the
    *     indices used in the font's sbit table.
    *
-   *   cpal ::
-   *     A pointer to data related to the 'CPAL' table.  `NULL` if the table
-   *     is not available.
-   *
-   *   colr ::
-   *     A pointer to data related to the 'COLR' table.  `NULL` if the table
-   *     is not available.
-   *
    *   kern_table ::
    *     A pointer to the 'kern' table.
    *
@@ -1445,19 +1394,23 @@
    *   vert_metrics_offset ::
    *     The file offset of the 'vmtx' table.
    *
-   *   sph_found_func_flags ::
-   *     Flags identifying special bytecode functions (used by the v38
-   *     implementation of the bytecode interpreter).
-   *
-   *   sph_compatibility_mode ::
-   *     This flag is set if we are in ClearType backward compatibility mode
-   *     (used by the v38 implementation of the bytecode interpreter).
-   *
    *   ebdt_start ::
    *     The file offset of the sbit data table (CBDT, bdat, etc.).
    *
    *   ebdt_size ::
    *     The size of the sbit data table.
+   *
+   *   cpal ::
+   *     A pointer to data related to the 'CPAL' table.  `NULL` if the table
+   *     is not available.
+   *
+   *   colr ::
+   *     A pointer to data related to the 'COLR' table.  `NULL` if the table
+   *     is not available.
+   *
+   *   svg ::
+   *     A pointer to data related to the 'SVG' table.  `NULL` if the table
+   *     is not available.
    */
   typedef struct  TT_FaceRec_
   {
@@ -1508,8 +1461,14 @@
     void*                 mm;
 
     /* a typeless pointer to the FT_Service_MetricsVariationsRec table */
-    /* used to handle the HVAR, VVAR, and MVAR OpenType tables         */
-    void*                 var;
+    /* used to handle the HVAR, VVAR, and MVAR OpenType tables by the  */
+    /* "truetype" driver                                               */
+    void*                 tt_var;
+
+    /* a typeless pointer to the FT_Service_MetricsVariationsRec table */
+    /* used to handle the HVAR, VVAR, and MVAR OpenType tables by this */
+    /* TT_Face's driver                                                */
+    void*                 face_var;             /* since 2.13.1 */
 #endif
 
     /* a typeless pointer to the PostScript Aux service */
@@ -1591,6 +1550,9 @@
     const char*           var_postscript_prefix;     /* since 2.7.2 */
     FT_UInt               var_postscript_prefix_len; /* since 2.7.2 */
 
+    FT_UInt               var_default_named_instance;  /* since 2.13.1 */
+
+    const char*           non_var_style_name;  /* since 2.13.1 */
 #endif
 
     /* since version 2.2 */
@@ -1627,13 +1589,6 @@
     FT_ULong              horz_metrics_offset;
     FT_ULong              vert_metrics_offset;
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    /* since 2.4.12 */
-    FT_ULong              sph_found_func_flags; /* special functions found */
-                                                /* for this face           */
-    FT_Bool               sph_compatibility_mode;
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
     /* since 2.7 */
     FT_ULong              ebdt_start;  /* either `CBDT', `EBDT', or `bdat' */
diff --git a/src/java.desktop/share/native/libfreetype/src/autofit/afblue.dat b/src/java.desktop/share/native/libfreetype/src/autofit/afblue.dat
index b7efe8b..8299baa 100644
--- a/src/java.desktop/share/native/libfreetype/src/autofit/afblue.dat
+++ b/src/java.desktop/share/native/libfreetype/src/autofit/afblue.dat
@@ -89,7 +89,7 @@
     "ت ث ط ظ ك"
   // We don't necessarily have access to medial forms via Unicode in case
   // Arabic presentational forms are missing.  The only character that is
-  // guaranteed to have the same vertical position with joining (this is,
+  // guaranteed to have the same vertical position with joining (that is,
   // non-isolated) forms is U+0640, ARABIC TATWEEL, which must join both
   // round and flat curves.
   AF_BLUE_STRING_ARABIC_JOIN
diff --git a/src/java.desktop/share/native/libfreetype/src/autofit/afcjk.c b/src/java.desktop/share/native/libfreetype/src/autofit/afcjk.c
index 5daefff..f414289 100644
--- a/src/java.desktop/share/native/libfreetype/src/autofit/afcjk.c
+++ b/src/java.desktop/share/native/libfreetype/src/autofit/afcjk.c
@@ -417,16 +417,14 @@
 
         {
           FT_Int  nn;
-          FT_Int  first = 0;
-          FT_Int  last  = -1;
+          FT_Int  pp, first, last;
 
 
-          for ( nn = 0; nn < outline.n_contours; first = last + 1, nn++ )
+          last = -1;
+          for ( nn = 0; nn < outline.n_contours; nn++ )
           {
-            FT_Int  pp;
-
-
-            last = outline.contours[nn];
+            first = last + 1;
+            last  = outline.contours[nn];
 
             /* Avoid single-point contours since they are never rasterized. */
             /* In some fonts, they correspond to mark attachment points     */
@@ -569,8 +567,8 @@
   af_cjk_metrics_check_digits( AF_CJKMetrics  metrics,
                                FT_Face        face )
   {
-    FT_Bool   started = 0, same_width = 1;
-    FT_Fixed  advance = 0, old_advance = 0;
+    FT_Bool  started = 0, same_width = 1;
+    FT_Long  advance = 0, old_advance = 0;
 
     /* If HarfBuzz is not available, we need a pointer to a single */
     /* unsigned long value.                                        */
@@ -635,10 +633,11 @@
   /* Initialize global metrics. */
 
   FT_LOCAL_DEF( FT_Error )
-  af_cjk_metrics_init( AF_CJKMetrics  metrics,
-                       FT_Face        face )
+  af_cjk_metrics_init( AF_StyleMetrics  metrics_,  /* AF_CJKMetrics */
+                       FT_Face          face )
   {
-    FT_CharMap  oldmap = face->charmap;
+    AF_CJKMetrics  metrics = (AF_CJKMetrics)metrics_;
+    FT_CharMap     oldmap  = face->charmap;
 
 
     metrics->units_per_em = face->units_per_EM;
@@ -756,9 +755,12 @@
   /* Scale global values in both directions. */
 
   FT_LOCAL_DEF( void )
-  af_cjk_metrics_scale( AF_CJKMetrics  metrics,
-                        AF_Scaler      scaler )
+  af_cjk_metrics_scale( AF_StyleMetrics  metrics_,   /* AF_CJKMetrics */
+                        AF_Scaler        scaler )
   {
+    AF_CJKMetrics  metrics = (AF_CJKMetrics)metrics_;
+
+
     /* we copy the whole structure since the x and y scaling values */
     /* are not modified, contrary to e.g. the `latin' auto-hinter   */
     metrics->root.scaler = *scaler;
@@ -771,11 +773,14 @@
   /* Extract standard_width from writing system/script specific */
   /* metrics class.                                             */
 
-  FT_LOCAL_DEF( void )
-  af_cjk_get_standard_widths( AF_CJKMetrics  metrics,
-                              FT_Pos*        stdHW,
-                              FT_Pos*        stdVW )
+  FT_CALLBACK_DEF( void )
+  af_cjk_get_standard_widths( AF_StyleMetrics  metrics_,  /* AF_CJKMetrics */
+                              FT_Pos*          stdHW,
+                              FT_Pos*          stdVW )
   {
+    AF_CJKMetrics  metrics = (AF_CJKMetrics)metrics_;
+
+
     if ( stdHW )
       *stdHW = metrics->axis[AF_DIMENSION_VERT].standard_width;
 
@@ -1376,9 +1381,10 @@
   /* Initalize hinting engine. */
 
   FT_LOCAL_DEF( FT_Error )
-  af_cjk_hints_init( AF_GlyphHints  hints,
-                     AF_CJKMetrics  metrics )
+  af_cjk_hints_init( AF_GlyphHints    hints,
+                     AF_StyleMetrics  metrics_ )   /* AF_CJKMetrics */
   {
+    AF_CJKMetrics   metrics = (AF_CJKMetrics)metrics_;
     FT_Render_Mode  mode;
     FT_UInt32       scaler_flags, other_flags;
 
@@ -1628,7 +1634,7 @@
 
     stem_edge->pos = base_edge->pos + fitted_width;
 
-    FT_TRACE5(( "  CJKLINK: edge %ld @%d (opos=%.2f) linked to %.2f,"
+    FT_TRACE5(( "  CJKLINK: edge %td @%d (opos=%.2f) linked to %.2f,"
                 " dist was %.2f, now %.2f\n",
                 stem_edge - hints->axis[dim].edges, stem_edge->fpos,
                 (double)stem_edge->opos / 64,
@@ -1852,7 +1858,7 @@
           continue;
 
 #ifdef FT_DEBUG_LEVEL_TRACE
-        FT_TRACE5(( "  CJKBLUE: edge %ld @%d (opos=%.2f) snapped to %.2f,"
+        FT_TRACE5(( "  CJKBLUE: edge %td @%d (opos=%.2f) snapped to %.2f,"
                     " was %.2f\n",
                     edge1 - edges, edge1->fpos, (double)edge1->opos / 64,
                     (double)blue->fit / 64, (double)edge1->pos / 64 ));
@@ -1916,7 +1922,7 @@
       /* this should not happen, but it's better to be safe */
       if ( edge2->blue_edge )
       {
-        FT_TRACE5(( "ASSERTION FAILED for edge %ld\n", edge2-edges ));
+        FT_TRACE5(( "ASSERTION FAILED for edge %td\n", edge2 - edges ));
 
         af_cjk_align_linked_edge( hints, dim, edge2, edge );
         edge->flags |= AF_EDGE_DONE;
@@ -2268,11 +2274,13 @@
   /* Apply the complete hinting algorithm to a CJK glyph. */
 
   FT_LOCAL_DEF( FT_Error )
-  af_cjk_hints_apply( FT_UInt        glyph_index,
-                      AF_GlyphHints  hints,
-                      FT_Outline*    outline,
-                      AF_CJKMetrics  metrics )
+  af_cjk_hints_apply( FT_UInt          glyph_index,
+                      AF_GlyphHints    hints,
+                      FT_Outline*      outline,
+                      AF_StyleMetrics  metrics_ )   /* AF_CJKMetrics */
   {
+    AF_CJKMetrics  metrics = (AF_CJKMetrics)metrics_;
+
     FT_Error  error;
     int       dim;
 
diff --git a/src/java.desktop/share/native/libfreetype/src/autofit/afcjk.h b/src/java.desktop/share/native/libfreetype/src/autofit/afcjk.h
index bd7b81b..f380ef6 100644
--- a/src/java.desktop/share/native/libfreetype/src/autofit/afcjk.h
+++ b/src/java.desktop/share/native/libfreetype/src/autofit/afcjk.h
@@ -103,22 +103,22 @@
 
 #ifdef AF_CONFIG_OPTION_CJK
   FT_LOCAL( FT_Error )
-  af_cjk_metrics_init( AF_CJKMetrics  metrics,
-                       FT_Face        face );
+  af_cjk_metrics_init( AF_StyleMetrics  metrics,
+                       FT_Face          face );
 
   FT_LOCAL( void )
-  af_cjk_metrics_scale( AF_CJKMetrics  metrics,
-                        AF_Scaler      scaler );
+  af_cjk_metrics_scale( AF_StyleMetrics  metrics,
+                        AF_Scaler        scaler );
 
   FT_LOCAL( FT_Error )
-  af_cjk_hints_init( AF_GlyphHints  hints,
-                     AF_CJKMetrics  metrics );
+  af_cjk_hints_init( AF_GlyphHints    hints,
+                     AF_StyleMetrics  metrics );
 
   FT_LOCAL( FT_Error )
-  af_cjk_hints_apply( FT_UInt        glyph_index,
-                      AF_GlyphHints  hints,
-                      FT_Outline*    outline,
-                      AF_CJKMetrics  metrics );
+  af_cjk_hints_apply( FT_UInt          glyph_index,
+                      AF_GlyphHints    hints,
+                      FT_Outline*      outline,
+                      AF_StyleMetrics  metrics );
 
   /* shared; called from afindic.c */
   FT_LOCAL( void )
diff --git a/src/java.desktop/share/native/libfreetype/src/autofit/afglobal.c b/src/java.desktop/share/native/libfreetype/src/autofit/afglobal.c
index ede27eb..b195757 100644
--- a/src/java.desktop/share/native/libfreetype/src/autofit/afglobal.c
+++ b/src/java.desktop/share/native/libfreetype/src/autofit/afglobal.c
@@ -376,8 +376,11 @@
 
 
   FT_LOCAL_DEF( void )
-  af_face_globals_free( AF_FaceGlobals  globals )
+  af_face_globals_free( void*  globals_ )
   {
+    AF_FaceGlobals  globals = (AF_FaceGlobals)globals_;
+
+
     if ( globals )
     {
       FT_Memory  memory = globals->face->memory;
diff --git a/src/java.desktop/share/native/libfreetype/src/autofit/afglobal.h b/src/java.desktop/share/native/libfreetype/src/autofit/afglobal.h
index 83a7c2f..66170e4 100644
--- a/src/java.desktop/share/native/libfreetype/src/autofit/afglobal.h
+++ b/src/java.desktop/share/native/libfreetype/src/autofit/afglobal.h
@@ -156,7 +156,7 @@
                                AF_StyleMetrics  *ametrics );
 
   FT_LOCAL( void )
-  af_face_globals_free( AF_FaceGlobals  globals );
+  af_face_globals_free( void*  globals );
 
   FT_LOCAL( FT_Bool )
   af_face_globals_is_digit( AF_FaceGlobals  globals,
diff --git a/src/java.desktop/share/native/libfreetype/src/autofit/afhints.c b/src/java.desktop/share/native/libfreetype/src/autofit/afhints.c
index 6515af9..e4a378f 100644
--- a/src/java.desktop/share/native/libfreetype/src/autofit/afhints.c
+++ b/src/java.desktop/share/native/libfreetype/src/autofit/afhints.c
@@ -320,8 +320,9 @@
 
 
   static char*
-  af_print_idx( char* p,
-                int   idx )
+  af_print_idx( char*   p,
+                size_t  n,
+                int     idx )
   {
     if ( idx == -1 )
     {
@@ -330,7 +331,7 @@
       p[2] = '\0';
     }
     else
-      ft_sprintf( p, "%d", idx );
+      ft_snprintf( p, n, "%d", idx );
 
     return p;
   }
@@ -457,12 +458,12 @@
                 " %5d %5d %7.2f %7.2f %7.2f %7.2f"
                 " %5s %5s %5s %5s\n",
                 point_idx,
-                af_print_idx( buf1,
+                af_print_idx( buf1, 16,
                               af_get_edge_index( hints, segment_idx_1, 1 ) ),
-                af_print_idx( buf2, segment_idx_1 ),
-                af_print_idx( buf3,
+                af_print_idx( buf2, 16, segment_idx_1 ),
+                af_print_idx( buf3, 16,
                               af_get_edge_index( hints, segment_idx_0, 0 ) ),
-                af_print_idx( buf4, segment_idx_0 ),
+                af_print_idx( buf4, 16, segment_idx_0 ),
                 ( point->flags & AF_FLAG_NEAR )
                   ? " near "
                   : ( point->flags & AF_FLAG_WEAK_INTERPOLATION )
@@ -476,18 +477,22 @@
                 (double)point->x / 64,
                 (double)point->y / 64,
 
-                af_print_idx( buf5, af_get_strong_edge_index( hints,
-                                                              point->before,
-                                                              1 ) ),
-                af_print_idx( buf6, af_get_strong_edge_index( hints,
-                                                              point->after,
-                                                              1 ) ),
-                af_print_idx( buf7, af_get_strong_edge_index( hints,
-                                                              point->before,
-                                                              0 ) ),
-                af_print_idx( buf8, af_get_strong_edge_index( hints,
-                                                              point->after,
-                                                              0 ) ) ));
+                af_print_idx( buf5, 16,
+                              af_get_strong_edge_index( hints,
+                                                        point->before,
+                                                        1 ) ),
+                af_print_idx( buf6, 16,
+                              af_get_strong_edge_index( hints,
+                                                        point->after,
+                                                        1 ) ),
+                af_print_idx( buf7, 16,
+                              af_get_strong_edge_index( hints,
+                                                        point->before,
+                                                        0 ) ),
+                af_print_idx( buf8, 16,
+                              af_get_strong_edge_index( hints,
+                                                        point->after,
+                                                        0 ) ) ));
     }
     AF_DUMP(( "\n" ));
   }
@@ -574,9 +579,12 @@
                   AF_INDEX_NUM( seg->first, points ),
                   AF_INDEX_NUM( seg->last, points ),
 
-                  af_print_idx( buf1, AF_INDEX_NUM( seg->link, segments ) ),
-                  af_print_idx( buf2, AF_INDEX_NUM( seg->serif, segments ) ),
-                  af_print_idx( buf3, AF_INDEX_NUM( seg->edge, edges ) ),
+                  af_print_idx( buf1, 16,
+                                AF_INDEX_NUM( seg->link, segments ) ),
+                  af_print_idx( buf2, 16,
+                                AF_INDEX_NUM( seg->serif, segments ) ),
+                  af_print_idx( buf3, 16,
+                                AF_INDEX_NUM( seg->edge, edges ) ),
 
                   seg->height,
                   seg->height - ( seg->max_coord - seg->min_coord ),
@@ -716,8 +724,10 @@
                   AF_INDEX_NUM( edge, edges ),
                   (double)(int)edge->opos / 64,
                   af_dir_str( (AF_Direction)edge->dir ),
-                  af_print_idx( buf1, AF_INDEX_NUM( edge->link, edges ) ),
-                  af_print_idx( buf2, AF_INDEX_NUM( edge->serif, edges ) ),
+                  af_print_idx( buf1, 16,
+                                AF_INDEX_NUM( edge->link, edges ) ),
+                  af_print_idx( buf2, 16,
+                                AF_INDEX_NUM( edge->serif, edges ) ),
 
                   edge->blue_edge ? 'y' : 'n',
                   (double)edge->opos / 64,
diff --git a/src/java.desktop/share/native/libfreetype/src/autofit/afindic.c b/src/java.desktop/share/native/libfreetype/src/autofit/afindic.c
index 289a09d..7fb12c6 100644
--- a/src/java.desktop/share/native/libfreetype/src/autofit/afindic.c
+++ b/src/java.desktop/share/native/libfreetype/src/autofit/afindic.c
@@ -28,9 +28,12 @@
 
 
   static FT_Error
-  af_indic_metrics_init( AF_CJKMetrics  metrics,
-                         FT_Face        face )
+  af_indic_metrics_init( AF_StyleMetrics  metrics_, /* AF_CJKMetrics */
+                         FT_Face          face )
   {
+    AF_CJKMetrics  metrics = (AF_CJKMetrics)metrics_;
+
+
     /* skip blue zone init in CJK routines */
     FT_CharMap  oldmap = face->charmap;
 
@@ -55,8 +58,8 @@
 
 
   static void
-  af_indic_metrics_scale( AF_CJKMetrics  metrics,
-                          AF_Scaler      scaler )
+  af_indic_metrics_scale( AF_StyleMetrics  metrics,
+                          AF_Scaler        scaler )
   {
     /* use CJK routines */
     af_cjk_metrics_scale( metrics, scaler );
@@ -64,8 +67,8 @@
 
 
   static FT_Error
-  af_indic_hints_init( AF_GlyphHints  hints,
-                       AF_CJKMetrics  metrics )
+  af_indic_hints_init( AF_GlyphHints    hints,
+                       AF_StyleMetrics  metrics )
   {
     /* use CJK routines */
     return af_cjk_hints_init( hints, metrics );
@@ -73,10 +76,10 @@
 
 
   static FT_Error
-  af_indic_hints_apply( FT_UInt        glyph_index,
-                        AF_GlyphHints  hints,
-                        FT_Outline*    outline,
-                        AF_CJKMetrics  metrics )
+  af_indic_hints_apply( FT_UInt          glyph_index,
+                        AF_GlyphHints    hints,
+                        FT_Outline*      outline,
+                        AF_StyleMetrics  metrics )
   {
     /* use CJK routines */
     return af_cjk_hints_apply( glyph_index, hints, outline, metrics );
@@ -87,10 +90,13 @@
   /* metrics class.                                             */
 
   static void
-  af_indic_get_standard_widths( AF_CJKMetrics  metrics,
-                                FT_Pos*        stdHW,
-                                FT_Pos*        stdVW )
+  af_indic_get_standard_widths( AF_StyleMetrics  metrics_, /* AF_CJKMetrics */
+                                FT_Pos*          stdHW,
+                                FT_Pos*          stdVW )
   {
+    AF_CJKMetrics  metrics = (AF_CJKMetrics)metrics_;
+
+
     if ( stdHW )
       *stdHW = metrics->axis[AF_DIMENSION_VERT].standard_width;
 
diff --git a/src/java.desktop/share/native/libfreetype/src/autofit/aflatin.c b/src/java.desktop/share/native/libfreetype/src/autofit/aflatin.c
index 4b3c59b..b86367a 100644
--- a/src/java.desktop/share/native/libfreetype/src/autofit/aflatin.c
+++ b/src/java.desktop/share/native/libfreetype/src/autofit/aflatin.c
@@ -496,23 +496,20 @@
           /* now compute min or max point indices and coordinates */
           points             = outline.points;
           best_point         = -1;
+          best_contour_first = -1;
+          best_contour_last  = -1;
           best_y             = 0;  /* make compiler happy */
-          best_contour_first = 0;  /* ditto */
-          best_contour_last  = 0;  /* ditto */
 
           {
             FT_Int  nn;
-            FT_Int  first = 0;
-            FT_Int  last  = -1;
+            FT_Int  pp, first, last;
 
 
-            for ( nn = 0; nn < outline.n_contours; first = last + 1, nn++ )
+            last = -1;
+            for ( nn = 0; nn < outline.n_contours; nn++ )
             {
-              FT_Int  old_best_point = best_point;
-              FT_Int  pp;
-
-
-              last = outline.contours[nn];
+              first = last + 1;
+              last  = outline.contours[nn];
 
               /* Avoid single-point contours since they are never      */
               /* rasterized.  In some fonts, they correspond to mark   */
@@ -551,7 +548,7 @@
                 }
               }
 
-              if ( best_point != old_best_point )
+              if ( best_point > best_contour_last )
               {
                 best_contour_first = first;
                 best_contour_last  = last;
@@ -1025,7 +1022,7 @@
         {
           *a = *b;
           FT_TRACE5(( "blue zone overlap:"
-                      " adjusting %s %ld to %ld\n",
+                      " adjusting %s %td to %ld\n",
                       a_is_top ? "overshoot" : "reference",
                       blue_sorted[i] - axis->blues,
                       *a ));
@@ -1068,8 +1065,8 @@
   af_latin_metrics_check_digits( AF_LatinMetrics  metrics,
                                  FT_Face          face )
   {
-    FT_Bool   started = 0, same_width = 1;
-    FT_Fixed  advance = 0, old_advance = 0;
+    FT_Bool  started = 0, same_width = 1;
+    FT_Long  advance = 0, old_advance = 0;
 
     /* If HarfBuzz is not available, we need a pointer to a single */
     /* unsigned long value.                                        */
@@ -1134,9 +1131,11 @@
   /* Initialize global metrics. */
 
   FT_LOCAL_DEF( FT_Error )
-  af_latin_metrics_init( AF_LatinMetrics  metrics,
+  af_latin_metrics_init( AF_StyleMetrics  metrics_,   /* AF_LatinMetrics */
                          FT_Face          face )
   {
+    AF_LatinMetrics  metrics = (AF_LatinMetrics)metrics_;
+
     FT_Error  error = FT_Err_Ok;
 
     FT_CharMap  oldmap = face->charmap;
@@ -1489,9 +1488,12 @@
   /* Scale global values in both directions. */
 
   FT_LOCAL_DEF( void )
-  af_latin_metrics_scale( AF_LatinMetrics  metrics,
+  af_latin_metrics_scale( AF_StyleMetrics  metrics_,   /* AF_LatinMetrics */
                           AF_Scaler        scaler )
   {
+    AF_LatinMetrics  metrics = (AF_LatinMetrics)metrics_;
+
+
     metrics->root.scaler.render_mode = scaler->render_mode;
     metrics->root.scaler.face        = scaler->face;
     metrics->root.scaler.flags       = scaler->flags;
@@ -1504,11 +1506,14 @@
   /* Extract standard_width from writing system/script specific */
   /* metrics class.                                             */
 
-  FT_LOCAL_DEF( void )
-  af_latin_get_standard_widths( AF_LatinMetrics  metrics,
+  FT_CALLBACK_DEF( void )
+  af_latin_get_standard_widths( AF_StyleMetrics  metrics_, /* AF_LatinMetrics */
                                 FT_Pos*          stdHW,
                                 FT_Pos*          stdVW )
   {
+    AF_LatinMetrics  metrics = (AF_LatinMetrics)metrics_;
+
+
     if ( stdHW )
       *stdHW = metrics->axis[AF_DIMENSION_VERT].standard_width;
 
@@ -2041,7 +2046,7 @@
             max = seg2->max_coord;
 
           /* compute maximum coordinate difference of the two segments */
-          /* (this is, how much they overlap)                          */
+          /* (that is, how much they overlap)                          */
           len = max - min;
           if ( len >= len_threshold )
           {
@@ -2610,8 +2615,10 @@
 
   static FT_Error
   af_latin_hints_init( AF_GlyphHints    hints,
-                       AF_LatinMetrics  metrics )
+                       AF_StyleMetrics  metrics_ )   /* AF_LatinMetrics */
   {
+    AF_LatinMetrics  metrics = (AF_LatinMetrics)metrics_;
+
     FT_Render_Mode  mode;
     FT_UInt32       scaler_flags, other_flags;
     FT_Face         face = metrics->root.scaler.face;
@@ -2953,7 +2960,7 @@
 
     stem_edge->pos = base_edge->pos + fitted_width;
 
-    FT_TRACE5(( "  LINK: edge %ld (opos=%.2f) linked to %.2f,"
+    FT_TRACE5(( "  LINK: edge %td (opos=%.2f) linked to %.2f,"
                 " dist was %.2f, now %.2f\n",
                 stem_edge - hints->axis[dim].edges,
                 (double)stem_edge->opos / 64, (double)stem_edge->pos / 64,
@@ -3078,13 +3085,13 @@
 
 #ifdef FT_DEBUG_LEVEL_TRACE
         if ( !anchor )
-          FT_TRACE5(( "  BLUE_ANCHOR: edge %ld (opos=%.2f) snapped to %.2f,"
-                      " was %.2f (anchor=edge %ld)\n",
+          FT_TRACE5(( "  BLUE_ANCHOR: edge %td (opos=%.2f) snapped to %.2f,"
+                      " was %.2f (anchor=edge %td)\n",
                       edge1 - edges,
                       (double)edge1->opos / 64, (double)blue->fit / 64,
                       (double)edge1->pos / 64, edge - edges ));
         else
-          FT_TRACE5(( "  BLUE: edge %ld (opos=%.2f) snapped to %.2f,"
+          FT_TRACE5(( "  BLUE: edge %td (opos=%.2f) snapped to %.2f,"
                       " was %.2f\n",
                       edge1 - edges,
                       (double)edge1->opos / 64, (double)blue->fit / 64,
@@ -3134,7 +3141,7 @@
       /* this should not happen, but it's better to be safe */
       if ( edge2->blue_edge )
       {
-        FT_TRACE5(( "  ASSERTION FAILED for edge %ld\n", edge2 - edges ));
+        FT_TRACE5(( "  ASSERTION FAILED for edge %td\n", edge2 - edges ));
 
         af_latin_align_linked_edge( hints, dim, edge2, edge );
         edge->flags |= AF_EDGE_DONE;
@@ -3202,7 +3209,7 @@
         anchor       = edge;
         edge->flags |= AF_EDGE_DONE;
 
-        FT_TRACE5(( "  ANCHOR: edge %ld (opos=%.2f) and %ld (opos=%.2f)"
+        FT_TRACE5(( "  ANCHOR: edge %td (opos=%.2f) and %td (opos=%.2f)"
                     " snapped to %.2f and %.2f\n",
                     edge - edges, (double)edge->opos / 64,
                     edge2 - edges, (double)edge2->opos / 64,
@@ -3231,7 +3238,7 @@
 
         if ( edge2->flags & AF_EDGE_DONE )
         {
-          FT_TRACE5(( "  ADJUST: edge %ld (pos=%.2f) moved to %.2f\n",
+          FT_TRACE5(( "  ADJUST: edge %td (pos=%.2f) moved to %.2f\n",
                       edge - edges, (double)edge->pos / 64,
                       (double)( edge2->pos - cur_len ) / 64 ));
 
@@ -3272,7 +3279,7 @@
           edge->pos  = cur_pos1 - cur_len / 2;
           edge2->pos = cur_pos1 + cur_len / 2;
 
-          FT_TRACE5(( "  STEM: edge %ld (opos=%.2f) linked to %ld (opos=%.2f)"
+          FT_TRACE5(( "  STEM: edge %td (opos=%.2f) linked to %td (opos=%.2f)"
                       " snapped to %.2f and %.2f\n",
                       edge - edges, (double)edge->opos / 64,
                       edge2 - edges, (double)edge2->opos / 64,
@@ -3303,7 +3310,7 @@
           edge->pos  = ( delta1 < delta2 ) ? cur_pos1 : cur_pos2;
           edge2->pos = edge->pos + cur_len;
 
-          FT_TRACE5(( "  STEM: edge %ld (opos=%.2f) linked to %ld (opos=%.2f)"
+          FT_TRACE5(( "  STEM: edge %td (opos=%.2f) linked to %td (opos=%.2f)"
                       " snapped to %.2f and %.2f\n",
                       edge - edges, (double)edge->opos / 64,
                       edge2 - edges, (double)edge2->opos / 64,
@@ -3326,7 +3333,7 @@
           if ( edge->link && FT_ABS( edge->link->pos - edge[-1].pos ) > 16 )
           {
 #ifdef FT_DEBUG_LEVEL_TRACE
-            FT_TRACE5(( "  BOUND: edge %ld (pos=%.2f) moved to %.2f\n",
+            FT_TRACE5(( "  BOUND: edge %td (pos=%.2f) moved to %.2f\n",
                         edge - edges,
                         (double)edge->pos / 64,
                         (double)edge[-1].pos / 64 ));
@@ -3428,7 +3435,7 @@
         if ( delta < 64 + 16 )
         {
           af_latin_align_serif_edge( hints, edge->serif, edge );
-          FT_TRACE5(( "  SERIF: edge %ld (opos=%.2f) serif to %ld (opos=%.2f)"
+          FT_TRACE5(( "  SERIF: edge %td (opos=%.2f) serif to %td (opos=%.2f)"
                       " aligned to %.2f\n",
                       edge - edges, (double)edge->opos / 64,
                       edge->serif - edges, (double)edge->serif->opos / 64,
@@ -3438,9 +3445,9 @@
         {
           edge->pos = FT_PIX_ROUND( edge->opos );
           anchor    = edge;
-          FT_TRACE5(( "  SERIF_ANCHOR: edge %ld (opos=%.2f)"
+          FT_TRACE5(( "  SERIF_ANCHOR: edge %td (opos=%.2f)"
                       " snapped to %.2f\n",
-                      edge-edges,
+                      edge - edges,
                       (double)edge->opos / 64, (double)edge->pos / 64 ));
         }
         else
@@ -3467,8 +3474,8 @@
                                      after->pos - before->pos,
                                      after->opos - before->opos );
 
-            FT_TRACE5(( "  SERIF_LINK1: edge %ld (opos=%.2f) snapped to %.2f"
-                        " from %ld (opos=%.2f)\n",
+            FT_TRACE5(( "  SERIF_LINK1: edge %td (opos=%.2f) snapped to %.2f"
+                        " from %td (opos=%.2f)\n",
                         edge - edges, (double)edge->opos / 64,
                         (double)edge->pos / 64,
                         before - edges, (double)before->opos / 64 ));
@@ -3477,7 +3484,7 @@
           {
             edge->pos = anchor->pos +
                         ( ( edge->opos - anchor->opos + 16 ) & ~31 );
-            FT_TRACE5(( "  SERIF_LINK2: edge %ld (opos=%.2f)"
+            FT_TRACE5(( "  SERIF_LINK2: edge %td (opos=%.2f)"
                         " snapped to %.2f\n",
                         edge - edges,
                         (double)edge->opos / 64, (double)edge->pos / 64 ));
@@ -3498,7 +3505,7 @@
           if ( edge->link && FT_ABS( edge->link->pos - edge[-1].pos ) > 16 )
           {
 #ifdef FT_DEBUG_LEVEL_TRACE
-            FT_TRACE5(( "  BOUND: edge %ld (pos=%.2f) moved to %.2f\n",
+            FT_TRACE5(( "  BOUND: edge %td (pos=%.2f) moved to %.2f\n",
                         edge - edges,
                         (double)edge->pos / 64,
                         (double)edge[-1].pos / 64 ));
@@ -3519,7 +3526,7 @@
           if ( edge->link && FT_ABS( edge->link->pos - edge[-1].pos ) > 16 )
           {
 #ifdef FT_DEBUG_LEVEL_TRACE
-            FT_TRACE5(( "  BOUND: edge %ld (pos=%.2f) moved to %.2f\n",
+            FT_TRACE5(( "  BOUND: edge %td (pos=%.2f) moved to %.2f\n",
                         edge - edges,
                         (double)edge->pos / 64,
                         (double)edge[1].pos / 64 ));
@@ -3547,8 +3554,10 @@
   af_latin_hints_apply( FT_UInt          glyph_index,
                         AF_GlyphHints    hints,
                         FT_Outline*      outline,
-                        AF_LatinMetrics  metrics )
+                        AF_StyleMetrics  metrics_ )    /* AF_LatinMetrics */
   {
+    AF_LatinMetrics  metrics = (AF_LatinMetrics)metrics_;
+
     FT_Error  error;
     int       dim;
 
diff --git a/src/java.desktop/share/native/libfreetype/src/autofit/aflatin.h b/src/java.desktop/share/native/libfreetype/src/autofit/aflatin.h
index 3c6a7ee..31aa91d 100644
--- a/src/java.desktop/share/native/libfreetype/src/autofit/aflatin.h
+++ b/src/java.desktop/share/native/libfreetype/src/autofit/aflatin.h
@@ -116,11 +116,11 @@
 
 
   FT_LOCAL( FT_Error )
-  af_latin_metrics_init( AF_LatinMetrics  metrics,
+  af_latin_metrics_init( AF_StyleMetrics  metrics,
                          FT_Face          face );
 
   FT_LOCAL( void )
-  af_latin_metrics_scale( AF_LatinMetrics  metrics,
+  af_latin_metrics_scale( AF_StyleMetrics  metrics,
                           AF_Scaler        scaler );
 
   FT_LOCAL( void )
diff --git a/src/java.desktop/share/native/libfreetype/src/autofit/afloader.c b/src/java.desktop/share/native/libfreetype/src/autofit/afloader.c
index c808279..7c47d56 100644
--- a/src/java.desktop/share/native/libfreetype/src/autofit/afloader.c
+++ b/src/java.desktop/share/native/libfreetype/src/autofit/afloader.c
@@ -55,10 +55,8 @@
       error = af_face_globals_new( face, &loader->globals, module );
       if ( !error )
       {
-        face->autohint.data =
-          (FT_Pointer)loader->globals;
-        face->autohint.finalizer =
-          (FT_Generic_Finalizer)af_face_globals_free;
+        face->autohint.data      = (FT_Pointer)loader->globals;
+        face->autohint.finalizer = af_face_globals_free;
       }
     }
 
diff --git a/src/java.desktop/share/native/libfreetype/src/autofit/afmodule.c b/src/java.desktop/share/native/libfreetype/src/autofit/afmodule.c
index 92e5156..20a6b96 100644
--- a/src/java.desktop/share/native/libfreetype/src/autofit/afmodule.c
+++ b/src/java.desktop/share/native/libfreetype/src/autofit/afmodule.c
@@ -89,10 +89,8 @@
       error = af_face_globals_new( face, &globals, module );
       if ( !error )
       {
-        face->autohint.data =
-          (FT_Pointer)globals;
-        face->autohint.finalizer =
-          (FT_Generic_Finalizer)af_face_globals_free;
+        face->autohint.data      = (FT_Pointer)globals;
+        face->autohint.finalizer = af_face_globals_free;
       }
     }
 
@@ -374,8 +372,9 @@
   FT_DEFINE_SERVICE_PROPERTIESREC(
     af_service_properties,
 
-    (FT_Properties_SetFunc)af_property_set,        /* set_property */
-    (FT_Properties_GetFunc)af_property_get )       /* get_property */
+    af_property_set,  /* FT_Properties_SetFunc set_property */
+    af_property_get   /* FT_Properties_GetFunc get_property */
+  )
 
 
   FT_DEFINE_SERVICEDESCREC1(
@@ -430,12 +429,14 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  af_autofitter_load_glyph( AF_Module     module,
-                            FT_GlyphSlot  slot,
-                            FT_Size       size,
-                            FT_UInt       glyph_index,
-                            FT_Int32      load_flags )
+  af_autofitter_load_glyph( FT_AutoHinter  module_,
+                            FT_GlyphSlot   slot,
+                            FT_Size        size,
+                            FT_UInt        glyph_index,
+                            FT_Int32       load_flags )
   {
+    AF_Module  module = (AF_Module)module_;
+
     FT_Error   error  = FT_Err_Ok;
     FT_Memory  memory = module->root.library->memory;
 
@@ -499,10 +500,10 @@
   FT_DEFINE_AUTOHINTER_INTERFACE(
     af_autofitter_interface,
 
-    NULL,                                                    /* reset_face */
-    NULL,                                              /* get_global_hints */
-    NULL,                                             /* done_global_hints */
-    (FT_AutoHinter_GlyphLoadFunc)af_autofitter_load_glyph    /* load_glyph */
+    NULL,                     /* FT_AutoHinter_GlobalResetFunc reset_face        */
+    NULL,                     /* FT_AutoHinter_GlobalGetFunc   get_global_hints  */
+    NULL,                     /* FT_AutoHinter_GlobalDoneFunc  done_global_hints */
+    af_autofitter_load_glyph  /* FT_AutoHinter_GlyphLoadFunc   load_glyph        */
   )
 
   FT_DEFINE_MODULE(
@@ -517,9 +518,9 @@
 
     (const void*)&af_autofitter_interface,
 
-    (FT_Module_Constructor)af_autofitter_init,  /* module_init   */
-    (FT_Module_Destructor) af_autofitter_done,  /* module_done   */
-    (FT_Module_Requester)  af_get_interface     /* get_interface */
+    af_autofitter_init,  /* FT_Module_Constructor module_init   */
+    af_autofitter_done,  /* FT_Module_Destructor  module_done   */
+    af_get_interface     /* FT_Module_Requester   get_interface */
   )
 
 
diff --git a/src/java.desktop/share/native/libfreetype/src/autofit/afshaper.c b/src/java.desktop/share/native/libfreetype/src/autofit/afshaper.c
index 1b8b870..abc6f1d 100644
--- a/src/java.desktop/share/native/libfreetype/src/autofit/afshaper.c
+++ b/src/java.desktop/share/native/libfreetype/src/autofit/afshaper.c
@@ -258,7 +258,7 @@
     /*
      * We now check whether we can construct blue zones, using glyphs
      * covered by the feature only.  In case there is not a single zone
-     * (this is, not a single character is covered), we skip this coverage.
+     * (that is, not a single character is covered), we skip this coverage.
      *
      */
     if ( style_class->coverage != AF_COVERAGE_DEFAULT )
@@ -313,9 +313,9 @@
      * hinted and usually rendered glyph.
      *
      * Consider the superscript feature of font `pala.ttf': Some of the
-     * glyphs are `real', this is, they have a zero vertical offset, but
+     * glyphs are `real', that is, they have a zero vertical offset, but
      * most of them are small caps glyphs shifted up to the superscript
-     * position (this is, the `sups' feature is present in both the GSUB and
+     * position (that is, the `sups' feature is present in both the GSUB and
      * GPOS tables).  The code for blue zones computation actually uses a
      * feature's y offset so that the `real' glyphs get correct hints.  But
      * later on it is impossible to decide whether a glyph index belongs to,
diff --git a/src/java.desktop/share/native/libfreetype/src/base/ftbbox.c b/src/java.desktop/share/native/libfreetype/src/base/ftbbox.c
index 7dd7188..385fea4 100644
--- a/src/java.desktop/share/native/libfreetype/src/base/ftbbox.c
+++ b/src/java.desktop/share/native/libfreetype/src/base/ftbbox.c
@@ -82,10 +82,13 @@
    * @Return:
    *   Always 0.  Needed for the interface only.
    */
-  static int
-  BBox_Move_To( FT_Vector*  to,
-                TBBox_Rec*  user )
+  FT_CALLBACK_DEF( int )
+  BBox_Move_To( const FT_Vector*  to,
+                void*             user_ )
   {
+    TBBox_Rec*  user = (TBBox_Rec*)user_;
+
+
     FT_UPDATE_BBOX( to, user->bbox );
 
     user->last = *to;
@@ -116,10 +119,13 @@
    * @Return:
    *   Always 0.  Needed for the interface only.
    */
-  static int
-  BBox_Line_To( FT_Vector*  to,
-                TBBox_Rec*  user )
+  FT_CALLBACK_DEF( int )
+  BBox_Line_To( const FT_Vector*  to,
+                void*             user_ )
   {
+    TBBox_Rec*  user = (TBBox_Rec*)user_;
+
+
     user->last = *to;
 
     return 0;
@@ -205,11 +211,14 @@
    *   In the case of a non-monotonous arc, we compute directly the
    *   extremum coordinates, as it is sufficiently fast.
    */
-  static int
-  BBox_Conic_To( FT_Vector*  control,
-                 FT_Vector*  to,
-                 TBBox_Rec*  user )
+  FT_CALLBACK_DEF( int )
+  BBox_Conic_To( const FT_Vector*  control,
+                 const FT_Vector*  to,
+                 void*             user_ )
   {
+    TBBox_Rec*  user = (TBBox_Rec*)user_;
+
+
     /* in case `to' is implicit and not included in bbox yet */
     FT_UPDATE_BBOX( to, user->bbox );
 
@@ -410,12 +419,15 @@
    *   In the case of a non-monotonous arc, we don't compute directly
    *   extremum coordinates, we subdivide instead.
    */
-  static int
-  BBox_Cubic_To( FT_Vector*  control1,
-                 FT_Vector*  control2,
-                 FT_Vector*  to,
-                 TBBox_Rec*  user )
+  FT_CALLBACK_DEF( int )
+  BBox_Cubic_To( const FT_Vector*  control1,
+                 const FT_Vector*  control2,
+                 const FT_Vector*  to,
+                 void*             user_ )
   {
+    TBBox_Rec*  user = (TBBox_Rec*)user_;
+
+
     /* We don't need to check `to' since it is always an on-point,    */
     /* thus within the bbox.  Only segments with an off-point outside */
     /* the bbox can possibly reach new extreme values.                */
diff --git a/src/java.desktop/share/native/libfreetype/src/base/ftcalc.c b/src/java.desktop/share/native/libfreetype/src/base/ftcalc.c
index 13e74f3..c5bc7e3 100644
--- a/src/java.desktop/share/native/libfreetype/src/base/ftcalc.c
+++ b/src/java.desktop/share/native/libfreetype/src/base/ftcalc.c
@@ -749,65 +749,43 @@
   FT_BASE_DEF( FT_Bool )
   FT_Matrix_Check( const FT_Matrix*  matrix )
   {
-    FT_Matrix  m;
-    FT_Fixed   val[4];
-    FT_Fixed   nonzero_minval, maxval;
-    FT_Fixed   temp1, temp2;
-    FT_UInt    i;
+    FT_Fixed  xx, xy, yx, yy;
+    FT_Fixed  val;
+    FT_Int    shift;
+    FT_ULong  temp1, temp2;
 
 
     if ( !matrix )
       return 0;
 
-    val[0] = FT_ABS( matrix->xx );
-    val[1] = FT_ABS( matrix->xy );
-    val[2] = FT_ABS( matrix->yx );
-    val[3] = FT_ABS( matrix->yy );
+    xx  = matrix->xx;
+    xy  = matrix->xy;
+    yx  = matrix->yx;
+    yy  = matrix->yy;
+    val = FT_ABS( xx ) | FT_ABS( xy ) | FT_ABS( yx ) | FT_ABS( yy );
 
-    /*
-     * To avoid overflow, we ensure that each value is not larger than
-     *
-     *   int(sqrt(2^31 / 4)) = 23170  ;
-     *
-     * we also check that no value becomes zero if we have to scale.
-     */
-
-    maxval         = 0;
-    nonzero_minval = FT_LONG_MAX;
-
-    for ( i = 0; i < 4; i++ )
-    {
-      if ( val[i] > maxval )
-        maxval = val[i];
-      if ( val[i] && val[i] < nonzero_minval )
-        nonzero_minval = val[i];
-    }
-
-    /* we only handle 32bit values */
-    if ( maxval > 0x7FFFFFFFL )
+    /* we only handle non-zero 32-bit values */
+    if ( !val || val > 0x7FFFFFFFL )
       return 0;
 
-    if ( maxval > 23170 )
+    /* Scale matrix to avoid the temp1 overflow, which is */
+    /* more stringent than avoiding the temp2 overflow.   */
+
+    shift = FT_MSB( val ) - 12;
+
+    if ( shift > 0 )
     {
-      FT_Fixed  scale = FT_DivFix( maxval, 23170 );
-
-
-      if ( !FT_DivFix( nonzero_minval, scale ) )
-        return 0;    /* value range too large */
-
-      m.xx = FT_DivFix( matrix->xx, scale );
-      m.xy = FT_DivFix( matrix->xy, scale );
-      m.yx = FT_DivFix( matrix->yx, scale );
-      m.yy = FT_DivFix( matrix->yy, scale );
+      xx >>= shift;
+      xy >>= shift;
+      yx >>= shift;
+      yy >>= shift;
     }
-    else
-      m = *matrix;
 
-    temp1 = FT_ABS( m.xx * m.yy - m.xy * m.yx );
-    temp2 = m.xx * m.xx + m.xy * m.xy + m.yx * m.yx + m.yy * m.yy;
+    temp1 = 32U * (FT_ULong)FT_ABS( xx * yy - xy * yx );
+    temp2 = (FT_ULong)( xx * xx ) + (FT_ULong)( xy * xy ) +
+            (FT_ULong)( yx * yx ) + (FT_ULong)( yy * yy );
 
-    if ( temp1 == 0         ||
-         temp2 / temp1 > 50 )
+    if ( temp1 <= temp2 )
       return 0;
 
     return 1;
@@ -1061,7 +1039,7 @@
     /*                                                           */
     /* This approach has the advantage that the angle between    */
     /* `in' and `out' is not checked.  In case one of the two    */
-    /* vectors is `dominant', this is, much larger than the      */
+    /* vectors is `dominant', that is, much larger than the      */
     /* other vector, we thus always have a flat corner.          */
     /*                                                           */
     /*                hypotenuse                                 */
@@ -1092,9 +1070,6 @@
   {
     FT_UInt   i;
     FT_Int64  temp;
-#ifndef FT_INT64
-    FT_Int64  halfUnit;
-#endif
 
 
 #ifdef FT_INT64
@@ -1103,7 +1078,7 @@
     for ( i = 0; i < count; ++i )
       temp += (FT_Int64)s[i] * f[i];
 
-    return ( temp + 0x8000 ) >> 16;
+    return (FT_Int32)( ( temp + 0x8000 ) >> 16 );
 #else
     temp.hi = 0;
     temp.lo = 0;
@@ -1139,13 +1114,10 @@
       FT_Add64( &temp, &multResult, &temp );
     }
 
-    /* Round value. */
-    halfUnit.hi = 0;
-    halfUnit.lo = 0x8000;
-    FT_Add64( &temp, &halfUnit, &temp );
+    /* Shift and round value. */
+    return (FT_Int32)( ( ( temp.hi << 16 ) | ( temp.lo >> 16 ) )
+                                     + ( 1 & ( temp.lo >> 15 ) ) );
 
-    return (FT_Int32)( ( (FT_Int32)( temp.hi & 0xFFFF ) << 16 ) |
-                                   ( temp.lo >> 16 )            );
 
 #endif /* !FT_INT64 */
 
diff --git a/src/java.desktop/share/native/libfreetype/src/base/ftdbgmem.c b/src/java.desktop/share/native/libfreetype/src/base/ftdbgmem.c
index 6730c4c..8fab50d 100644
--- a/src/java.desktop/share/native/libfreetype/src/base/ftdbgmem.c
+++ b/src/java.desktop/share/native/libfreetype/src/base/ftdbgmem.c
@@ -963,7 +963,7 @@
 #else  /* !FT_DEBUG_MEMORY */
 
   /* ANSI C doesn't like empty source files */
-  typedef int  _debug_mem_dummy;
+  typedef int  debug_mem_dummy_;
 
 #endif /* !FT_DEBUG_MEMORY */
 
diff --git a/src/java.desktop/share/native/libfreetype/src/base/ftmac.c b/src/java.desktop/share/native/libfreetype/src/base/ftmac.c
index de34e83..492d055 100644
--- a/src/java.desktop/share/native/libfreetype/src/base/ftmac.c
+++ b/src/java.desktop/share/native/libfreetype/src/base/ftmac.c
@@ -1082,7 +1082,7 @@
 #else /* !FT_MACINTOSH */
 
   /* ANSI C doesn't like empty source files */
-  typedef int  _ft_mac_dummy;
+  typedef int  ft_mac_dummy_;
 
 #endif /* !FT_MACINTOSH */
 
diff --git a/src/java.desktop/share/native/libfreetype/src/base/ftmm.c b/src/java.desktop/share/native/libfreetype/src/base/ftmm.c
index a2b4bd0..9e2dd7e 100644
--- a/src/java.desktop/share/native/libfreetype/src/base/ftmm.c
+++ b/src/java.desktop/share/native/libfreetype/src/base/ftmm.c
@@ -185,6 +185,14 @@
       error = FT_ERR( Invalid_Argument );
       if ( service->set_mm_design )
         error = service->set_mm_design( face, num_coords, coords );
+
+      if ( !error )
+      {
+        if ( num_coords )
+          face->face_flags |= FT_FACE_FLAG_VARIATION;
+        else
+          face->face_flags &= ~FT_FACE_FLAG_VARIATION;
+      }
     }
 
     /* enforce recomputation of auto-hinting data */
@@ -220,6 +228,14 @@
       error = FT_ERR( Invalid_Argument );
       if ( service->set_mm_weightvector )
         error = service->set_mm_weightvector( face, len, weightvector );
+
+      if ( !error )
+      {
+        if ( len )
+          face->face_flags |= FT_FACE_FLAG_VARIATION;
+        else
+          face->face_flags &= ~FT_FACE_FLAG_VARIATION;
+      }
     }
 
     /* enforce recomputation of auto-hinting data */
@@ -283,6 +299,30 @@
       if ( service_mm->set_var_design )
         error = service_mm->set_var_design( face, num_coords, coords );
 
+      if ( !error || error == -1 )
+      {
+        FT_Bool  is_variation_old = FT_IS_VARIATION( face );
+
+
+        if ( num_coords )
+          face->face_flags |= FT_FACE_FLAG_VARIATION;
+        else
+          face->face_flags &= ~FT_FACE_FLAG_VARIATION;
+
+        if ( service_mm->construct_ps_name )
+        {
+          if ( error == -1 )
+          {
+            /* The PS name of a named instance and a non-named instance */
+            /* usually differs, even if the axis values are identical.  */
+            if ( is_variation_old != FT_IS_VARIATION( face ) )
+              service_mm->construct_ps_name( face );
+          }
+          else
+            service_mm->construct_ps_name( face );
+        }
+      }
+
       /* internal error code -1 means `no change'; we can exit immediately */
       if ( error == -1 )
         return FT_Err_Ok;
@@ -359,6 +399,30 @@
       if ( service_mm->set_mm_blend )
         error = service_mm->set_mm_blend( face, num_coords, coords );
 
+      if ( !error || error == -1 )
+      {
+        FT_Bool  is_variation_old = FT_IS_VARIATION( face );
+
+
+        if ( num_coords )
+          face->face_flags |= FT_FACE_FLAG_VARIATION;
+        else
+          face->face_flags &= ~FT_FACE_FLAG_VARIATION;
+
+        if ( service_mm->construct_ps_name )
+        {
+          if ( error == -1 )
+          {
+            /* The PS name of a named instance and a non-named instance */
+            /* usually differs, even if the axis values are identical.  */
+            if ( is_variation_old != FT_IS_VARIATION( face ) )
+              service_mm->construct_ps_name( face );
+          }
+          else
+            service_mm->construct_ps_name( face );
+        }
+      }
+
       /* internal error code -1 means `no change'; we can exit immediately */
       if ( error == -1 )
         return FT_Err_Ok;
@@ -410,6 +474,30 @@
       if ( service_mm->set_mm_blend )
         error = service_mm->set_mm_blend( face, num_coords, coords );
 
+      if ( !error || error == -1 )
+      {
+        FT_Bool  is_variation_old = FT_IS_VARIATION( face );
+
+
+        if ( num_coords )
+          face->face_flags |= FT_FACE_FLAG_VARIATION;
+        else
+          face->face_flags &= ~FT_FACE_FLAG_VARIATION;
+
+        if ( service_mm->construct_ps_name )
+        {
+          if ( error == -1 )
+          {
+            /* The PS name of a named instance and a non-named instance */
+            /* usually differs, even if the axis values are identical.  */
+            if ( is_variation_old != FT_IS_VARIATION( face ) )
+              service_mm->construct_ps_name( face );
+          }
+          else
+            service_mm->construct_ps_name( face );
+        }
+      }
+
       /* internal error code -1 means `no change'; we can exit immediately */
       if ( error == -1 )
         return FT_Err_Ok;
@@ -535,8 +623,35 @@
     if ( !error )
     {
       error = FT_ERR( Invalid_Argument );
-      if ( service_mm->set_instance )
-        error = service_mm->set_instance( face, instance_index );
+      if ( service_mm->set_named_instance )
+        error = service_mm->set_named_instance( face, instance_index );
+
+      if ( !error || error == -1 )
+      {
+        FT_Bool  is_variation_old = FT_IS_VARIATION( face );
+
+
+        face->face_flags &= ~FT_FACE_FLAG_VARIATION;
+        face->face_index  = ( instance_index << 16 )        |
+                            ( face->face_index & 0xFFFFL );
+
+        if ( service_mm->construct_ps_name )
+        {
+          if ( error == -1 )
+          {
+            /* The PS name of a named instance and a non-named instance */
+            /* usually differs, even if the axis values are identical.  */
+            if ( is_variation_old != FT_IS_VARIATION( face ) )
+              service_mm->construct_ps_name( face );
+          }
+          else
+            service_mm->construct_ps_name( face );
+        }
+      }
+
+      /* internal error code -1 means `no change'; we can exit immediately */
+      if ( error == -1 )
+        return FT_Err_Ok;
     }
 
     if ( !error )
@@ -554,11 +669,32 @@
       face->autohint.data = NULL;
     }
 
+    return error;
+  }
+
+
+  /* documentation is in ftmm.h */
+
+  FT_EXPORT_DEF( FT_Error )
+  FT_Get_Default_Named_Instance( FT_Face   face,
+                                 FT_UInt  *instance_index )
+  {
+    FT_Error  error;
+
+    FT_Service_MultiMasters  service_mm = NULL;
+
+
+    /* check of `face' delayed to `ft_face_get_mm_service' */
+
+    error = ft_face_get_mm_service( face, &service_mm );
     if ( !error )
     {
-      face->face_index  = ( instance_index << 16 )        |
-                          ( face->face_index & 0xFFFFL );
-      face->face_flags &= ~FT_FACE_FLAG_VARIATION;
+      /* no error if `get_default_named_instance` is not available */
+      if ( service_mm->get_default_named_instance )
+        error = service_mm->get_default_named_instance( face,
+                                                        instance_index );
+      else
+        error = FT_Err_Ok;
     }
 
     return error;
diff --git a/src/java.desktop/share/native/libfreetype/src/base/ftobjs.c b/src/java.desktop/share/native/libfreetype/src/base/ftobjs.c
index ad6ef0a..89a25bc 100644
--- a/src/java.desktop/share/native/libfreetype/src/base/ftobjs.c
+++ b/src/java.desktop/share/native/libfreetype/src/base/ftobjs.c
@@ -1019,7 +1019,8 @@
       /*      elegant.                                            */
 
       /* try to load SVG documents if available */
-      if ( FT_HAS_SVG( face ) )
+      if ( ( load_flags & FT_LOAD_NO_SVG ) == 0 &&
+           FT_HAS_SVG( face )                   )
       {
         error = driver->clazz->load_glyph( slot, face->size,
                                            glyph_index,
@@ -1245,9 +1246,13 @@
   /* destructor for sizes list */
   static void
   destroy_size( FT_Memory  memory,
-                FT_Size    size,
-                FT_Driver  driver )
+                void*      size_,
+                void*      driver_ )
   {
+    FT_Size    size   = (FT_Size)size_;
+    FT_Driver  driver = (FT_Driver)driver_;
+
+
     /* finalize client-specific data */
     if ( size->generic.finalizer )
       size->generic.finalizer( size );
@@ -1293,10 +1298,12 @@
   /* destructor for faces list */
   static void
   destroy_face( FT_Memory  memory,
-                FT_Face    face,
-                FT_Driver  driver )
+                void*      face_,
+                void*      driver_ )
   {
-    FT_Driver_Class  clazz = driver->clazz;
+    FT_Face          face   = (FT_Face)face_;
+    FT_Driver        driver = (FT_Driver)driver_;
+    FT_Driver_Class  clazz  = driver->clazz;
 
 
     /* discard auto-hinting data */
@@ -1310,7 +1317,7 @@
 
     /* discard all sizes for this face */
     FT_List_Finalize( &face->sizes_list,
-                      (FT_List_Destructor)destroy_size,
+                      destroy_size,
                       memory,
                       driver );
     face->size = NULL;
@@ -1346,7 +1353,7 @@
   Destroy_Driver( FT_Driver  driver )
   {
     FT_List_Finalize( &driver->faces_list,
-                      (FT_List_Destructor)destroy_face,
+                      destroy_face,
                       driver->root.memory,
                       driver );
   }
@@ -1740,7 +1747,8 @@
     FT_Memory     memory = library->memory;
 
 
-    args.flags = 0;
+    args.driver = NULL;
+    args.flags  = 0;
 
     if ( driver_name )
     {
diff --git a/src/java.desktop/share/native/libfreetype/src/base/ftoutln.c b/src/java.desktop/share/native/libfreetype/src/base/ftoutln.c
index 30ff21f..134f39d 100644
--- a/src/java.desktop/share/native/libfreetype/src/base/ftoutln.c
+++ b/src/java.desktop/share/native/libfreetype/src/base/ftoutln.c
@@ -58,7 +58,9 @@
     FT_Error    error;
 
     FT_Int   n;         /* index of contour in outline     */
-    FT_UInt  first;     /* index of first point in contour */
+    FT_Int   first;     /* index of first point in contour */
+    FT_Int   last;      /* index of last point in contour  */
+
     FT_Int   tag;       /* current point's state           */
 
     FT_Int   shift;
@@ -73,18 +75,17 @@
 
     shift = func_interface->shift;
     delta = func_interface->delta;
-    first = 0;
 
+    last = -1;
     for ( n = 0; n < outline->n_contours; n++ )
     {
-      FT_Int  last;  /* index of last point in contour */
+      FT_TRACE5(( "FT_Outline_Decompose: Contour %d\n", n ));
 
-
-      FT_TRACE5(( "FT_Outline_Decompose: Outline %d\n", n ));
-
-      last = outline->contours[n];
-      if ( last < 0 )
+      first = last + 1;
+      last  = outline->contours[n];
+      if ( last < first )
         goto Invalid_Outline;
+
       limit = outline->points + last;
 
       v_start   = outline->points[first];
@@ -282,8 +283,6 @@
     Close:
       if ( error )
         goto Exit;
-
-      first = (FT_UInt)last + 1;
     }
 
     FT_TRACE5(( "FT_Outline_Decompose: Done\n" ));
@@ -368,7 +367,7 @@
       if ( n_points <= 0 || n_contours <= 0 )
         goto Bad;
 
-      end0 = end = -1;
+      end0 = -1;
       for ( n = 0; n < n_contours; n++ )
       {
         end = outline->contours[n];
@@ -380,7 +379,7 @@
         end0 = end;
       }
 
-      if ( end != n_points - 1 )
+      if ( end0 != n_points - 1 )
         goto Bad;
 
       /* XXX: check the tags array */
@@ -388,7 +387,7 @@
     }
 
   Bad:
-    return FT_THROW( Invalid_Argument );
+    return FT_THROW( Invalid_Outline );
   }
 
 
@@ -550,10 +549,12 @@
     if ( !outline )
       return;
 
-    first = 0;
-
+    last = -1;
     for ( n = 0; n < outline->n_contours; n++ )
     {
+      /* keep the first contour point as is and swap points around it */
+      /* to guarantee that the cubic arches stay valid after reverse  */
+      first = last + 2;
       last  = outline->contours[n];
 
       /* reverse point table */
@@ -591,8 +592,6 @@
           q--;
         }
       }
-
-      first = last + 1;
     }
 
     outline->flags ^= FT_OUTLINE_REVERSE_FILL;
@@ -941,7 +940,7 @@
 
     points = outline->points;
 
-    first = 0;
+    last = -1;
     for ( c = 0; c < outline->n_contours; c++ )
     {
       FT_Vector  in, out, anchor, shift;
@@ -949,8 +948,9 @@
       FT_Int     i, j, k;
 
 
-      l_in = 0;
-      last = outline->contours[c];
+      first = last + 1;
+      last  = outline->contours[c];
+      l_in  = 0;
 
       /* pacify compiler */
       in.x = in.y = anchor.x = anchor.y = 0;
@@ -1037,8 +1037,6 @@
         in   = out;
         l_in = l_out;
       }
-
-      first = last + 1;
     }
 
     return FT_Err_Ok;
@@ -1054,7 +1052,7 @@
     FT_Int      xshift, yshift;
     FT_Vector*  points;
     FT_Vector   v_prev, v_cur;
-    FT_Int      c, n, first;
+    FT_Int      c, n, first, last;
     FT_Pos      area = 0;
 
 
@@ -1086,11 +1084,11 @@
 
     points = outline->points;
 
-    first = 0;
+    last = -1;
     for ( c = 0; c < outline->n_contours; c++ )
     {
-      FT_Int  last = outline->contours[c];
-
+      first = last + 1;
+      last  = outline->contours[c];
 
       v_prev.x = points[last].x >> xshift;
       v_prev.y = points[last].y >> yshift;
@@ -1106,8 +1104,6 @@
 
         v_prev = v_cur;
       }
-
-      first = last + 1;
     }
 
     if ( area > 0 )
diff --git a/src/java.desktop/share/native/libfreetype/src/base/ftstream.c b/src/java.desktop/share/native/libfreetype/src/base/ftstream.c
index 05c5637..64826ac 100644
--- a/src/java.desktop/share/native/libfreetype/src/base/ftstream.c
+++ b/src/java.desktop/share/native/libfreetype/src/base/ftstream.c
@@ -141,7 +141,9 @@
       if ( read_bytes > count )
         read_bytes = count;
 
-      FT_MEM_COPY( buffer, stream->base + pos, read_bytes );
+      /* Allow "reading" zero bytes without UB even if buffer is NULL */
+      if ( count )
+        FT_MEM_COPY( buffer, stream->base + pos, read_bytes );
     }
 
     stream->pos = pos + read_bytes;
@@ -178,7 +180,9 @@
       if ( read_bytes > count )
         read_bytes = count;
 
-      FT_MEM_COPY( buffer, stream->base + stream->pos, read_bytes );
+      /* Allow "reading" zero bytes without UB even if buffer is NULL */
+      if ( count )
+        FT_MEM_COPY( buffer, stream->base + stream->pos, read_bytes );
     }
 
     stream->pos += read_bytes;
diff --git a/src/java.desktop/share/native/libfreetype/src/base/ftstroke.c b/src/java.desktop/share/native/libfreetype/src/base/ftstroke.c
index db358e7..92f1e43 100644
--- a/src/java.desktop/share/native/libfreetype/src/base/ftstroke.c
+++ b/src/java.desktop/share/native/libfreetype/src/base/ftstroke.c
@@ -2055,7 +2055,9 @@
     FT_Error    error;
 
     FT_Int      n;         /* index of contour in outline     */
-    FT_UInt     first;     /* index of first point in contour */
+    FT_Int      first;     /* index of first point in contour */
+    FT_Int      last;      /* index of last point in contour  */
+
     FT_Int      tag;       /* current point's state           */
 
 
@@ -2067,22 +2069,17 @@
 
     FT_Stroker_Rewind( stroker );
 
-    first = 0;
-
+    last = -1;
     for ( n = 0; n < outline->n_contours; n++ )
     {
-      FT_UInt  last;  /* index of last point in contour */
-
-
-      last  = (FT_UInt)outline->contours[n];
-      limit = outline->points + last;
+      first = last + 1;
+      last  = outline->contours[n];
 
       /* skip empty points; we don't stroke these */
       if ( last <= first )
-      {
-        first = last + 1;
         continue;
-      }
+
+      limit = outline->points + last;
 
       v_start = outline->points[first];
       v_last  = outline->points[last];
@@ -2231,8 +2228,6 @@
         if ( error )
           goto Exit;
       }
-
-      first = last + 1;
     }
 
     return FT_Err_Ok;
diff --git a/src/java.desktop/share/native/libfreetype/src/base/ftsynth.c b/src/java.desktop/share/native/libfreetype/src/base/ftsynth.c
index 6ec25e1..f32edd3 100644
--- a/src/java.desktop/share/native/libfreetype/src/base/ftsynth.c
+++ b/src/java.desktop/share/native/libfreetype/src/base/ftsynth.c
@@ -98,8 +98,17 @@
   FT_EXPORT_DEF( void )
   FT_GlyphSlot_Embolden( FT_GlyphSlot  slot )
   {
+    FT_GlyphSlot_AdjustWeight( slot, 0x0AAA, 0x0AAA );
+  }
+
+
+  FT_EXPORT_DEF( void )
+  FT_GlyphSlot_AdjustWeight( FT_GlyphSlot  slot,
+                             FT_Fixed      xdelta,
+                             FT_Fixed      ydelta )
+  {
     FT_Library  library;
-    FT_Face     face;
+    FT_Size     size;
     FT_Error    error;
     FT_Pos      xstr, ystr;
 
@@ -108,16 +117,15 @@
       return;
 
     library = slot->library;
-    face    = slot->face;
+    size    = slot->face->size;
 
     if ( slot->format != FT_GLYPH_FORMAT_OUTLINE &&
          slot->format != FT_GLYPH_FORMAT_BITMAP  )
       return;
 
-    /* some reasonable strength */
-    xstr = FT_MulFix( face->units_per_EM,
-                      face->size->metrics.y_scale ) / 24;
-    ystr = xstr;
+    /* express deltas in pixels in 26.6 format */
+    xstr = (FT_Pos)size->metrics.x_ppem * xdelta / 1024;
+    ystr = (FT_Pos)size->metrics.y_ppem * ydelta / 1024;
 
     if ( slot->format == FT_GLYPH_FORMAT_OUTLINE )
       FT_Outline_EmboldenXY( &slot->outline, xstr, ystr );
diff --git a/src/java.desktop/share/native/libfreetype/src/base/ftsystem.c b/src/java.desktop/share/native/libfreetype/src/base/ftsystem.c
index fcd289d..61c99e3 100644
--- a/src/java.desktop/share/native/libfreetype/src/base/ftsystem.c
+++ b/src/java.desktop/share/native/libfreetype/src/base/ftsystem.c
@@ -206,7 +206,7 @@
    *     The number of bytes to read from the stream.
    *
    * @Return:
-   *   The number of bytes actually read.  If `count' is zero (this is,
+   *   The number of bytes actually read.  If `count' is zero (that is,
    *   the function is used for seeking), a non-zero return value
    *   indicates an error.
    */
@@ -219,7 +219,7 @@
     FT_FILE*  file;
 
 
-    if ( !count && offset > stream->size )
+    if ( offset > stream->size && !count )
       return 1;
 
     file = STREAM_FILE( stream );
@@ -227,6 +227,11 @@
     if ( stream->pos != offset )
       ft_fseek( file, (long)offset, SEEK_SET );
 
+    /* Avoid calling `fread` with `buffer=NULL` and `count=0`, */
+    /* which is undefined behaviour.                           */
+    if ( !count )
+      return 0;
+
     return (unsigned long)ft_fread( buffer, 1, count, file );
   }
 
diff --git a/src/java.desktop/share/native/libfreetype/src/cff/cffcmap.c b/src/java.desktop/share/native/libfreetype/src/cff/cffcmap.c
index 6ed3143..10d287b 100644
--- a/src/java.desktop/share/native/libfreetype/src/cff/cffcmap.c
+++ b/src/java.desktop/share/native/libfreetype/src/cff/cffcmap.c
@@ -32,9 +32,10 @@
   /*************************************************************************/
 
   FT_CALLBACK_DEF( FT_Error )
-  cff_cmap_encoding_init( CFF_CMapStd  cmap,
-                          FT_Pointer   pointer )
+  cff_cmap_encoding_init( FT_CMap     cmap,
+                          FT_Pointer  pointer )
   {
+    CFF_CMapStd   cffcmap  = (CFF_CMapStd)cmap;
     TT_Face       face     = (TT_Face)FT_CMAP_FACE( cmap );
     CFF_Font      cff      = (CFF_Font)face->extra.data;
     CFF_Encoding  encoding = &cff->encoding;
@@ -42,63 +43,56 @@
     FT_UNUSED( pointer );
 
 
-    cmap->gids  = encoding->codes;
+    cffcmap->gids = encoding->codes;
 
     return 0;
   }
 
 
   FT_CALLBACK_DEF( void )
-  cff_cmap_encoding_done( CFF_CMapStd  cmap )
+  cff_cmap_encoding_done( FT_CMap  cmap )
   {
-    cmap->gids  = NULL;
+    CFF_CMapStd  cffcmap = (CFF_CMapStd)cmap;
+
+
+    cffcmap->gids = NULL;
   }
 
 
   FT_CALLBACK_DEF( FT_UInt )
-  cff_cmap_encoding_char_index( CFF_CMapStd  cmap,
-                                FT_UInt32    char_code )
+  cff_cmap_encoding_char_index( FT_CMap    cmap,
+                                FT_UInt32  char_code )
   {
-    FT_UInt  result = 0;
+    CFF_CMapStd  cffcmap = (CFF_CMapStd)cmap;
+    FT_UInt      result  = 0;
 
 
     if ( char_code < 256 )
-      result = cmap->gids[char_code];
+      result = cffcmap->gids[char_code];
 
     return result;
   }
 
 
-  FT_CALLBACK_DEF( FT_UInt32 )
-  cff_cmap_encoding_char_next( CFF_CMapStd   cmap,
-                               FT_UInt32    *pchar_code )
+  FT_CALLBACK_DEF( FT_UInt )
+  cff_cmap_encoding_char_next( FT_CMap     cmap,
+                               FT_UInt32  *pchar_code )
   {
-    FT_UInt    result    = 0;
-    FT_UInt32  char_code = *pchar_code;
+    CFF_CMapStd  cffcmap   = (CFF_CMapStd)cmap;
+    FT_UInt      result    = 0;
+    FT_UInt32    char_code = *pchar_code;
 
 
-    *pchar_code = 0;
-
-    if ( char_code < 255 )
+    while ( char_code < 255 )
     {
-      FT_UInt  code = (FT_UInt)( char_code + 1 );
-
-
-      for (;;)
+      result = cffcmap->gids[++char_code];
+      if ( result )
       {
-        if ( code >= 256 )
-          break;
-
-        result = cmap->gids[code];
-        if ( result != 0 )
-        {
-          *pchar_code = code;
-          break;
-        }
-
-        code++;
+        *pchar_code = char_code;
+        break;
       }
     }
+
     return result;
   }
 
@@ -130,9 +124,10 @@
   /*************************************************************************/
 
   FT_CALLBACK_DEF( const char* )
-  cff_sid_to_glyph_name( TT_Face  face,
+  cff_sid_to_glyph_name( void*    face_,  /* TT_Face */
                          FT_UInt  idx )
   {
+    TT_Face      face    = (TT_Face)face_;
     CFF_Font     cff     = (CFF_Font)face->extra.data;
     CFF_Charset  charset = &cff->charset;
     FT_UInt      sid     = charset->sids[idx];
@@ -143,14 +138,15 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  cff_cmap_unicode_init( PS_Unicodes  unicodes,
+  cff_cmap_unicode_init( FT_CMap      cmap,     /* PS_Unicodes */
                          FT_Pointer   pointer )
   {
-    TT_Face             face    = (TT_Face)FT_CMAP_FACE( unicodes );
-    FT_Memory           memory  = FT_FACE_MEMORY( face );
-    CFF_Font            cff     = (CFF_Font)face->extra.data;
-    CFF_Charset         charset = &cff->charset;
-    FT_Service_PsCMaps  psnames = (FT_Service_PsCMaps)cff->psnames;
+    PS_Unicodes         unicodes = (PS_Unicodes)cmap;
+    TT_Face             face     = (TT_Face)FT_CMAP_FACE( cmap );
+    FT_Memory           memory   = FT_FACE_MEMORY( face );
+    CFF_Font            cff      = (CFF_Font)face->extra.data;
+    CFF_Charset         charset  = &cff->charset;
+    FT_Service_PsCMaps  psnames  = (FT_Service_PsCMaps)cff->psnames;
 
     FT_UNUSED( pointer );
 
@@ -166,17 +162,18 @@
     return psnames->unicodes_init( memory,
                                    unicodes,
                                    cff->num_glyphs,
-                                   (PS_GetGlyphNameFunc)&cff_sid_to_glyph_name,
+                                   &cff_sid_to_glyph_name,
                                    (PS_FreeGlyphNameFunc)NULL,
                                    (FT_Pointer)face );
   }
 
 
   FT_CALLBACK_DEF( void )
-  cff_cmap_unicode_done( PS_Unicodes  unicodes )
+  cff_cmap_unicode_done( FT_CMap  cmap )    /* PS_Unicodes */
   {
-    FT_Face    face   = FT_CMAP_FACE( unicodes );
-    FT_Memory  memory = FT_FACE_MEMORY( face );
+    PS_Unicodes  unicodes = (PS_Unicodes)cmap;
+    FT_Face      face     = FT_CMAP_FACE( cmap );
+    FT_Memory    memory   = FT_FACE_MEMORY( face );
 
 
     FT_FREE( unicodes->maps );
@@ -185,25 +182,27 @@
 
 
   FT_CALLBACK_DEF( FT_UInt )
-  cff_cmap_unicode_char_index( PS_Unicodes  unicodes,
-                               FT_UInt32    char_code )
+  cff_cmap_unicode_char_index( FT_CMap    cmap,       /* PS_Unicodes */
+                               FT_UInt32  char_code )
   {
-    TT_Face             face    = (TT_Face)FT_CMAP_FACE( unicodes );
-    CFF_Font            cff     = (CFF_Font)face->extra.data;
-    FT_Service_PsCMaps  psnames = (FT_Service_PsCMaps)cff->psnames;
+    PS_Unicodes         unicodes = (PS_Unicodes)cmap;
+    TT_Face             face     = (TT_Face)FT_CMAP_FACE( cmap );
+    CFF_Font            cff      = (CFF_Font)face->extra.data;
+    FT_Service_PsCMaps  psnames  = (FT_Service_PsCMaps)cff->psnames;
 
 
     return psnames->unicodes_char_index( unicodes, char_code );
   }
 
 
-  FT_CALLBACK_DEF( FT_UInt32 )
-  cff_cmap_unicode_char_next( PS_Unicodes  unicodes,
-                              FT_UInt32   *pchar_code )
+  FT_CALLBACK_DEF( FT_UInt )
+  cff_cmap_unicode_char_next( FT_CMap     cmap,        /* PS_Unicodes */
+                              FT_UInt32  *pchar_code )
   {
-    TT_Face             face    = (TT_Face)FT_CMAP_FACE( unicodes );
-    CFF_Font            cff     = (CFF_Font)face->extra.data;
-    FT_Service_PsCMaps  psnames = (FT_Service_PsCMaps)cff->psnames;
+    PS_Unicodes         unicodes = (PS_Unicodes)cmap;
+    TT_Face             face     = (TT_Face)FT_CMAP_FACE( cmap );
+    CFF_Font            cff      = (CFF_Font)face->extra.data;
+    FT_Service_PsCMaps  psnames  = (FT_Service_PsCMaps)cff->psnames;
 
 
     return psnames->unicodes_char_next( unicodes, pchar_code );
diff --git a/src/java.desktop/share/native/libfreetype/src/cff/cffdrivr.c b/src/java.desktop/share/native/libfreetype/src/cff/cffdrivr.c
index 4e2e0e0..9898d62 100644
--- a/src/java.desktop/share/native/libfreetype/src/cff/cffdrivr.c
+++ b/src/java.desktop/share/native/libfreetype/src/cff/cffdrivr.c
@@ -108,20 +108,20 @@
    *   They can be implemented by format-specific interfaces.
    */
   FT_CALLBACK_DEF( FT_Error )
-  cff_get_kerning( FT_Face     ttface,          /* TT_Face */
+  cff_get_kerning( FT_Face     face,          /* CFF_Face */
                    FT_UInt     left_glyph,
                    FT_UInt     right_glyph,
                    FT_Vector*  kerning )
   {
-    TT_Face       face = (TT_Face)ttface;
-    SFNT_Service  sfnt = (SFNT_Service)face->sfnt;
+    CFF_Face      cffface = (CFF_Face)face;
+    SFNT_Service  sfnt    = (SFNT_Service)cffface->sfnt;
 
 
     kerning->x = 0;
     kerning->y = 0;
 
     if ( sfnt )
-      kerning->x = sfnt->get_kerning( face, left_glyph, right_glyph );
+      kerning->x = sfnt->get_kerning( cffface, left_glyph, right_glyph );
 
     return FT_Err_Ok;
   }
@@ -158,23 +158,23 @@
    *   FreeType error code.  0 means success.
    */
   FT_CALLBACK_DEF( FT_Error )
-  cff_glyph_load( FT_GlyphSlot  cffslot,      /* CFF_GlyphSlot */
-                  FT_Size       cffsize,      /* CFF_Size      */
+  cff_glyph_load( FT_GlyphSlot  slot,        /* CFF_GlyphSlot */
+                  FT_Size       size,        /* CFF_Size      */
                   FT_UInt       glyph_index,
                   FT_Int32      load_flags )
   {
     FT_Error       error;
-    CFF_GlyphSlot  slot = (CFF_GlyphSlot)cffslot;
-    CFF_Size       size = (CFF_Size)cffsize;
+    CFF_GlyphSlot  cffslot = (CFF_GlyphSlot)slot;
+    CFF_Size       cffsize = (CFF_Size)size;
 
 
-    if ( !slot )
+    if ( !cffslot )
       return FT_THROW( Invalid_Slot_Handle );
 
     FT_TRACE1(( "cff_glyph_load: glyph index %d\n", glyph_index ));
 
     /* check whether we want a scaled outline or bitmap */
-    if ( !size )
+    if ( !cffsize )
       load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
 
     /* reset the size object if necessary */
@@ -184,12 +184,12 @@
     if ( size )
     {
       /* these two objects must have the same parent */
-      if ( cffsize->face != cffslot->face )
+      if ( size->face != slot->face )
         return FT_THROW( Invalid_Face_Handle );
     }
 
     /* now load the glyph outline if necessary */
-    error = cff_slot_load( slot, size, glyph_index, load_flags );
+    error = cff_slot_load( cffslot, cffsize, glyph_index, load_flags );
 
     /* force drop-out mode to 2 - irrelevant now */
     /* slot->outline.dropout_mode = 2; */
@@ -216,7 +216,7 @@
       /* it is no longer necessary that those values are identical to   */
       /* the values in the `CFF' table                                  */
 
-      TT_Face   ttface = (TT_Face)face;
+      CFF_Face  cffface = (CFF_Face)face;
       FT_Short  dummy;
 
 
@@ -225,7 +225,7 @@
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
         /* no fast retrieval for blended MM fonts without VVAR table */
         if ( ( FT_IS_NAMED_INSTANCE( face ) || FT_IS_VARIATION( face ) ) &&
-             !( ttface->variation_support & TT_FACE_FLAG_VAR_VADVANCE )  )
+             !( cffface->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
           return FT_THROW( Unimplemented_Feature );
 #endif
 
@@ -233,7 +233,7 @@
         /* otherwise we extract the info from the CFF glyphstrings  */
         /* (instead of synthesizing a global value using the `OS/2' */
         /* table)                                                   */
-        if ( !ttface->vertical_info )
+        if ( !cffface->vertical_info )
           goto Missing_Table;
 
         for ( nn = 0; nn < count; nn++ )
@@ -241,11 +241,11 @@
           FT_UShort  ah;
 
 
-          ( (SFNT_Service)ttface->sfnt )->get_metrics( ttface,
-                                                       1,
-                                                       start + nn,
-                                                       &dummy,
-                                                       &ah );
+          ( (SFNT_Service)cffface->sfnt )->get_metrics( cffface,
+                                                        1,
+                                                        start + nn,
+                                                        &dummy,
+                                                        &ah );
 
           FT_TRACE5(( "  idx %d: advance height %d font unit%s\n",
                       start + nn,
@@ -259,12 +259,12 @@
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
         /* no fast retrieval for blended MM fonts without HVAR table */
         if ( ( FT_IS_NAMED_INSTANCE( face ) || FT_IS_VARIATION( face ) ) &&
-             !( ttface->variation_support & TT_FACE_FLAG_VAR_HADVANCE )  )
+             !( cffface->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
           return FT_THROW( Unimplemented_Feature );
 #endif
 
         /* check whether we have data from the `hmtx' table at all */
-        if ( !ttface->horizontal.number_Of_HMetrics )
+        if ( !cffface->horizontal.number_Of_HMetrics )
           goto Missing_Table;
 
         for ( nn = 0; nn < count; nn++ )
@@ -272,11 +272,11 @@
           FT_UShort  aw;
 
 
-          ( (SFNT_Service)ttface->sfnt )->get_metrics( ttface,
-                                                       0,
-                                                       start + nn,
-                                                       &dummy,
-                                                       &aw );
+          ( (SFNT_Service)cffface->sfnt )->get_metrics( cffface,
+                                                        0,
+                                                        start + nn,
+                                                        &dummy,
+                                                        &aw );
 
           FT_TRACE5(( "  idx %d: advance width %d font unit%s\n",
                       start + nn,
@@ -312,13 +312,14 @@
    *
    */
 
-  static FT_Error
-  cff_get_glyph_name( CFF_Face    face,
+  FT_CALLBACK_DEF( FT_Error )
+  cff_get_glyph_name( FT_Face     face,        /* CFF_Face */
                       FT_UInt     glyph_index,
                       FT_Pointer  buffer,
                       FT_UInt     buffer_max )
   {
-    CFF_Font    font   = (CFF_Font)face->extra.data;
+    CFF_Face    cffface = (CFF_Face)face;
+    CFF_Font    font    = (CFF_Font)cffface->extra.data;
     FT_String*  gname;
     FT_UShort   sid;
     FT_Error    error;
@@ -338,10 +339,7 @@
 
 
       if ( service && service->get_name )
-        return service->get_name( FT_FACE( face ),
-                                  glyph_index,
-                                  buffer,
-                                  buffer_max );
+        return service->get_name( face, glyph_index, buffer, buffer_max );
       else
       {
         FT_ERROR(( "cff_get_glyph_name:"
@@ -366,7 +364,7 @@
     /* first, locate the sid in the charset table */
     sid = font->charset.sids[glyph_index];
 
-    /* now, lookup the name itself */
+    /* now, look up the name itself */
     gname = cff_index_get_sid_string( font, sid );
 
     if ( gname )
@@ -379,21 +377,19 @@
   }
 
 
-  static FT_UInt
-  cff_get_name_index( CFF_Face          face,
+  FT_CALLBACK_DEF( FT_UInt )
+  cff_get_name_index( FT_Face           face,        /* CFF_Face */
                       const FT_String*  glyph_name )
   {
-    CFF_Font            cff;
-    CFF_Charset         charset;
+    CFF_Face            cffface = (CFF_Face)face;
+    CFF_Font            cff     = (CFF_Font)cffface->extra.data;
+    CFF_Charset         charset = &cff->charset;
     FT_Service_PsCMaps  psnames;
     FT_String*          name;
     FT_UShort           sid;
     FT_UInt             i;
 
 
-    cff     = (CFF_FontRec *)face->extra.data;
-    charset = &cff->charset;
-
     /* CFF2 table does not have glyph names; */
     /* we need to use `post' table method    */
     if ( cff->version_major == 2 )
@@ -408,7 +404,7 @@
 
 
       if ( service && service->name_index )
-        return service->name_index( FT_FACE( face ), glyph_name );
+        return service->name_index( face, glyph_name );
       else
       {
         FT_ERROR(( "cff_get_name_index:"
@@ -446,8 +442,8 @@
   FT_DEFINE_SERVICE_GLYPHDICTREC(
     cff_service_glyph_dict,
 
-    (FT_GlyphDict_GetNameFunc)  cff_get_glyph_name,      /* get_name   */
-    (FT_GlyphDict_NameIndexFunc)cff_get_name_index       /* name_index */
+    cff_get_glyph_name,  /* FT_GlyphDict_GetNameFunc   get_name   */
+    cff_get_name_index   /* FT_GlyphDict_NameIndexFunc name_index */
   )
 
 
@@ -456,25 +452,32 @@
    *
    */
 
-  static FT_Int
+  FT_CALLBACK_DEF( FT_Int )
   cff_ps_has_glyph_names( FT_Face  face )
   {
     return ( face->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) > 0;
   }
 
 
-  static FT_Error
-  cff_ps_get_font_info( CFF_Face         face,
+  FT_CALLBACK_DEF( FT_Error )
+  cff_ps_get_font_info( FT_Face          face,        /* CFF_Face */
                         PS_FontInfoRec*  afont_info )
   {
-    CFF_Font  cff   = (CFF_Font)face->extra.data;
-    FT_Error  error = FT_Err_Ok;
+    CFF_Face  cffface = (CFF_Face)face;
+    CFF_Font  cff     = (CFF_Font)cffface->extra.data;
+    FT_Error  error   = FT_Err_Ok;
 
 
+    if ( cffface->is_cff2 )
+    {
+      error = FT_THROW( Invalid_Argument );
+      goto Fail;
+    }
+
     if ( cff && !cff->font_info )
     {
       CFF_FontRecDict  dict      = &cff->top_font.font_dict;
-      FT_Memory        memory    = face->root.memory;
+      FT_Memory        memory    = FT_FACE_MEMORY( face );
       PS_FontInfoRec*  font_info = NULL;
 
 
@@ -507,18 +510,19 @@
   }
 
 
-  static FT_Error
-  cff_ps_get_font_extra( CFF_Face          face,
+  FT_CALLBACK_DEF( FT_Error )
+  cff_ps_get_font_extra( FT_Face           face,         /* CFF_Face */
                          PS_FontExtraRec*  afont_extra )
   {
-    CFF_Font  cff   = (CFF_Font)face->extra.data;
-    FT_Error  error = FT_Err_Ok;
+    CFF_Face  cffface = (CFF_Face)face;
+    CFF_Font  cff     = (CFF_Font)cffface->extra.data;
+    FT_Error  error   = FT_Err_Ok;
 
 
     if ( cff && !cff->font_extra )
     {
       CFF_FontRecDict   dict       = &cff->top_font.font_dict;
-      FT_Memory         memory     = face->root.memory;
+      FT_Memory         memory     = FT_FACE_MEMORY( face );
       PS_FontExtraRec*  font_extra = NULL;
       FT_String*        embedded_postscript;
 
@@ -588,13 +592,13 @@
   FT_DEFINE_SERVICE_PSINFOREC(
     cff_service_ps_info,
 
-    (PS_GetFontInfoFunc)   cff_ps_get_font_info,    /* ps_get_font_info    */
-    (PS_GetFontExtraFunc)  cff_ps_get_font_extra,   /* ps_get_font_extra   */
-    (PS_HasGlyphNamesFunc) cff_ps_has_glyph_names,  /* ps_has_glyph_names  */
+    cff_ps_get_font_info,    /* PS_GetFontInfoFunc    ps_get_font_info    */
+    cff_ps_get_font_extra,   /* PS_GetFontExtraFunc   ps_get_font_extra   */
+    cff_ps_has_glyph_names,  /* PS_HasGlyphNamesFunc  ps_has_glyph_names  */
     /* unsupported with CFF fonts */
-    (PS_GetFontPrivateFunc)NULL,                    /* ps_get_font_private */
+    NULL,                    /* PS_GetFontPrivateFunc ps_get_font_private */
     /* not implemented            */
-    (PS_GetFontValueFunc)  NULL                     /* ps_get_font_value   */
+    NULL                     /* PS_GetFontValueFunc   ps_get_font_value   */
   )
 
 
@@ -603,17 +607,18 @@
    *
    */
 
-  static const char*
-  cff_get_ps_name( CFF_Face  face )
+  FT_CALLBACK_DEF( const char* )
+  cff_get_ps_name( FT_Face  face )    /* CFF_Face */
   {
-    CFF_Font      cff  = (CFF_Font)face->extra.data;
-    SFNT_Service  sfnt = (SFNT_Service)face->sfnt;
+    CFF_Face      cffface = (CFF_Face)face;
+    CFF_Font      cff     = (CFF_Font)cffface->extra.data;
+    SFNT_Service  sfnt    = (SFNT_Service)cffface->sfnt;
 
 
     /* following the OpenType specification 1.7, we return the name stored */
     /* in the `name' table for a CFF wrapped into an SFNT container        */
 
-    if ( FT_IS_SFNT( FT_FACE( face ) ) && sfnt )
+    if ( FT_IS_SFNT( face ) && sfnt )
     {
       FT_Library             library     = FT_FACE_LIBRARY( face );
       FT_Module              sfnt_module = FT_Get_Module( library, "sfnt" );
@@ -625,17 +630,17 @@
 
 
       if ( service && service->get_ps_font_name )
-        return service->get_ps_font_name( FT_FACE( face ) );
+        return service->get_ps_font_name( face );
     }
 
-    return (const char*)cff->font_name;
+    return cff ? (const char*)cff->font_name : NULL;
   }
 
 
   FT_DEFINE_SERVICE_PSFONTNAMEREC(
     cff_service_ps_name,
 
-    (FT_PsName_GetFunc)cff_get_ps_name      /* get_ps_font_name */
+    cff_get_ps_name  /* FT_PsName_GetFunc get_ps_font_name */
   )
 
 
@@ -649,7 +654,7 @@
    * Otherwise call the service function in the sfnt module.
    *
    */
-  static FT_Error
+  FT_CALLBACK_DEF( FT_Error )
   cff_get_cmap_info( FT_CharMap    charmap,
                      TT_CMapInfo  *cmap_info )
   {
@@ -683,7 +688,7 @@
   FT_DEFINE_SERVICE_TTCMAPSREC(
     cff_service_get_cmap_info,
 
-    (TT_CMap_Info_GetFunc)cff_get_cmap_info    /* get_cmap_info */
+    cff_get_cmap_info  /* TT_CMap_Info_GetFunc get_cmap_info */
   )
 
 
@@ -691,14 +696,15 @@
    * CID INFO SERVICE
    *
    */
-  static FT_Error
-  cff_get_ros( CFF_Face      face,
+  FT_CALLBACK_DEF( FT_Error )
+  cff_get_ros( FT_Face       face,        /* FT_Face */
                const char*  *registry,
                const char*  *ordering,
                FT_Int       *supplement )
   {
-    FT_Error  error = FT_Err_Ok;
-    CFF_Font  cff   = (CFF_Font)face->extra.data;
+    FT_Error  error   = FT_Err_Ok;
+    CFF_Face  cffface = (CFF_Face)face;
+    CFF_Font  cff     = (CFF_Font)cffface->extra.data;
 
 
     if ( cff )
@@ -748,12 +754,13 @@
   }
 
 
-  static FT_Error
-  cff_get_is_cid( CFF_Face  face,
+  FT_CALLBACK_DEF( FT_Error )
+  cff_get_is_cid( FT_Face   face,    /* CFF_Face */
                   FT_Bool  *is_cid )
   {
-    FT_Error  error = FT_Err_Ok;
-    CFF_Font  cff   = (CFF_Font)face->extra.data;
+    FT_Error  error   = FT_Err_Ok;
+    CFF_Face  cffface = (CFF_Face)face;
+    CFF_Font  cff     = (CFF_Font)cffface->extra.data;
 
 
     *is_cid = 0;
@@ -771,17 +778,16 @@
   }
 
 
-  static FT_Error
-  cff_get_cid_from_glyph_index( CFF_Face  face,
+  FT_CALLBACK_DEF( FT_Error )
+  cff_get_cid_from_glyph_index( FT_Face   face,        /* CFF_Face */
                                 FT_UInt   glyph_index,
                                 FT_UInt  *cid )
   {
-    FT_Error  error = FT_Err_Ok;
-    CFF_Font  cff;
+    FT_Error  error   = FT_Err_Ok;
+    CFF_Face  cffface = (CFF_Face)face;
+    CFF_Font  cff     = (CFF_Font)cffface->extra.data;
 
 
-    cff = (CFF_Font)face->extra.data;
-
     if ( cff )
     {
       FT_UInt          c;
@@ -814,12 +820,12 @@
   FT_DEFINE_SERVICE_CIDREC(
     cff_service_cid_info,
 
-    (FT_CID_GetRegistryOrderingSupplementFunc)
-      cff_get_ros,                             /* get_ros                  */
-    (FT_CID_GetIsInternallyCIDKeyedFunc)
-      cff_get_is_cid,                          /* get_is_cid               */
-    (FT_CID_GetCIDFromGlyphIndexFunc)
-      cff_get_cid_from_glyph_index             /* get_cid_from_glyph_index */
+    cff_get_ros,
+      /* FT_CID_GetRegistryOrderingSupplementFunc get_ros                  */
+    cff_get_is_cid,
+      /* FT_CID_GetIsInternallyCIDKeyedFunc       get_is_cid               */
+    cff_get_cid_from_glyph_index
+      /* FT_CID_GetCIDFromGlyphIndexFunc          get_cid_from_glyph_index */
   )
 
 
@@ -831,9 +837,9 @@
   FT_DEFINE_SERVICE_PROPERTIESREC(
     cff_service_properties,
 
-    (FT_Properties_SetFunc)ps_property_set,      /* set_property */
-    (FT_Properties_GetFunc)ps_property_get )     /* get_property */
-
+    ps_property_set,  /* FT_Properties_SetFunc set_property */
+    ps_property_get   /* FT_Properties_GetFunc get_property */
+  )
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
 
@@ -842,160 +848,195 @@
    *
    */
 
-  static FT_Error
-  cff_set_mm_blend( CFF_Face   face,
+  FT_CALLBACK_DEF( FT_Error )
+  cff_set_mm_blend( FT_Face    face,        /* CFF_Face */
                     FT_UInt    num_coords,
                     FT_Fixed*  coords )
   {
-    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+    CFF_Face                 cffface = (CFF_Face)face;
+    FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
 
 
-    return mm->set_mm_blend( FT_FACE( face ), num_coords, coords );
+    return mm->set_mm_blend( face, num_coords, coords );
   }
 
 
-  static FT_Error
-  cff_get_mm_blend( CFF_Face   face,
+  FT_CALLBACK_DEF( FT_Error )
+  cff_get_mm_blend( FT_Face    face,       /* CFF_Face */
                     FT_UInt    num_coords,
                     FT_Fixed*  coords )
   {
-    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+    CFF_Face                 cffface = (CFF_Face)face;
+    FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
 
 
-    return mm->get_mm_blend( FT_FACE( face ), num_coords, coords );
+    return mm->get_mm_blend( face, num_coords, coords );
   }
 
 
-  static FT_Error
-  cff_set_mm_weightvector( CFF_Face   face,
+  FT_CALLBACK_DEF( FT_Error )
+  cff_set_mm_weightvector( FT_Face    face,          /* CFF_Face */
                            FT_UInt    len,
                            FT_Fixed*  weightvector )
   {
-    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+    CFF_Face                 cffface = (CFF_Face)face;
+    FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
 
 
-    return mm->set_mm_weightvector( FT_FACE( face ), len, weightvector );
+    return mm->set_mm_weightvector( face, len, weightvector );
   }
 
 
-  static FT_Error
-  cff_get_mm_weightvector( CFF_Face   face,
+  FT_CALLBACK_DEF( FT_Error )
+  cff_get_mm_weightvector( FT_Face    face,          /* CFF_Face */
                            FT_UInt*   len,
                            FT_Fixed*  weightvector )
   {
-    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+    CFF_Face                 cffface = (CFF_Face)face;
+    FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
 
 
-    return mm->get_mm_weightvector( FT_FACE( face ), len, weightvector );
+    return mm->get_mm_weightvector( face, len, weightvector );
   }
 
 
-  static FT_Error
-  cff_get_mm_var( CFF_Face     face,
+  FT_CALLBACK_DEF( void )
+  cff_construct_ps_name( FT_Face  face )  /* CFF_Face */
+  {
+    CFF_Face                 cffface = (CFF_Face)face;
+    FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
+
+
+    mm->construct_ps_name( face );
+  }
+
+
+  FT_CALLBACK_DEF( FT_Error )
+  cff_get_mm_var( FT_Face      face,    /* CFF_Face */
                   FT_MM_Var*  *master )
   {
-    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+    CFF_Face                 cffface = (CFF_Face)face;
+    FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
 
 
-    return mm->get_mm_var( FT_FACE( face ), master );
+    return mm->get_mm_var( face, master );
   }
 
 
-  static FT_Error
-  cff_set_var_design( CFF_Face   face,
+  FT_CALLBACK_DEF( FT_Error )
+  cff_set_var_design( FT_Face    face,       /* CFF_Face */
                       FT_UInt    num_coords,
                       FT_Fixed*  coords )
   {
-    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+    CFF_Face                 cffface = (CFF_Face)face;
+    FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
 
 
-    return mm->set_var_design( FT_FACE( face ), num_coords, coords );
+    return mm->set_var_design( face, num_coords, coords );
   }
 
 
-  static FT_Error
-  cff_get_var_design( CFF_Face   face,
+  FT_CALLBACK_DEF( FT_Error )
+  cff_get_var_design( FT_Face    face,       /* CFF_Face */
                       FT_UInt    num_coords,
                       FT_Fixed*  coords )
   {
-    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+    CFF_Face                 cffface = (CFF_Face)face;
+    FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
 
 
-    return mm->get_var_design( FT_FACE( face ), num_coords, coords );
+    return mm->get_var_design( face, num_coords, coords );
   }
 
 
-  static FT_Error
-  cff_set_instance( CFF_Face  face,
-                    FT_UInt   instance_index )
+  FT_CALLBACK_DEF( FT_Error )
+  cff_set_named_instance( FT_Face   face,            /* CFF_Face */
+                          FT_UInt   instance_index )
   {
-    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+    CFF_Face                 cffface = (CFF_Face)face;
+    FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
 
 
-    return mm->set_instance( FT_FACE( face ), instance_index );
+    return mm->set_named_instance( face, instance_index );
   }
 
 
-  static FT_Error
-  cff_load_item_variation_store( CFF_Face         face,
+  FT_CALLBACK_DEF( FT_Error )
+  cff_get_default_named_instance( FT_Face   face,            /* CFF_Face */
+                                  FT_UInt  *instance_index )
+  {
+    CFF_Face                 cffface = (CFF_Face)face;
+    FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
+
+
+    return mm->get_default_named_instance( face, instance_index );
+  }
+
+
+  FT_CALLBACK_DEF( FT_Error )
+  cff_load_item_variation_store( FT_Face          face,       /* CFF_Face */
                                  FT_ULong         offset,
                                  GX_ItemVarStore  itemStore )
   {
-    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+    CFF_Face                 cffface = (CFF_Face)face;
+    FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
 
 
-    return mm->load_item_var_store( FT_FACE(face), offset, itemStore );
+    return mm->load_item_var_store( face, offset, itemStore );
   }
 
 
-  static FT_Error
-  cff_load_delta_set_index_mapping( CFF_Face           face,
+  FT_CALLBACK_DEF( FT_Error )
+  cff_load_delta_set_index_mapping( FT_Face            face,   /* CFF_Face */
                                     FT_ULong           offset,
                                     GX_DeltaSetIdxMap  map,
                                     GX_ItemVarStore    itemStore,
                                     FT_ULong           table_len )
   {
-    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+    CFF_Face                 cffface = (CFF_Face)face;
+    FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
 
 
-    return mm->load_delta_set_idx_map( FT_FACE( face ), offset, map,
+    return mm->load_delta_set_idx_map( face, offset, map,
                                        itemStore, table_len );
   }
 
 
-  static FT_Int
-  cff_get_item_delta( CFF_Face         face,
+  FT_CALLBACK_DEF( FT_Int )
+  cff_get_item_delta( FT_Face          face,        /* CFF_Face */
                       GX_ItemVarStore  itemStore,
                       FT_UInt          outerIndex,
                       FT_UInt          innerIndex )
   {
-    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+    CFF_Face                 cffface = (CFF_Face)face;
+    FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
 
 
-    return mm->get_item_delta( FT_FACE( face ), itemStore,
-                               outerIndex, innerIndex );
+    return mm->get_item_delta( face, itemStore, outerIndex, innerIndex );
   }
 
 
-  static void
-  cff_done_item_variation_store( CFF_Face          face,
+  FT_CALLBACK_DEF( void )
+  cff_done_item_variation_store( FT_Face          face,       /* CFF_Face */
                                  GX_ItemVarStore  itemStore )
   {
-    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+    CFF_Face                 cffface = (CFF_Face)face;
+    FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
 
 
-    mm->done_item_var_store( FT_FACE( face ), itemStore );
+    mm->done_item_var_store( face, itemStore );
   }
 
 
-  static void
-  cff_done_delta_set_index_map( CFF_Face           face,
+  FT_CALLBACK_DEF( void )
+  cff_done_delta_set_index_map( FT_Face            face,       /* CFF_Face */
                                 GX_DeltaSetIdxMap  deltaSetIdxMap )
   {
-    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+    CFF_Face                 cffface = (CFF_Face)face;
+    FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
 
 
-    mm->done_delta_set_idx_map( FT_FACE ( face ), deltaSetIdxMap );
+    mm->done_delta_set_idx_map( face, deltaSetIdxMap );
   }
 
 
@@ -1003,36 +1044,35 @@
   FT_DEFINE_SERVICE_MULTIMASTERSREC(
     cff_service_multi_masters,
 
-    (FT_Get_MM_Func)        NULL,               /* get_mm                    */
-    (FT_Set_MM_Design_Func) NULL,               /* set_mm_design             */
-    (FT_Set_MM_Blend_Func)  cff_set_mm_blend,   /* set_mm_blend              */
-    (FT_Get_MM_Blend_Func)  cff_get_mm_blend,   /* get_mm_blend              */
-    (FT_Get_MM_Var_Func)    cff_get_mm_var,     /* get_mm_var                */
-    (FT_Set_Var_Design_Func)cff_set_var_design, /* set_var_design            */
-    (FT_Get_Var_Design_Func)cff_get_var_design, /* get_var_design            */
-    (FT_Set_Instance_Func)  cff_set_instance,   /* set_instance              */
-    (FT_Set_MM_WeightVector_Func)
-                            cff_set_mm_weightvector,
-                                                /* set_mm_weightvector       */
-    (FT_Get_MM_WeightVector_Func)
-                            cff_get_mm_weightvector,
-                                                /* get_mm_weightvector       */
-    (FT_Var_Load_Delta_Set_Idx_Map_Func)
-                            cff_load_delta_set_index_mapping,
-                                                /* load_delta_set_idx_map    */
-    (FT_Var_Load_Item_Var_Store_Func)
-                            cff_load_item_variation_store,
-                                                /* load_item_variation_store */
-    (FT_Var_Get_Item_Delta_Func)
-                            cff_get_item_delta, /* get_item_delta            */
-    (FT_Var_Done_Item_Var_Store_Func)
-                            cff_done_item_variation_store,
-                                                /* done_item_variation_store */
-    (FT_Var_Done_Delta_Set_Idx_Map_Func)
-                            cff_done_delta_set_index_map,
-                                                /* done_delta_set_index_map  */
-    (FT_Get_Var_Blend_Func) cff_get_var_blend,  /* get_var_blend             */
-    (FT_Done_Blend_Func)    cff_done_blend      /* done_blend                */
+    NULL,                /* FT_Get_MM_Func         get_mm                     */
+    NULL,                /* FT_Set_MM_Design_Func  set_mm_design              */
+    cff_set_mm_blend,    /* FT_Set_MM_Blend_Func   set_mm_blend               */
+    cff_get_mm_blend,    /* FT_Get_MM_Blend_Func   get_mm_blend               */
+    cff_get_mm_var,      /* FT_Get_MM_Var_Func     get_mm_var                 */
+    cff_set_var_design,  /* FT_Set_Var_Design_Func set_var_design             */
+    cff_get_var_design,  /* FT_Get_Var_Design_Func get_var_design             */
+    cff_set_named_instance,
+             /* FT_Set_Named_Instance_Func         set_named_instance         */
+    cff_get_default_named_instance,
+             /* FT_Get_Default_Named_Instance_Func get_default_named_instance */
+    cff_set_mm_weightvector,
+             /* FT_Set_MM_WeightVector_Func        set_mm_weightvector        */
+    cff_get_mm_weightvector,
+             /* FT_Get_MM_WeightVector_Func        get_mm_weightvector        */
+    cff_construct_ps_name,
+             /* FT_Construct_PS_Name_Func          construct_ps_name          */
+    cff_load_delta_set_index_mapping,
+             /* FT_Var_Load_Delta_Set_Idx_Map_Func load_delta_set_idx_map     */
+    cff_load_item_variation_store,
+             /* FT_Var_Load_Item_Var_Store_Func    load_item_variation_store  */
+    cff_get_item_delta,
+             /* FT_Var_Get_Item_Delta_Func         get_item_delta             */
+    cff_done_item_variation_store,
+             /* FT_Var_Done_Item_Var_Store_Func    done_item_variation_store  */
+    cff_done_delta_set_index_map,
+             /* FT_Var_Done_Delta_Set_Idx_Map_Func done_delta_set_index_map   */
+    cff_get_var_blend,   /* FT_Get_Var_Blend_Func  get_var_blend              */
+    cff_done_blend       /* FT_Done_Blend_Func     done_blend                 */
   )
 
 
@@ -1041,41 +1081,46 @@
    *
    */
 
-  static FT_Error
-  cff_hadvance_adjust( CFF_Face  face,
+  FT_CALLBACK_DEF( FT_Error )
+  cff_hadvance_adjust( FT_Face   face,    /* CFF_Face */
                        FT_UInt   gindex,
                        FT_Int   *avalue )
   {
-    FT_Service_MetricsVariations  var = (FT_Service_MetricsVariations)face->var;
+    CFF_Face  cffface = (CFF_Face)face;
+    FT_Service_MetricsVariations
+              var     = (FT_Service_MetricsVariations)cffface->tt_var;
 
 
-    return var->hadvance_adjust( FT_FACE( face ), gindex, avalue );
+    return var->hadvance_adjust( face, gindex, avalue );
   }
 
 
-  static void
-  cff_metrics_adjust( CFF_Face  face )
+  FT_CALLBACK_DEF( void )
+  cff_metrics_adjust( FT_Face  face )    /* CFF_Face */
   {
-    FT_Service_MetricsVariations  var = (FT_Service_MetricsVariations)face->var;
+    CFF_Face  cffface = (CFF_Face)face;
+    FT_Service_MetricsVariations
+              var     = (FT_Service_MetricsVariations)cffface->tt_var;
 
 
-    var->metrics_adjust( FT_FACE( face ) );
+    var->metrics_adjust( face );
   }
 
 
   FT_DEFINE_SERVICE_METRICSVARIATIONSREC(
     cff_service_metrics_variations,
 
-    (FT_HAdvance_Adjust_Func)cff_hadvance_adjust,    /* hadvance_adjust */
-    (FT_LSB_Adjust_Func)     NULL,                   /* lsb_adjust      */
-    (FT_RSB_Adjust_Func)     NULL,                   /* rsb_adjust      */
+    cff_hadvance_adjust,  /* FT_HAdvance_Adjust_Func hadvance_adjust */
+    NULL,                 /* FT_LSB_Adjust_Func      lsb_adjust      */
+    NULL,                 /* FT_RSB_Adjust_Func      rsb_adjust      */
 
-    (FT_VAdvance_Adjust_Func)NULL,                   /* vadvance_adjust */
-    (FT_TSB_Adjust_Func)     NULL,                   /* tsb_adjust      */
-    (FT_BSB_Adjust_Func)     NULL,                   /* bsb_adjust      */
-    (FT_VOrg_Adjust_Func)    NULL,                   /* vorg_adjust     */
+    NULL,                 /* FT_VAdvance_Adjust_Func vadvance_adjust */
+    NULL,                 /* FT_TSB_Adjust_Func      tsb_adjust      */
+    NULL,                 /* FT_BSB_Adjust_Func      bsb_adjust      */
+    NULL,                 /* FT_VOrg_Adjust_Func     vorg_adjust     */
 
-    (FT_Metrics_Adjust_Func) cff_metrics_adjust      /* metrics_adjust  */
+    cff_metrics_adjust,   /* FT_Metrics_Adjust_Func  metrics_adjust  */
+    NULL                  /* FT_Size_Reset_Func      size_reset      */
   )
 #endif
 
@@ -1088,11 +1133,11 @@
   FT_DEFINE_SERVICE_CFFLOADREC(
     cff_service_cff_load,
 
-    (FT_Get_Standard_Encoding_Func)cff_get_standard_encoding,
-    (FT_Load_Private_Dict_Func)    cff_load_private_dict,
-    (FT_FD_Select_Get_Func)        cff_fd_select_get,
-    (FT_Blend_Check_Vector_Func)   cff_blend_check_vector,
-    (FT_Blend_Build_Vector_Func)   cff_blend_build_vector
+    cff_get_standard_encoding,  /* FT_Get_Standard_Encoding_Func get_standard_encoding */
+    cff_load_private_dict,      /* FT_Load_Private_Dict_Func     load_private_dict     */
+    cff_fd_select_get,          /* FT_FD_Select_Get_Func         fd_select_get         */
+    cff_blend_check_vector,     /* FT_Blend_Check_Vector_Func    blend_check_vector    */
+    cff_blend_build_vector      /* FT_Blend_Build_Vector_Func    blend_build_vector    */
   )
 
 
diff --git a/src/java.desktop/share/native/libfreetype/src/cff/cffgload.c b/src/java.desktop/share/native/libfreetype/src/cff/cffgload.c
index cfa0aaf..c483d1d 100644
--- a/src/java.desktop/share/native/libfreetype/src/cff/cffgload.c
+++ b/src/java.desktop/share/native/libfreetype/src/cff/cffgload.c
@@ -356,14 +356,16 @@
 
 #ifdef FT_CONFIG_OPTION_SVG
     /* check for OT-SVG */
-    if ( ( load_flags & FT_LOAD_COLOR ) && face->svg )
+    if ( ( load_flags & FT_LOAD_NO_SVG ) == 0 &&
+         ( load_flags & FT_LOAD_COLOR )       &&
+         face->svg                            )
     {
       /*
        * We load the SVG document and try to grab the advances from the
        * table.  For the bearings we rely on the presetting hook to do that.
        */
 
-      SFNT_Service  sfnt  = (SFNT_Service)face->sfnt;
+      SFNT_Service  sfnt = (SFNT_Service)face->sfnt;
 
 
       if ( size && (size->root.metrics.x_ppem < 1 ||
diff --git a/src/java.desktop/share/native/libfreetype/src/cff/cffload.c b/src/java.desktop/share/native/libfreetype/src/cff/cffload.c
index 4b8c6e1..af79082 100644
--- a/src/java.desktop/share/native/libfreetype/src/cff/cffload.c
+++ b/src/java.desktop/share/native/libfreetype/src/cff/cffload.c
@@ -400,7 +400,7 @@
 
   /* Allocate a table containing pointers to an index's elements. */
   /* The `pool' argument makes this function convert the index    */
-  /* entries to C-style strings (this is, null-terminated).       */
+  /* entries to C-style strings (that is, null-terminated).       */
   static FT_Error
   cff_index_get_pointers( CFF_Index   idx,
                           FT_Byte***  table,
@@ -1361,14 +1361,15 @@
     for ( i = 0; i < numBlends; i++ )
     {
       const FT_Int32*  weight = &blend->BV[1];
-      FT_UInt32        sum;
+      FT_Fixed         sum;
 
 
-      /* convert inputs to 16.16 fixed-point */
-      sum = cff_parse_num( parser, &parser->stack[i + base] ) * 0x10000;
+      /* convert inputs to 16.16 fixed point */
+      sum = cff_parse_fixed( parser, &parser->stack[i + base] );
 
       for ( j = 1; j < blend->lenBV; j++ )
-        sum += cff_parse_num( parser, &parser->stack[delta++] ) * *weight++;
+        sum += FT_MulFix( cff_parse_fixed( parser, &parser->stack[delta++] ),
+                          *weight++ );
 
       /* point parser stack to new value on blend_stack */
       parser->stack[i + base] = subFont->blend_top;
@@ -1589,16 +1590,17 @@
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
 
   FT_LOCAL_DEF( FT_Error )
-  cff_get_var_blend( CFF_Face     face,
+  cff_get_var_blend( FT_Face      face,             /* CFF_Face */
                      FT_UInt     *num_coords,
                      FT_Fixed*   *coords,
                      FT_Fixed*   *normalizedcoords,
                      FT_MM_Var*  *mm_var )
   {
-    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+    CFF_Face                 cffface = (CFF_Face)face;
+    FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
 
 
-    return mm->get_var_blend( FT_FACE( face ),
+    return mm->get_var_blend( face,
                               num_coords,
                               coords,
                               normalizedcoords,
@@ -1607,13 +1609,14 @@
 
 
   FT_LOCAL_DEF( void )
-  cff_done_blend( CFF_Face  face )
+  cff_done_blend( FT_Face  face )    /* CFF_Face */
   {
-    FT_Service_MultiMasters  mm = (FT_Service_MultiMasters)face->mm;
+    CFF_Face                 cffface = (CFF_Face)face;
+    FT_Service_MultiMasters  mm      = (FT_Service_MultiMasters)cffface->mm;
 
 
-    if (mm)
-      mm->done_blend( FT_FACE( face ) );
+    if ( mm )
+      mm->done_blend( face );
   }
 
 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
@@ -1650,13 +1653,6 @@
       goto Exit;
     }
 
-    /* Zero out the code to gid/sid mappings. */
-    for ( j = 0; j < 256; j++ )
-    {
-      encoding->sids [j] = 0;
-      encoding->codes[j] = 0;
-    }
-
     /* Note: The encoding table in a CFF font is indexed by glyph index;  */
     /* the first encoded glyph index is 1.  Hence, we read the character  */
     /* code (`glyph_code') at index j and make the assignment:            */
@@ -1671,6 +1667,10 @@
 
     if ( offset > 1 )
     {
+      /* Zero out the code to gid/sid mappings. */
+      FT_ARRAY_ZERO( encoding->sids,  256 );
+      FT_ARRAY_ZERO( encoding->codes, 256 );
+
       encoding->offset = base_offset + offset;
 
       /* we need to parse the table to determine its size */
@@ -2012,7 +2012,7 @@
     /*       Top and Font DICTs are not allowed to have blend operators. */
     error = cff_parser_init( &parser,
                              code,
-                             &subfont->font_dict,
+                             top,
                              font->library,
                              stackSize,
                              0,
diff --git a/src/java.desktop/share/native/libfreetype/src/cff/cffload.h b/src/java.desktop/share/native/libfreetype/src/cff/cffload.h
index 5a41cde..b5286b0 100644
--- a/src/java.desktop/share/native/libfreetype/src/cff/cffload.h
+++ b/src/java.desktop/share/native/libfreetype/src/cff/cffload.h
@@ -105,14 +105,14 @@
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
   FT_LOCAL( FT_Error )
-  cff_get_var_blend( CFF_Face     face,
+  cff_get_var_blend( FT_Face      face,
                      FT_UInt     *num_coords,
                      FT_Fixed*   *coords,
                      FT_Fixed*   *normalizedcoords,
                      FT_MM_Var*  *mm_var );
 
   FT_LOCAL( void )
-  cff_done_blend( CFF_Face  face );
+  cff_done_blend( FT_Face  face );
 #endif
 
 
diff --git a/src/java.desktop/share/native/libfreetype/src/cff/cffobjs.c b/src/java.desktop/share/native/libfreetype/src/cff/cffobjs.c
index 40cd9bf..6d08620 100644
--- a/src/java.desktop/share/native/libfreetype/src/cff/cffobjs.c
+++ b/src/java.desktop/share/native/libfreetype/src/cff/cffobjs.c
@@ -69,8 +69,8 @@
     FT_Module         module;
 
 
-    module = FT_Get_Module( size->root.face->driver->root.library,
-                            "pshinter" );
+    module = FT_Get_Module( font->library, "pshinter" );
+
     return ( module && pshinter && pshinter->get_globals_funcs )
            ? pshinter->get_globals_funcs( module )
            : 0;
@@ -182,8 +182,7 @@
       goto Exit;
 
     cff_make_private_dict( &font->top_font, &priv );
-    error = funcs->create( cffsize->face->memory, &priv,
-                             &internal->topfont );
+    error = funcs->create( memory, &priv, &internal->topfont );
     if ( error )
       goto Exit;
 
@@ -193,8 +192,7 @@
 
 
       cff_make_private_dict( sub, &priv );
-      error = funcs->create( cffsize->face->memory, &priv,
-                               &internal->subfonts[i - 1] );
+      error = funcs->create( memory, &priv, &internal->subfonts[i - 1] );
       if ( error )
         goto Exit;
     }
@@ -381,8 +379,7 @@
       FT_Module  module;
 
 
-      module = FT_Get_Module( slot->face->driver->root.library,
-                              "pshinter" );
+      module = FT_Get_Module( slot->library, "pshinter" );
       if ( module )
       {
         T2_Hints_Funcs  funcs;
@@ -722,22 +719,15 @@
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
       {
-        FT_Service_MultiMasters       mm  = (FT_Service_MultiMasters)face->mm;
-        FT_Service_MetricsVariations  var = (FT_Service_MetricsVariations)face->var;
-
         FT_UInt  instance_index = (FT_UInt)face_index >> 16;
 
 
         if ( FT_HAS_MULTIPLE_MASTERS( cffface ) &&
-             mm                                 &&
              instance_index > 0                 )
         {
-          error = mm->set_instance( cffface, instance_index );
+          error = FT_Set_Named_Instance( cffface, instance_index );
           if ( error )
             goto Exit;
-
-          if ( var )
-            var->metrics_adjust( cffface );
         }
       }
 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
@@ -1160,7 +1150,7 @@
     }
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
-    cff_done_blend( face );
+    cff_done_blend( cffface );
     face->blend = NULL;
 #endif
   }
diff --git a/src/java.desktop/share/native/libfreetype/src/cff/cffparse.c b/src/java.desktop/share/native/libfreetype/src/cff/cffparse.c
index e16206f..3b07670 100644
--- a/src/java.desktop/share/native/libfreetype/src/cff/cffparse.c
+++ b/src/java.desktop/share/native/libfreetype/src/cff/cffparse.c
@@ -63,10 +63,7 @@
 
     /* allocate the stack buffer */
     if ( FT_QNEW_ARRAY( parser->stack, stackSize ) )
-    {
-      FT_FREE( parser->stack );
       goto Exit;
-    }
 
     parser->stackSize = stackSize;
     parser->top       = parser->stack;    /* empty stack */
@@ -76,23 +73,6 @@
   }
 
 
-#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
-  static void
-  finalize_t2_strings( FT_Memory  memory,
-                       void*      data,
-                       void*      user )
-  {
-    CFF_T2_String  t2 = (CFF_T2_String)data;
-
-
-    FT_UNUSED( user );
-
-    memory->free( memory, t2->start );
-    memory->free( memory, data );
-  }
-#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
-
-
   FT_LOCAL_DEF( void )
   cff_parser_done( CFF_Parser  parser )
   {
@@ -102,63 +82,19 @@
     FT_FREE( parser->stack );
 
 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
-    FT_List_Finalize( &parser->t2_strings,
-                      finalize_t2_strings,
-                      memory,
-                      NULL );
+    FT_List_Finalize( &parser->t2_strings, NULL, memory, NULL );
 #endif
   }
 
 
-  /* Assuming `first >= last'. */
-
-  static FT_Error
-  cff_parser_within_limits( CFF_Parser  parser,
-                            FT_Byte*    first,
-                            FT_Byte*    last )
-  {
-#ifndef CFF_CONFIG_OPTION_OLD_ENGINE
-
-    /* Fast path for regular FreeType builds with the "new" engine; */
-    /*   `first >= parser->start' can be assumed.                   */
-
-    FT_UNUSED( first );
-
-    return last < parser->limit ? FT_Err_Ok : FT_THROW( Invalid_Argument );
-
-#else /* CFF_CONFIG_OPTION_OLD_ENGINE */
-
-    FT_ListNode  node;
-
-
-    if ( first >= parser->start &&
-         last  <  parser->limit )
-      return FT_Err_Ok;
-
-    node = parser->t2_strings.head;
-
-    while ( node )
-    {
-      CFF_T2_String  t2 = (CFF_T2_String)node->data;
-
-
-      if ( first >= t2->start &&
-           last  <  t2->limit )
-        return FT_Err_Ok;
-
-      node = node->next;
-    }
-
-    return FT_THROW( Invalid_Argument );
-
-#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
-  }
-
+  /* The parser limit checks in the next two functions are supposed */
+  /* to detect the immediate crossing of the stream boundary.  They */
+  /* shall not be triggered from the distant t2_strings buffers.    */
 
   /* read an integer */
   static FT_Long
-  cff_parse_integer( CFF_Parser  parser,
-                     FT_Byte*    start )
+  cff_parse_integer( FT_Byte*  start,
+                     FT_Byte*  limit )
   {
     FT_Byte*  p   = start;
     FT_Int    v   = *p++;
@@ -167,14 +103,14 @@
 
     if ( v == 28 )
     {
-      if ( cff_parser_within_limits( parser, p, p + 1 ) )
+      if ( p + 2 > limit && limit >= p )
         goto Bad;
 
       val = (FT_Short)( ( (FT_UShort)p[0] << 8 ) | p[1] );
     }
     else if ( v == 29 )
     {
-      if ( cff_parser_within_limits( parser, p, p + 3 ) )
+      if ( p + 4 > limit && limit >= p )
         goto Bad;
 
       val = (FT_Long)( ( (FT_ULong)p[0] << 24 ) |
@@ -188,14 +124,14 @@
     }
     else if ( v < 251 )
     {
-      if ( cff_parser_within_limits( parser, p, p ) )
+      if ( p + 1 > limit && limit >= p )
         goto Bad;
 
       val = ( v - 247 ) * 256 + p[0] + 108;
     }
     else
     {
-      if ( cff_parser_within_limits( parser, p, p ) )
+      if ( p + 1 > limit && limit >= p )
         goto Bad;
 
       val = -( v - 251 ) * 256 - p[0] - 108;
@@ -244,10 +180,10 @@
 
   /* read a real */
   static FT_Fixed
-  cff_parse_real( CFF_Parser  parser,
-                  FT_Byte*    start,
-                  FT_Long     power_ten,
-                  FT_Long*    scaling )
+  cff_parse_real( FT_Byte*  start,
+                  FT_Byte*  limit,
+                  FT_Long   power_ten,
+                  FT_Long*  scaling )
   {
     FT_Byte*  p = start;
     FT_Int    nib;
@@ -282,7 +218,7 @@
         p++;
 
         /* Make sure we don't read past the end. */
-        if ( cff_parser_within_limits( parser, p, p ) )
+        if ( p + 1 > limit && limit >= p )
           goto Bad;
       }
 
@@ -319,7 +255,7 @@
           p++;
 
           /* Make sure we don't read past the end. */
-          if ( cff_parser_within_limits( parser, p, p ) )
+          if ( p + 1 > limit && limit >= p )
             goto Bad;
         }
 
@@ -358,7 +294,7 @@
           p++;
 
           /* Make sure we don't read past the end. */
-          if ( cff_parser_within_limits( parser, p, p ) )
+          if ( p + 1 > limit && limit >= p )
             goto Bad;
         }
 
@@ -525,7 +461,7 @@
     if ( **d == 30 )
     {
       /* binary-coded decimal is truncated to integer */
-      return cff_parse_real( parser, *d, 0, NULL ) >> 16;
+      return cff_parse_real( *d, parser->limit, 0, NULL ) >> 16;
     }
 
     else if ( **d == 255 )
@@ -551,7 +487,7 @@
     }
 
     else
-      return cff_parse_integer( parser, *d );
+      return cff_parse_integer( *d, parser->limit );
   }
 
 
@@ -562,16 +498,34 @@
             FT_Long     scaling )
   {
     if ( **d == 30 )
-      return cff_parse_real( parser, *d, scaling, NULL );
-    else
+      return cff_parse_real( *d, parser->limit, scaling, NULL );
+    else if ( **d == 255 )
     {
-      FT_Long  val = cff_parse_integer( parser, *d );
-
+      FT_Fixed val = ( ( ( (FT_UInt32)*( d[0] + 1 ) << 24 ) |
+                         ( (FT_UInt32)*( d[0] + 2 ) << 16 ) |
+                         ( (FT_UInt32)*( d[0] + 3 ) <<  8 ) |
+                           (FT_UInt32)*( d[0] + 4 )         ) );
 
       if ( scaling )
       {
         if ( FT_ABS( val ) > power_ten_limits[scaling] )
         {
+           FT_TRACE4(( "!!!OVERFLOW:!!!" ));
+           return val > 0 ? 0x7FFFFFFFL : -0x7FFFFFFFL;
+        }
+        val *= power_tens[scaling];
+      }
+      return val;
+    }
+    else
+    {
+      FT_Long  val = cff_parse_integer( *d, parser->limit );
+
+
+      if ( scaling )
+      {
+        if ( ( FT_ABS( val ) << 16 ) > power_ten_limits[scaling] )
+        {
           val = val > 0 ? 0x7FFFFFFFL : -0x7FFFFFFFL;
           goto Overflow;
         }
@@ -600,7 +554,7 @@
 
 
   /* read a floating point number, either integer or real */
-  static FT_Fixed
+  FT_LOCAL_DEF( FT_Fixed )
   cff_parse_fixed( CFF_Parser  parser,
                    FT_Byte**   d )
   {
@@ -630,14 +584,14 @@
     FT_ASSERT( scaling );
 
     if ( **d == 30 )
-      return cff_parse_real( parser, *d, 0, scaling );
+      return cff_parse_real( *d, parser->limit, 0, scaling );
     else
     {
       FT_Long  number;
       FT_Int   integer_length;
 
 
-      number = cff_parse_integer( parser, d[0] );
+      number = cff_parse_integer( *d, parser->limit );
 
       if ( number > 0x7FFFL )
       {
@@ -686,7 +640,7 @@
 
       dict->has_font_matrix = TRUE;
 
-      /* We expect a well-formed font matrix, this is, the matrix elements */
+      /* We expect a well-formed font matrix, that is, the matrix elements */
       /* `xx' and `yy' are of approximately the same magnitude.  To avoid  */
       /* loss of precision, we use the magnitude of the largest matrix     */
       /* element to scale all other elements.  The scaling factor is then  */
@@ -1264,11 +1218,8 @@
         FT_Byte*     charstring_base;
         FT_ULong     charstring_len;
 
-        FT_Fixed*      stack;
-        FT_ListNode    node;
-        CFF_T2_String  t2;
-        FT_Fixed       t2_size;
-        FT_Byte*       q;
+        FT_Fixed*  stack;
+        FT_Byte*   q = NULL;
 
 
         charstring_base = ++p;
@@ -1309,39 +1260,18 @@
         /* Now copy the stack data in the temporary decoder object,    */
         /* converting it back to charstring number representations     */
         /* (this is ugly, I know).                                     */
+        /* The maximum required size is 5 bytes per stack element.     */
+        if ( FT_QALLOC( q, (FT_Long)( 2 * sizeof ( FT_ListNode ) ) +
+                           5 * ( decoder.top - decoder.stack ) ) )
+          goto Exit;
 
-        node = (FT_ListNode)memory->alloc( memory,
-                                           sizeof ( FT_ListNodeRec ) );
-        if ( !node )
-          goto Out_Of_Memory_Error;
+        FT_List_Add( &parser->t2_strings, (FT_ListNode)q );
 
-        FT_List_Add( &parser->t2_strings, node );
+        q += 2 * sizeof ( FT_ListNode );
 
-        t2 = (CFF_T2_String)memory->alloc( memory,
-                                           sizeof ( CFF_T2_StringRec ) );
-        if ( !t2 )
-          goto Out_Of_Memory_Error;
-
-        node->data = t2;
-
-        /* `5' is the conservative upper bound of required bytes per stack */
-        /* element.                                                        */
-
-        t2_size = 5 * ( decoder.top - decoder.stack );
-
-        q = (FT_Byte*)memory->alloc( memory, t2_size );
-        if ( !q )
-          goto Out_Of_Memory_Error;
-
-        t2->start = q;
-        t2->limit = q + t2_size;
-
-        stack = decoder.stack;
-
-        while ( stack < decoder.top )
+        for ( stack = decoder.stack; stack < decoder.top; stack++ )
         {
-          FT_ULong  num;
-          FT_Bool   neg;
+          FT_Long  num = *stack;
 
 
           if ( (FT_UInt)( parser->top - parser->stack ) >= parser->stackSize )
@@ -1349,69 +1279,37 @@
 
           *parser->top++ = q;
 
-          if ( *stack < 0 )
-          {
-            num = (FT_ULong)NEG_LONG( *stack );
-            neg = 1;
-          }
-          else
-          {
-            num = (FT_ULong)*stack;
-            neg = 0;
-          }
-
           if ( num & 0xFFFFU )
           {
-            if ( neg )
-              num = (FT_ULong)-num;
-
             *q++ = 255;
-            *q++ = ( num & 0xFF000000U ) >> 24;
-            *q++ = ( num & 0x00FF0000U ) >> 16;
-            *q++ = ( num & 0x0000FF00U ) >>  8;
-            *q++ =   num & 0x000000FFU;
+            *q++ = (FT_Byte)( ( num >> 24 ) & 0xFF );
+            *q++ = (FT_Byte)( ( num >> 16 ) & 0xFF );
+            *q++ = (FT_Byte)( ( num >>  8 ) & 0xFF );
+            *q++ = (FT_Byte)( ( num       ) & 0xFF );
           }
           else
           {
             num >>= 16;
 
-            if ( neg )
+            if ( -107 <= num && num <= 107 )
+              *q++ = (FT_Byte)( num + 139 );
+            else if ( 108 <= num && num <= 1131 )
             {
-              if ( num <= 107 )
-                *q++ = (FT_Byte)( 139 - num );
-              else if ( num <= 1131 )
-              {
-                *q++ = (FT_Byte)( ( ( num - 108 ) >> 8 ) + 251 );
-                *q++ = (FT_Byte)( ( num - 108 ) & 0xFF );
-              }
-              else
-              {
-                num = (FT_ULong)-num;
-
-                *q++ = 28;
-                *q++ = (FT_Byte)( num >> 8 );
-                *q++ = (FT_Byte)( num & 0xFF );
-              }
+              *q++ = (FT_Byte)( ( ( num - 108 ) >> 8 ) + 247 );
+              *q++ = (FT_Byte)( ( num - 108 ) & 0xFF );
+            }
+            else if ( -1131 <= num && num <= -108 )
+            {
+              *q++ = (FT_Byte)( ( ( -num - 108 ) >> 8 ) + 251 );
+              *q++ = (FT_Byte)( ( -num - 108) & 0xFF );
             }
             else
             {
-              if ( num <= 107 )
-                *q++ = (FT_Byte)( num + 139 );
-              else if ( num <= 1131 )
-              {
-                *q++ = (FT_Byte)( ( ( num - 108 ) >> 8 ) + 247 );
-                *q++ = (FT_Byte)( ( num - 108 ) & 0xFF );
-              }
-              else
-              {
-                *q++ = 28;
-                *q++ = (FT_Byte)( num >> 8 );
-                *q++ = (FT_Byte)( num & 0xFF );
-              }
+              *q++ = 28;
+              *q++ = (FT_Byte)( num >> 8 );
+              *q++ = (FT_Byte)( num & 0xFF );
             }
           }
-
-          stack++;
         }
       }
 #endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
@@ -1598,12 +1496,6 @@
   Exit:
     return error;
 
-#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
-  Out_Of_Memory_Error:
-    error = FT_THROW( Out_Of_Memory );
-    goto Exit;
-#endif
-
   Stack_Overflow:
     error = FT_THROW( Invalid_Argument );
     goto Exit;
diff --git a/src/java.desktop/share/native/libfreetype/src/cff/cffparse.h b/src/java.desktop/share/native/libfreetype/src/cff/cffparse.h
index 58d59fa..418caac 100644
--- a/src/java.desktop/share/native/libfreetype/src/cff/cffparse.h
+++ b/src/java.desktop/share/native/libfreetype/src/cff/cffparse.h
@@ -76,6 +76,10 @@
   cff_parse_num( CFF_Parser  parser,
                  FT_Byte**   d );
 
+  FT_LOCAL( FT_Fixed )
+  cff_parse_fixed( CFF_Parser  parser,
+                   FT_Byte**   d );
+
   FT_LOCAL( FT_Error )
   cff_parser_init( CFF_Parser  parser,
                    FT_UInt     code,
@@ -133,15 +137,6 @@
 FT_END_HEADER
 
 
-#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
-  typedef struct  CFF_T2_String_
-  {
-    FT_Byte*  start;
-    FT_Byte*  limit;
-
-  } CFF_T2_StringRec, *CFF_T2_String;
-#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
-
 #endif /* CFFPARSE_H_ */
 
 
diff --git a/src/java.desktop/share/native/libfreetype/src/cid/cidgload.c b/src/java.desktop/share/native/libfreetype/src/cid/cidgload.c
index ba4b756..eaca765 100644
--- a/src/java.desktop/share/native/libfreetype/src/cid/cidgload.c
+++ b/src/java.desktop/share/native/libfreetype/src/cid/cidgload.c
@@ -40,6 +40,117 @@
 #define FT_COMPONENT  cidgload
 
 
+  /*
+   * A helper function to compute FD number (`fd_select`), the offset to the
+   * head of the glyph data (`off1`), and the offset to the and of the glyph
+   * data (`off2`).
+   *
+   * The number how many times `cid_get_offset` is invoked can be controlled
+   * by the number of non-NULL arguments.  If `fd_select` is non-NULL but
+   * `off1` and `off2` are NULL, `cid_get_offset` is invoked only for
+   * `fd_select`; `off1` and `off2` are not validated.
+   *
+   */
+  FT_LOCAL_DEF( FT_Error )
+  cid_compute_fd_and_offsets( CID_Face   face,
+                              FT_UInt    glyph_index,
+                              FT_ULong*  fd_select_p,
+                              FT_ULong*  off1_p,
+                              FT_ULong*  off2_p )
+  {
+    FT_Error  error = FT_Err_Ok;
+
+    CID_FaceInfo  cid       = &face->cid;
+    FT_Stream     stream    =  face->cid_stream;
+    FT_UInt       entry_len = cid->fd_bytes + cid->gd_bytes;
+
+    FT_Byte*  p;
+    FT_Bool   need_frame_exit = 0;
+    FT_ULong  fd_select, off1, off2;
+
+
+    /* For ordinary fonts, read the CID font dictionary index */
+    /* and charstring offset from the CIDMap.                 */
+
+    if ( FT_STREAM_SEEK( cid->data_offset + cid->cidmap_offset +
+                         glyph_index * entry_len )               ||
+         FT_FRAME_ENTER( 2 * entry_len )                         )
+      goto Exit;
+
+    need_frame_exit = 1;
+
+    p         = (FT_Byte*)stream->cursor;
+    fd_select = cid_get_offset( &p, cid->fd_bytes );
+    off1      = cid_get_offset( &p, cid->gd_bytes );
+
+    p    += cid->fd_bytes;
+    off2  = cid_get_offset( &p, cid->gd_bytes );
+
+    if ( fd_select_p )
+      *fd_select_p = fd_select;
+    if ( off1_p )
+      *off1_p = off1;
+    if ( off2_p )
+      *off2_p = off2;
+
+    if ( fd_select >= cid->num_dicts )
+    {
+      /*
+       * fd_select == 0xFF is often used to indicate that the CID
+       * has no charstring to be rendered, similar to GID = 0xFFFF
+       * in TrueType fonts.
+       */
+      if ( ( cid->fd_bytes == 1 && fd_select == 0xFFU   ) ||
+           ( cid->fd_bytes == 2 && fd_select == 0xFFFFU ) )
+      {
+        FT_TRACE1(( "cid_load_glyph: fail for glyph index %d:\n",
+                    glyph_index ));
+        FT_TRACE1(( "                FD number %ld is the maximum\n",
+                    fd_select ));
+        FT_TRACE1(( "                integer fitting into %d byte%s\n",
+                    cid->fd_bytes, cid->fd_bytes == 1 ? "" : "s" ));
+      }
+      else
+      {
+        FT_TRACE0(( "cid_load_glyph: fail for glyph index %d:\n",
+                    glyph_index ));
+        FT_TRACE0(( "                FD number %ld is larger\n",
+                    fd_select ));
+        FT_TRACE0(( "                than number of dictionaries (%d)\n",
+                    cid->num_dicts ));
+      }
+
+      error = FT_THROW( Invalid_Offset );
+      goto Exit;
+    }
+    else if ( off2 > stream->size )
+    {
+      FT_TRACE0(( "cid_load_glyph: fail for glyph index %d:\n",
+                  glyph_index ));
+      FT_TRACE0(( "               end of the glyph data\n" ));
+      FT_TRACE0(( "               is beyond the data stream\n" ));
+
+      error = FT_THROW( Invalid_Offset );
+      goto Exit;
+    }
+    else if ( off1 > off2 )
+    {
+      FT_TRACE0(( "cid_load_glyph: fail for glyph index %d:\n",
+                  glyph_index ));
+      FT_TRACE0(( "                the end position of glyph data\n" ));
+      FT_TRACE0(( "                is set before the start position\n" ));
+
+      error = FT_THROW( Invalid_Offset );
+    }
+
+    Exit:
+      if ( need_frame_exit )
+        FT_FRAME_EXIT();
+
+    return error;
+  }
+
+
   FT_CALLBACK_DEF( FT_Error )
   cid_load_glyph( T1_Decoder  decoder,
                   FT_UInt     glyph_index )
@@ -97,35 +208,15 @@
     else
 
 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
-
-    /* For ordinary fonts read the CID font dictionary index */
-    /* and charstring offset from the CIDMap.                */
     {
-      FT_UInt   entry_len = cid->fd_bytes + cid->gd_bytes;
       FT_ULong  off1, off2;
 
 
-      if ( FT_STREAM_SEEK( cid->data_offset + cid->cidmap_offset +
-                           glyph_index * entry_len )               ||
-           FT_FRAME_ENTER( 2 * entry_len )                         )
+      error = cid_compute_fd_and_offsets( face, glyph_index,
+                                          &fd_select, &off1, &off2 );
+      if ( error )
         goto Exit;
 
-      p         = (FT_Byte*)stream->cursor;
-      fd_select = cid_get_offset( &p, cid->fd_bytes );
-      off1      = cid_get_offset( &p, cid->gd_bytes );
-      p        += cid->fd_bytes;
-      off2      = cid_get_offset( &p, cid->gd_bytes );
-      FT_FRAME_EXIT();
-
-      if ( fd_select >= cid->num_dicts ||
-           off2 > stream->size         ||
-           off1 > off2                 )
-      {
-        FT_TRACE0(( "cid_load_glyph: invalid glyph stream offsets\n" ));
-        error = FT_THROW( Invalid_Offset );
-        goto Exit;
-      }
-
       glyph_length = off2 - off1;
 
       if ( glyph_length == 0                             ||
@@ -161,7 +252,9 @@
       cs_offset = decoder->lenIV >= 0 ? (FT_UInt)decoder->lenIV : 0;
       if ( cs_offset > glyph_length )
       {
-        FT_TRACE0(( "cid_load_glyph: invalid glyph stream offsets\n" ));
+        FT_TRACE0(( "cid_load_glyph: fail for glyph_index=%d, "
+                    "offset to the charstring is beyond glyph length\n",
+                    glyph_index ));
         error = FT_THROW( Invalid_Offset );
         goto Exit;
       }
diff --git a/src/java.desktop/share/native/libfreetype/src/cid/cidgload.h b/src/java.desktop/share/native/libfreetype/src/cid/cidgload.h
index 97954d4..edd6229 100644
--- a/src/java.desktop/share/native/libfreetype/src/cid/cidgload.h
+++ b/src/java.desktop/share/native/libfreetype/src/cid/cidgload.h
@@ -42,6 +42,14 @@
                        FT_Int32      load_flags );
 
 
+  FT_LOCAL( FT_Error )
+  cid_compute_fd_and_offsets( CID_Face   face,
+                              FT_UInt    glyph_index,
+                              FT_ULong*  fd_select_p,
+                              FT_ULong*  off1_p,
+                              FT_ULong*  off2_p );
+
+
 FT_END_HEADER
 
 #endif /* CIDGLOAD_H_ */
diff --git a/src/java.desktop/share/native/libfreetype/src/cid/cidload.c b/src/java.desktop/share/native/libfreetype/src/cid/cidload.c
index 26daa5d..a7da8ea 100644
--- a/src/java.desktop/share/native/libfreetype/src/cid/cidload.c
+++ b/src/java.desktop/share/native/libfreetype/src/cid/cidload.c
@@ -155,23 +155,24 @@
 
 
   FT_CALLBACK_DEF( void )
-  cid_parse_font_matrix( CID_Face     face,
-                         CID_Parser*  parser )
+  cid_parse_font_matrix( FT_Face  face,     /* CID_Face */
+                         void*    parser_ )
   {
+    CID_Face      cidface = (CID_Face)face;
+    CID_Parser*   parser  = (CID_Parser*)parser_;
     CID_FaceDict  dict;
-    FT_Face       root = (FT_Face)&face->root;
     FT_Fixed      temp[6];
     FT_Fixed      temp_scale;
 
 
-    if ( parser->num_dict < face->cid.num_dicts )
+    if ( parser->num_dict < cidface->cid.num_dicts )
     {
       FT_Matrix*  matrix;
       FT_Vector*  offset;
       FT_Int      result;
 
 
-      dict   = face->cid.font_dicts + parser->num_dict;
+      dict   = cidface->cid.font_dicts + parser->num_dict;
       matrix = &dict->font_matrix;
       offset = &dict->font_offset;
 
@@ -204,7 +205,7 @@
       if ( temp_scale != 0x10000L )
       {
         /* set units per EM based on FontMatrix values */
-        root->units_per_EM = (FT_UShort)FT_DivFix( 1000, temp_scale );
+        face->units_per_EM = (FT_UShort)FT_DivFix( 1000, temp_scale );
 
         temp[0] = FT_DivFix( temp[0], temp_scale );
         temp[1] = FT_DivFix( temp[1], temp_scale );
@@ -237,13 +238,15 @@
 
 
   FT_CALLBACK_DEF( void )
-  parse_fd_array( CID_Face     face,
-                  CID_Parser*  parser )
+  parse_fd_array( FT_Face  face,     /* CID_Face */
+                  void*    parser_ )
   {
-    CID_FaceInfo  cid    = &face->cid;
-    FT_Memory     memory = face->root.memory;
-    FT_Stream     stream = parser->stream;
-    FT_Error      error  = FT_Err_Ok;
+    CID_Face      cidface = (CID_Face)face;
+    CID_Parser*   parser  = (CID_Parser*)parser_;
+    CID_FaceInfo  cid     = &cidface->cid;
+    FT_Memory     memory  = FT_FACE_MEMORY( face );
+    FT_Stream     stream  = parser->stream;
+    FT_Error      error   = FT_Err_Ok;
     FT_Long       num_dicts, max_dicts;
 
 
@@ -313,18 +316,20 @@
 
   /* By mistake, `expansion_factor' appears both in PS_PrivateRec */
   /* and CID_FaceDictRec (both are public header files and can't  */
-  /* changed).  We simply copy the value.                         */
+  /* be thus changed).  We simply copy the value.                 */
 
   FT_CALLBACK_DEF( void )
-  parse_expansion_factor( CID_Face     face,
-                          CID_Parser*  parser )
+  parse_expansion_factor( FT_Face  face,    /* CID_Face */
+                          void*    parser_ )
   {
+    CID_Face      cidface = (CID_Face)face;
+    CID_Parser*   parser  = (CID_Parser*)parser_;
     CID_FaceDict  dict;
 
 
-    if ( parser->num_dict < face->cid.num_dicts )
+    if ( parser->num_dict < cidface->cid.num_dicts )
     {
-      dict = face->cid.font_dicts + parser->num_dict;
+      dict = cidface->cid.font_dicts + parser->num_dict;
 
       dict->expansion_factor              = cid_parser_to_fixed( parser, 0 );
       dict->private_dict.expansion_factor = dict->expansion_factor;
@@ -341,11 +346,15 @@
   /* to catch it for producing better trace output.                */
 
   FT_CALLBACK_DEF( void )
-  parse_font_name( CID_Face     face,
-                   CID_Parser*  parser )
+  parse_font_name( FT_Face  face,     /* CID_Face */
+                   void*    parser_ )
   {
 #ifdef FT_DEBUG_LEVEL_TRACE
-    if ( parser->num_dict < face->cid.num_dicts )
+    CID_Face      cidface = (CID_Face)face;
+    CID_Parser*   parser  = (CID_Parser*)parser_;
+
+
+    if ( parser->num_dict < cidface->cid.num_dicts )
     {
       T1_TokenRec  token;
       FT_UInt      len;
@@ -361,7 +370,7 @@
     }
 #else
     FT_UNUSED( face );
-    FT_UNUSED( parser );
+    FT_UNUSED( parser_ );
 #endif
 
     return;
diff --git a/src/java.desktop/share/native/libfreetype/src/cid/cidobjs.c b/src/java.desktop/share/native/libfreetype/src/cid/cidobjs.c
index 06b2139..f698a41 100644
--- a/src/java.desktop/share/native/libfreetype/src/cid/cidobjs.c
+++ b/src/java.desktop/share/native/libfreetype/src/cid/cidobjs.c
@@ -69,8 +69,7 @@
       FT_Module  module;
 
 
-      module = FT_Get_Module( slot->face->driver->root.library,
-                              "pshinter" );
+      module = FT_Get_Module( slot->library, "pshinter" );
       if ( module )
       {
         T1_Hints_Funcs  funcs;
@@ -268,7 +267,8 @@
    *
    * @Input:
    *   stream ::
-   *     The source font stream.
+   *     Dummy argument for compatibility with the `FT_Face_InitFunc` API.
+   *     Ignored.  The stream should be passed through `face->root.stream`.
    *
    *   face_index ::
    *     The index of the font face in the resource.
@@ -375,6 +375,14 @@
       if ( info->is_fixed_pitch )
         cidface->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
 
+      /*
+       * For the sfnt-wrapped CID fonts for MacOS, currently,
+       * its `cmap' tables are ignored, and the content in
+       * its `CID ' table is treated the same as naked CID-keyed
+       * font.  See ft_lookup_PS_in_sfnt_stream().
+       */
+      cidface->face_flags |= FT_FACE_FLAG_CID_KEYED;
+
       /* XXX: TODO: add kerning with .afm support */
 
       /* get style name -- be careful, some broken fonts only */
diff --git a/src/java.desktop/share/native/libfreetype/src/cid/cidparse.c b/src/java.desktop/share/native/libfreetype/src/cid/cidparse.c
index 16889db..171a886 100644
--- a/src/java.desktop/share/native/libfreetype/src/cid/cidparse.c
+++ b/src/java.desktop/share/native/libfreetype/src/cid/cidparse.c
@@ -214,18 +214,24 @@
            cur <= limit - STARTDATA_LEN                            &&
            ft_strncmp( (char*)cur, STARTDATA, STARTDATA_LEN ) == 0 )
       {
-        if ( ft_strncmp( (char*)arg1, "(Hex)", 5 ) == 0 )
+        T1_TokenRec  type_token;
+        FT_Long      binary_length;
+
+
+        parser->root.cursor = arg1;
+        cid_parser_to_token( parser, &type_token );
+        if ( type_token.limit - type_token.start == 5              &&
+             ft_memcmp( (char*)type_token.start, "(Hex)", 5 ) == 0 )
         {
-          FT_Long  tmp = ft_strtol( (const char *)arg2, NULL, 10 );
-
-
-          if ( tmp < 0 )
+          parser->root.cursor = arg2;
+          binary_length = cid_parser_to_int( parser );
+          if ( binary_length < 0 )
           {
             FT_ERROR(( "cid_parser_new: invalid length of hex data\n" ));
             error = FT_THROW( Invalid_File_Format );
           }
           else
-            parser->binary_length = (FT_ULong)tmp;
+            parser->binary_length = (FT_ULong)binary_length;
         }
 
         goto Exit;
diff --git a/src/java.desktop/share/native/libfreetype/src/cid/cidriver.c b/src/java.desktop/share/native/libfreetype/src/cid/cidriver.c
index f749923..99e7b11 100644
--- a/src/java.desktop/share/native/libfreetype/src/cid/cidriver.c
+++ b/src/java.desktop/share/native/libfreetype/src/cid/cidriver.c
@@ -48,10 +48,11 @@
    *
    */
 
-  static const char*
-  cid_get_postscript_name( CID_Face  face )
+  FT_CALLBACK_DEF( const char* )
+  cid_get_postscript_name( FT_Face  face )    /* CID_Face */
   {
-    const char*  result = face->cid.cid_font_name;
+    CID_Face     cidface = (CID_Face)face;
+    const char*  result  = cidface->cid.cid_font_name;
 
 
     if ( result && result[0] == '/' )
@@ -72,34 +73,36 @@
    *
    */
 
-  static FT_Error
-  cid_ps_get_font_info( FT_Face          face,
+  FT_CALLBACK_DEF( FT_Error )
+  cid_ps_get_font_info( FT_Face          face,        /* CID_Face */
                         PS_FontInfoRec*  afont_info )
   {
-    *afont_info = ((CID_Face)face)->cid.font_info;
+    *afont_info = ( (CID_Face)face )->cid.font_info;
 
     return FT_Err_Ok;
   }
 
-  static FT_Error
-  cid_ps_get_font_extra( FT_Face          face,
-                        PS_FontExtraRec*  afont_extra )
+
+  FT_CALLBACK_DEF( FT_Error )
+  cid_ps_get_font_extra( FT_Face           face,         /* CID_Face */
+                         PS_FontExtraRec*  afont_extra )
   {
-    *afont_extra = ((CID_Face)face)->font_extra;
+    *afont_extra = ( (CID_Face)face )->font_extra;
 
     return FT_Err_Ok;
   }
 
+
   static const FT_Service_PsInfoRec  cid_service_ps_info =
   {
-    (PS_GetFontInfoFunc)   cid_ps_get_font_info,   /* ps_get_font_info    */
-    (PS_GetFontExtraFunc)  cid_ps_get_font_extra,  /* ps_get_font_extra   */
+    cid_ps_get_font_info,   /* PS_GetFontInfoFunc    ps_get_font_info    */
+    cid_ps_get_font_extra,  /* PS_GetFontExtraFunc   ps_get_font_extra   */
     /* unsupported with CID fonts */
-    (PS_HasGlyphNamesFunc) NULL,                   /* ps_has_glyph_names  */
+    NULL,                   /* PS_HasGlyphNamesFunc  ps_has_glyph_names  */
     /* unsupported                */
-    (PS_GetFontPrivateFunc)NULL,                   /* ps_get_font_private */
+    NULL,                   /* PS_GetFontPrivateFunc ps_get_font_private */
     /* not implemented            */
-    (PS_GetFontValueFunc)  NULL                    /* ps_get_font_value   */
+    NULL                    /* PS_GetFontValueFunc   ps_get_font_value   */
   };
 
 
@@ -107,13 +110,14 @@
    * CID INFO SERVICE
    *
    */
-  static FT_Error
-  cid_get_ros( CID_Face      face,
+  FT_CALLBACK_DEF( FT_Error )
+  cid_get_ros( FT_Face       face,        /* CID_Face */
                const char*  *registry,
                const char*  *ordering,
                FT_Int       *supplement )
   {
-    CID_FaceInfo  cid = &face->cid;
+    CID_Face      cidface = (CID_Face)face;
+    CID_FaceInfo  cid     = &cidface->cid;
 
 
     if ( registry )
@@ -129,32 +133,48 @@
   }
 
 
-  static FT_Error
-  cid_get_is_cid( CID_Face  face,
+  FT_CALLBACK_DEF( FT_Error )
+  cid_get_is_cid( FT_Face   face,    /* CID_Face */
                   FT_Bool  *is_cid )
   {
     FT_Error  error = FT_Err_Ok;
     FT_UNUSED( face );
 
 
+    /*
+     * XXX: If the ROS is Adobe-Identity-H or -V,
+     * the font has no reliable information about
+     * its glyph collection.  Should we not set
+     * *is_cid in such cases?
+     */
     if ( is_cid )
-      *is_cid = 1; /* cid driver is only used for CID keyed fonts */
+      *is_cid = 1;
 
     return error;
   }
 
 
-  static FT_Error
-  cid_get_cid_from_glyph_index( CID_Face  face,
+  FT_CALLBACK_DEF( FT_Error )
+  cid_get_cid_from_glyph_index( FT_Face   face,        /* CID_Face */
                                 FT_UInt   glyph_index,
                                 FT_UInt  *cid )
   {
-    FT_Error  error = FT_Err_Ok;
-    FT_UNUSED( face );
+    FT_Error  error   = FT_Err_Ok;
+    CID_Face  cidface = (CID_Face)face;
 
 
-    if ( cid )
-      *cid = glyph_index; /* identity mapping */
+    /*
+     * Currently, FreeType does not support incrementally-defined, CID-keyed
+     * fonts that store the glyph description data in a `/GlyphDirectory`
+     * array or dictionary.  Fonts loaded by the incremental loading feature
+     * are thus not handled here.
+     */
+    error = cid_compute_fd_and_offsets( cidface, glyph_index,
+                                        NULL, NULL, NULL );
+    if ( error )
+      *cid = 0;
+    else
+      *cid = glyph_index;
 
     return error;
   }
@@ -162,12 +182,12 @@
 
   static const FT_Service_CIDRec  cid_service_cid_info =
   {
-    (FT_CID_GetRegistryOrderingSupplementFunc)
-      cid_get_ros,                             /* get_ros                  */
-    (FT_CID_GetIsInternallyCIDKeyedFunc)
-      cid_get_is_cid,                          /* get_is_cid               */
-    (FT_CID_GetCIDFromGlyphIndexFunc)
-      cid_get_cid_from_glyph_index             /* get_cid_from_glyph_index */
+    cid_get_ros,
+      /* FT_CID_GetRegistryOrderingSupplementFunc get_ros                  */
+    cid_get_is_cid,
+      /* FT_CID_GetIsInternallyCIDKeyedFunc       get_is_cid               */
+    cid_get_cid_from_glyph_index
+      /* FT_CID_GetCIDFromGlyphIndexFunc          get_cid_from_glyph_index */
   };
 
 
@@ -179,9 +199,9 @@
   FT_DEFINE_SERVICE_PROPERTIESREC(
     cid_service_properties,
 
-    (FT_Properties_SetFunc)ps_property_set,      /* set_property */
-    (FT_Properties_GetFunc)ps_property_get )     /* get_property */
-
+    ps_property_set,  /* FT_Properties_SetFunc set_property */
+    ps_property_get   /* FT_Properties_GetFunc get_property */
+  )
 
   /*
    * SERVICE LIST
@@ -209,7 +229,6 @@
   }
 
 
-
   FT_CALLBACK_TABLE_DEF
   const FT_Driver_ClassRec  t1cid_driver_class =
   {
diff --git a/src/java.desktop/share/native/libfreetype/src/psaux/afmparse.c b/src/java.desktop/share/native/libfreetype/src/psaux/afmparse.c
index 68f9569..db08941 100644
--- a/src/java.desktop/share/native/libfreetype/src/psaux/afmparse.c
+++ b/src/java.desktop/share/native/libfreetype/src/psaux/afmparse.c
@@ -1086,7 +1086,7 @@
 #else /* T1_CONFIG_OPTION_NO_AFM */
 
   /* ANSI C doesn't like empty source files */
-  typedef int  _afm_parse_dummy;
+  typedef int  afm_parse_dummy_;
 
 #endif /* T1_CONFIG_OPTION_NO_AFM */
 
diff --git a/src/java.desktop/share/native/libfreetype/src/psaux/cffdecode.c b/src/java.desktop/share/native/libfreetype/src/psaux/cffdecode.c
index 2cd91c9..562d17d 100644
--- a/src/java.desktop/share/native/libfreetype/src/psaux/cffdecode.c
+++ b/src/java.desktop/share/native/libfreetype/src/psaux/cffdecode.c
@@ -2153,7 +2153,7 @@
                                       decoder->locals_bias );
 
 
-            FT_TRACE4(( " callsubr (idx %d, entering level %ld)\n",
+            FT_TRACE4(( " callsubr (idx %d, entering level %td)\n",
                         idx,
                         zone - decoder->zones + 1 ));
 
@@ -2197,7 +2197,7 @@
                                       decoder->globals_bias );
 
 
-            FT_TRACE4(( " callgsubr (idx %d, entering level %ld)\n",
+            FT_TRACE4(( " callgsubr (idx %d, entering level %td)\n",
                         idx,
                         zone - decoder->zones + 1 ));
 
@@ -2236,7 +2236,7 @@
           break;
 
         case cff_op_return:
-          FT_TRACE4(( " return (leaving level %ld)\n",
+          FT_TRACE4(( " return (leaving level %td)\n",
                       decoder->zone - decoder->zones ));
 
           if ( decoder->zone <= decoder->zones )
diff --git a/src/java.desktop/share/native/libfreetype/src/psaux/pshints.c b/src/java.desktop/share/native/libfreetype/src/psaux/pshints.c
index 6f44d0a..7bd08a9 100644
--- a/src/java.desktop/share/native/libfreetype/src/psaux/pshints.c
+++ b/src/java.desktop/share/native/libfreetype/src/psaux/pshints.c
@@ -310,7 +310,7 @@
       CF2_Hint  hint = &hintmap->edge[i];
 
 
-      FT_TRACE6(( "  %3ld    %7.2f  %7.2f  %5d  %s%s%s%s\n",
+      FT_TRACE6(( "  %3zu    %7.2f  %7.2f  %5d  %s%s%s%s\n",
                   hint->index,
                   hint->csCoord / 65536.0,
                   hint->dsCoord / ( hint->scale * 1.0 ),
diff --git a/src/java.desktop/share/native/libfreetype/src/psaux/t1cmap.c b/src/java.desktop/share/native/libfreetype/src/psaux/t1cmap.c
index bf0a393..c4bcf59 100644
--- a/src/java.desktop/share/native/libfreetype/src/psaux/t1cmap.c
+++ b/src/java.desktop/share/native/libfreetype/src/psaux/t1cmap.c
@@ -50,8 +50,11 @@
 
 
   FT_CALLBACK_DEF( void )
-  t1_cmap_std_done( T1_CMapStd  cmap )
+  t1_cmap_std_done( FT_CMap  cmap_ )   /* T1_CMapStd */
   {
+    T1_CMapStd  cmap = (T1_CMapStd)cmap_;
+
+
     cmap->num_glyphs    = 0;
     cmap->glyph_names   = NULL;
     cmap->sid_to_string = NULL;
@@ -60,10 +63,11 @@
 
 
   FT_CALLBACK_DEF( FT_UInt )
-  t1_cmap_std_char_index( T1_CMapStd  cmap,
-                          FT_UInt32   char_code )
+  t1_cmap_std_char_index( FT_CMap    cmap,       /* T1_CMapStd */
+                          FT_UInt32  char_code )
   {
-    FT_UInt  result = 0;
+    T1_CMapStd  t1cmap = (T1_CMapStd)cmap;
+    FT_UInt     result = 0;
 
 
     if ( char_code < 256 )
@@ -73,13 +77,13 @@
 
 
       /* convert character code to Adobe SID string */
-      code       = cmap->code_to_sid[char_code];
-      glyph_name = cmap->sid_to_string( code );
+      code       = t1cmap->code_to_sid[char_code];
+      glyph_name = t1cmap->sid_to_string( code );
 
       /* look for the corresponding glyph name */
-      for ( n = 0; n < cmap->num_glyphs; n++ )
+      for ( n = 0; n < t1cmap->num_glyphs; n++ )
       {
-        const char* gname = cmap->glyph_names[n];
+        const char* gname = t1cmap->glyph_names[n];
 
 
         if ( gname && gname[0] == glyph_name[0]  &&
@@ -95,9 +99,9 @@
   }
 
 
-  FT_CALLBACK_DEF( FT_UInt32 )
-  t1_cmap_std_char_next( T1_CMapStd   cmap,
-                         FT_UInt32   *pchar_code )
+  FT_CALLBACK_DEF( FT_UInt )
+  t1_cmap_std_char_next( FT_CMap     cmap,
+                         FT_UInt32  *pchar_code )
   {
     FT_UInt    result    = 0;
     FT_UInt32  char_code = *pchar_code + 1;
@@ -120,13 +124,14 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  t1_cmap_standard_init( T1_CMapStd  cmap,
+  t1_cmap_standard_init( FT_CMap     cmap,     /* T1_CMapStd */
                          FT_Pointer  pointer )
   {
+    T1_CMapStd  t1cmap = (T1_CMapStd)cmap;
     FT_UNUSED( pointer );
 
 
-    t1_cmap_std_init( cmap, 0 );
+    t1_cmap_std_init( t1cmap, 0 );
     return 0;
   }
 
@@ -150,13 +155,14 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  t1_cmap_expert_init( T1_CMapStd  cmap,
+  t1_cmap_expert_init( FT_CMap     cmap,     /* T1_CMapStd */
                        FT_Pointer  pointer )
   {
+    T1_CMapStd  t1cmap = (T1_CMapStd)cmap;
     FT_UNUSED( pointer );
 
 
-    t1_cmap_std_init( cmap, 1 );
+    t1_cmap_std_init( t1cmap, 1 );
     return 0;
   }
 
@@ -188,20 +194,21 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  t1_cmap_custom_init( T1_CMapCustom  cmap,
-                       FT_Pointer     pointer )
+  t1_cmap_custom_init( FT_CMap     cmap,     /* T1_CMapCustom */
+                       FT_Pointer  pointer )
   {
-    T1_Face      face     = (T1_Face)FT_CMAP_FACE( cmap );
-    T1_Encoding  encoding = &face->type1.encoding;
+    T1_CMapCustom  t1cmap   = (T1_CMapCustom)cmap;
+    T1_Face        face     = (T1_Face)FT_CMAP_FACE( cmap );
+    T1_Encoding    encoding = &face->type1.encoding;
 
     FT_UNUSED( pointer );
 
 
-    cmap->first   = (FT_UInt)encoding->code_first;
-    cmap->count   = (FT_UInt)encoding->code_last - cmap->first;
-    cmap->indices = encoding->char_index;
+    t1cmap->first   = (FT_UInt)encoding->code_first;
+    t1cmap->count   = (FT_UInt)encoding->code_last - t1cmap->first;
+    t1cmap->indices = encoding->char_index;
 
-    FT_ASSERT( cmap->indices );
+    FT_ASSERT( t1cmap->indices );
     FT_ASSERT( encoding->code_first <= encoding->code_last );
 
     return 0;
@@ -209,45 +216,50 @@
 
 
   FT_CALLBACK_DEF( void )
-  t1_cmap_custom_done( T1_CMapCustom  cmap )
+  t1_cmap_custom_done( FT_CMap  cmap )   /* T1_CMapCustom */
   {
-    cmap->indices = NULL;
-    cmap->first   = 0;
-    cmap->count   = 0;
+    T1_CMapCustom  t1cmap = (T1_CMapCustom)cmap;
+
+
+    t1cmap->indices = NULL;
+    t1cmap->first   = 0;
+    t1cmap->count   = 0;
   }
 
 
   FT_CALLBACK_DEF( FT_UInt )
-  t1_cmap_custom_char_index( T1_CMapCustom  cmap,
-                             FT_UInt32      char_code )
+  t1_cmap_custom_char_index( FT_CMap    cmap,       /* T1_CMapCustom */
+                             FT_UInt32  char_code )
   {
-    FT_UInt    result = 0;
+    T1_CMapCustom  t1cmap = (T1_CMapCustom)cmap;
+    FT_UInt        result = 0;
 
 
-    if ( ( char_code >= cmap->first )                  &&
-         ( char_code < ( cmap->first + cmap->count ) ) )
-      result = cmap->indices[char_code];
+    if ( char_code >= t1cmap->first                    &&
+         char_code < ( t1cmap->first + t1cmap->count ) )
+      result = t1cmap->indices[char_code];
 
     return result;
   }
 
 
-  FT_CALLBACK_DEF( FT_UInt32 )
-  t1_cmap_custom_char_next( T1_CMapCustom  cmap,
-                            FT_UInt32     *pchar_code )
+  FT_CALLBACK_DEF( FT_UInt )
+  t1_cmap_custom_char_next( FT_CMap     cmap,        /* T1_CMapCustom */
+                            FT_UInt32  *pchar_code )
   {
-    FT_UInt    result = 0;
-    FT_UInt32  char_code = *pchar_code;
+    T1_CMapCustom  t1cmap    = (T1_CMapCustom)cmap;
+    FT_UInt        result    = 0;
+    FT_UInt32      char_code = *pchar_code;
 
 
     char_code++;
 
-    if ( char_code < cmap->first )
-      char_code = cmap->first;
+    if ( char_code < t1cmap->first )
+      char_code = t1cmap->first;
 
-    for ( ; char_code < ( cmap->first + cmap->count ); char_code++ )
+    for ( ; char_code < ( t1cmap->first + t1cmap->count ); char_code++ )
     {
-      result = cmap->indices[char_code];
+      result = t1cmap->indices[char_code];
       if ( result != 0 )
         goto Exit;
     }
@@ -287,20 +299,24 @@
   /*************************************************************************/
 
   FT_CALLBACK_DEF( const char * )
-  psaux_get_glyph_name( T1_Face  face,
+  psaux_get_glyph_name( void*    face_,
                         FT_UInt  idx )
   {
+    T1_Face  face = (T1_Face)face_;
+
+
     return face->type1.glyph_names[idx];
   }
 
 
   FT_CALLBACK_DEF( FT_Error )
-  t1_cmap_unicode_init( PS_Unicodes  unicodes,
-                        FT_Pointer   pointer )
+  t1_cmap_unicode_init( FT_CMap     cmap,     /* PS_Unicodes */
+                        FT_Pointer  pointer )
   {
-    T1_Face             face    = (T1_Face)FT_CMAP_FACE( unicodes );
-    FT_Memory           memory  = FT_FACE_MEMORY( face );
-    FT_Service_PsCMaps  psnames = (FT_Service_PsCMaps)face->psnames;
+    PS_Unicodes         unicodes = (PS_Unicodes)cmap;
+    T1_Face             face     = (T1_Face)FT_CMAP_FACE( cmap );
+    FT_Memory           memory   = FT_FACE_MEMORY( face );
+    FT_Service_PsCMaps  psnames  = (FT_Service_PsCMaps)face->psnames;
 
     FT_UNUSED( pointer );
 
@@ -311,17 +327,18 @@
     return psnames->unicodes_init( memory,
                                    unicodes,
                                    (FT_UInt)face->type1.num_glyphs,
-                                   (PS_GetGlyphNameFunc)&psaux_get_glyph_name,
+                                   &psaux_get_glyph_name,
                                    (PS_FreeGlyphNameFunc)NULL,
                                    (FT_Pointer)face );
   }
 
 
   FT_CALLBACK_DEF( void )
-  t1_cmap_unicode_done( PS_Unicodes  unicodes )
+  t1_cmap_unicode_done( FT_CMap  cmap )   /* PS_Unicodes */
   {
-    FT_Face    face   = FT_CMAP_FACE( unicodes );
-    FT_Memory  memory = FT_FACE_MEMORY( face );
+    PS_Unicodes  unicodes = (PS_Unicodes)cmap;
+    FT_Face      face     = FT_CMAP_FACE( cmap );
+    FT_Memory    memory   = FT_FACE_MEMORY( face );
 
 
     FT_FREE( unicodes->maps );
@@ -330,23 +347,25 @@
 
 
   FT_CALLBACK_DEF( FT_UInt )
-  t1_cmap_unicode_char_index( PS_Unicodes  unicodes,
-                              FT_UInt32    char_code )
+  t1_cmap_unicode_char_index( FT_CMap    cmap,       /* PS_Unicodes */
+                              FT_UInt32  char_code )
   {
-    T1_Face             face    = (T1_Face)FT_CMAP_FACE( unicodes );
-    FT_Service_PsCMaps  psnames = (FT_Service_PsCMaps)face->psnames;
+    PS_Unicodes         unicodes = (PS_Unicodes)cmap;
+    T1_Face             face     = (T1_Face)FT_CMAP_FACE( cmap );
+    FT_Service_PsCMaps  psnames  = (FT_Service_PsCMaps)face->psnames;
 
 
     return psnames->unicodes_char_index( unicodes, char_code );
   }
 
 
-  FT_CALLBACK_DEF( FT_UInt32 )
-  t1_cmap_unicode_char_next( PS_Unicodes  unicodes,
-                             FT_UInt32   *pchar_code )
+  FT_CALLBACK_DEF( FT_UInt )
+  t1_cmap_unicode_char_next( FT_CMap     cmap,        /* PS_Unicodes */
+                             FT_UInt32  *pchar_code )
   {
-    T1_Face             face    = (T1_Face)FT_CMAP_FACE( unicodes );
-    FT_Service_PsCMaps  psnames = (FT_Service_PsCMaps)face->psnames;
+    PS_Unicodes         unicodes = (PS_Unicodes)cmap;
+    T1_Face             face     = (T1_Face)FT_CMAP_FACE( cmap );
+    FT_Service_PsCMaps  psnames  = (FT_Service_PsCMaps)face->psnames;
 
 
     return psnames->unicodes_char_next( unicodes, pchar_code );
diff --git a/src/java.desktop/share/native/libfreetype/src/psaux/t1decode.c b/src/java.desktop/share/native/libfreetype/src/psaux/t1decode.c
index bfed45b..4b6b969 100644
--- a/src/java.desktop/share/native/libfreetype/src/psaux/t1decode.c
+++ b/src/java.desktop/share/native/libfreetype/src/psaux/t1decode.c
@@ -520,7 +520,7 @@
 #ifdef FT_DEBUG_LEVEL_TRACE
       if ( bol )
       {
-        FT_TRACE5(( " (%ld)", decoder->top - decoder->stack ));
+        FT_TRACE5(( " (%td)", decoder->top - decoder->stack ));
         bol = FALSE;
       }
 #endif
@@ -1165,7 +1165,7 @@
           if ( top - decoder->stack != num_args )
             FT_TRACE0(( "t1_decoder_parse_charstrings:"
                         " too much operands on the stack"
-                        " (seen %ld, expected %d)\n",
+                        " (seen %td, expected %d)\n",
                         top - decoder->stack, num_args ));
           break;
         }
diff --git a/src/java.desktop/share/native/libfreetype/src/pshinter/pshalgo.c b/src/java.desktop/share/native/libfreetype/src/pshinter/pshalgo.c
index a7f3212..4f622e1 100644
--- a/src/java.desktop/share/native/libfreetype/src/pshinter/pshalgo.c
+++ b/src/java.desktop/share/native/libfreetype/src/pshinter/pshalgo.c
@@ -516,7 +516,7 @@
             if ( !psh_hint_is_fitted( parent ) )
               psh_hint_align( parent, globals, dimension, glyph );
 
-            /* keep original relation between hints, this is, use the */
+            /* keep original relation between hints, that is, use the */
             /* scaled distance between the centers of the hints to    */
             /* compute the new position                               */
             par_org_center = parent->org_pos + ( parent->org_len >> 1 );
diff --git a/src/java.desktop/share/native/libfreetype/src/pshinter/pshmod.c b/src/java.desktop/share/native/libfreetype/src/pshinter/pshmod.c
index a12e485..974a99e 100644
--- a/src/java.desktop/share/native/libfreetype/src/pshinter/pshmod.c
+++ b/src/java.desktop/share/native/libfreetype/src/pshinter/pshmod.c
@@ -37,8 +37,11 @@
 
   /* finalize module */
   FT_CALLBACK_DEF( void )
-  ps_hinter_done( PS_Hinter_Module  module )
+  ps_hinter_done( FT_Module  module_ )    /* PS_Hinter_Module */
   {
+    PS_Hinter_Module  module = (PS_Hinter_Module)module_;
+
+
     module->t1_funcs.hints = NULL;
     module->t2_funcs.hints = NULL;
 
@@ -48,8 +51,10 @@
 
   /* initialize module, create hints recorder and the interface */
   FT_CALLBACK_DEF( FT_Error )
-  ps_hinter_init( PS_Hinter_Module  module )
+  ps_hinter_init( FT_Module  module_ )    /* PS_Hinter_Module */
   {
+    PS_Hinter_Module  module = (PS_Hinter_Module)module_;
+
     FT_Memory  memory = module->root.memory;
     void*      ph     = &module->ps_hints;
 
diff --git a/src/java.desktop/share/native/libfreetype/src/pshinter/pshrec.c b/src/java.desktop/share/native/libfreetype/src/pshinter/pshrec.c
index 58c8cf1..680e6d0 100644
--- a/src/java.desktop/share/native/libfreetype/src/pshinter/pshrec.c
+++ b/src/java.desktop/share/native/libfreetype/src/pshinter/pshrec.c
@@ -851,10 +851,11 @@
 
   /* add one Type1 counter stem to the current hints table */
   static void
-  ps_hints_t1stem3( PS_Hints   hints,
+  ps_hints_t1stem3( T1_Hints   hints_,    /* PS_Hints */
                     FT_UInt    dimension,
                     FT_Fixed*  stems )
   {
+    PS_Hints  hints = (PS_Hints)hints_;
     FT_Error  error = FT_Err_Ok;
 
 
@@ -914,9 +915,10 @@
 
   /* reset hints (only with Type 1 hints) */
   static void
-  ps_hints_t1reset( PS_Hints  hints,
+  ps_hints_t1reset( T1_Hints  hints_,     /* PS_Hints */
                     FT_UInt   end_point )
   {
+    PS_Hints  hints = (PS_Hints)hints_;
     FT_Error  error = FT_Err_Ok;
 
 
@@ -953,11 +955,12 @@
 
   /* Type2 "hintmask" operator, add a new hintmask to each direction */
   static void
-  ps_hints_t2mask( PS_Hints        hints,
+  ps_hints_t2mask( T2_Hints        hints_,    /* PS_Hints */
                    FT_UInt         end_point,
                    FT_UInt         bit_count,
                    const FT_Byte*  bytes )
   {
+    PS_Hints  hints = (PS_Hints)hints_;
     FT_Error  error;
 
 
@@ -999,10 +1002,11 @@
 
 
   static void
-  ps_hints_t2counter( PS_Hints        hints,
+  ps_hints_t2counter( T2_Hints        hints_,    /* PS_Hints */
                       FT_UInt         bit_count,
                       const FT_Byte*  bytes )
   {
+    PS_Hints  hints = (PS_Hints)hints_;
     FT_Error  error;
 
 
@@ -1087,6 +1091,13 @@
     ps_hints_open( (PS_Hints)hints, PS_HINT_TYPE_1 );
   }
 
+  static FT_Error
+  t1_hints_close( T1_Hints  hints,
+                  FT_UInt   end_point )
+  {
+    return ps_hints_close( (PS_Hints)hints, end_point );
+  }
+
   static void
   t1_hints_stem( T1_Hints   hints,
                  FT_UInt    dimension,
@@ -1102,17 +1113,27 @@
   }
 
 
+  static FT_Error
+  t1_hints_apply( T1_Hints        hints,
+                  FT_Outline*     outline,
+                  PSH_Globals     globals,
+                  FT_Render_Mode  hint_mode )
+  {
+    return ps_hints_apply( (PS_Hints)hints, outline, globals, hint_mode );
+  }
+
+
   FT_LOCAL_DEF( void )
   t1_hints_funcs_init( T1_Hints_FuncsRec*  funcs )
   {
     FT_ZERO( funcs );
 
     funcs->open  = (T1_Hints_OpenFunc)    t1_hints_open;
-    funcs->close = (T1_Hints_CloseFunc)   ps_hints_close;
+    funcs->close = (T1_Hints_CloseFunc)   t1_hints_close;
     funcs->stem  = (T1_Hints_SetStemFunc) t1_hints_stem;
     funcs->stem3 = (T1_Hints_SetStem3Func)ps_hints_t1stem3;
     funcs->reset = (T1_Hints_ResetFunc)   ps_hints_t1reset;
-    funcs->apply = (T1_Hints_ApplyFunc)   ps_hints_apply;
+    funcs->apply = (T1_Hints_ApplyFunc)   t1_hints_apply;
   }
 
 
@@ -1131,6 +1152,14 @@
   }
 
 
+  static FT_Error
+  t2_hints_close( T2_Hints  hints,
+                  FT_UInt   end_point )
+  {
+    return ps_hints_close( (PS_Hints)hints, end_point );
+  }
+
+
   static void
   t2_hints_stems( T2_Hints   hints,
                   FT_UInt    dimension,
@@ -1168,17 +1197,27 @@
   }
 
 
+  static FT_Error
+  t2_hints_apply( T2_Hints        hints,
+                  FT_Outline*     outline,
+                  PSH_Globals     globals,
+                  FT_Render_Mode  hint_mode )
+  {
+    return ps_hints_apply( (PS_Hints)hints, outline, globals, hint_mode );
+  }
+
+
   FT_LOCAL_DEF( void )
   t2_hints_funcs_init( T2_Hints_FuncsRec*  funcs )
   {
     FT_ZERO( funcs );
 
-    funcs->open    = (T2_Hints_OpenFunc)   t2_hints_open;
-    funcs->close   = (T2_Hints_CloseFunc)  ps_hints_close;
-    funcs->stems   = (T2_Hints_StemsFunc)  t2_hints_stems;
-    funcs->hintmask= (T2_Hints_MaskFunc)   ps_hints_t2mask;
-    funcs->counter = (T2_Hints_CounterFunc)ps_hints_t2counter;
-    funcs->apply   = (T2_Hints_ApplyFunc)  ps_hints_apply;
+    funcs->open     = (T2_Hints_OpenFunc)   t2_hints_open;
+    funcs->close    = (T2_Hints_CloseFunc)  t2_hints_close;
+    funcs->stems    = (T2_Hints_StemsFunc)  t2_hints_stems;
+    funcs->hintmask = (T2_Hints_MaskFunc)   ps_hints_t2mask;
+    funcs->counter  = (T2_Hints_CounterFunc)ps_hints_t2counter;
+    funcs->apply    = (T2_Hints_ApplyFunc)  t2_hints_apply;
   }
 
 
diff --git a/src/java.desktop/share/native/libfreetype/src/psnames/psmodule.c b/src/java.desktop/share/native/libfreetype/src/psnames/psmodule.c
index db454e5..8203a04 100644
--- a/src/java.desktop/share/native/libfreetype/src/psnames/psmodule.c
+++ b/src/java.desktop/share/native/libfreetype/src/psnames/psmodule.c
@@ -57,7 +57,7 @@
   /* the name, as in `A.swash' or `e.final'; in this case, the           */
   /* VARIANT_BIT is set in the return value.                             */
   /*                                                                     */
-  static FT_UInt32
+  FT_CALLBACK_DEF( FT_UInt32 )
   ps_unicode_value( const char*  glyph_name )
   {
     /* If the name begins with `uni', then the glyph name may be a */
@@ -309,7 +309,7 @@
 
 
   /* Build a table that maps Unicode values to glyph indices. */
-  static FT_Error
+  FT_CALLBACK_DEF( FT_Error )
   ps_unicodes_init( FT_Memory             memory,
                     PS_Unicodes           table,
                     FT_UInt               num_glyphs,
@@ -408,7 +408,7 @@
   }
 
 
-  static FT_UInt
+  FT_CALLBACK_DEF( FT_UInt )
   ps_unicodes_char_index( PS_Unicodes  table,
                           FT_UInt32    unicode )
   {
@@ -453,7 +453,7 @@
   }
 
 
-  static FT_UInt32
+  FT_CALLBACK_DEF( FT_UInt )
   ps_unicodes_char_next( PS_Unicodes  table,
                          FT_UInt32   *unicode )
   {
@@ -518,7 +518,7 @@
 #endif /* FT_CONFIG_OPTION_ADOBE_GLYPH_LIST */
 
 
-  static const char*
+  FT_CALLBACK_DEF( const char* )
   ps_get_macintosh_name( FT_UInt  name_index )
   {
     if ( name_index >= FT_NUM_MAC_NAMES )
@@ -528,7 +528,7 @@
   }
 
 
-  static const char*
+  FT_CALLBACK_DEF( const char* )
   ps_get_standard_strings( FT_UInt  sid )
   {
     if ( sid >= FT_NUM_SID_NAMES )
@@ -543,13 +543,13 @@
   FT_DEFINE_SERVICE_PSCMAPSREC(
     pscmaps_interface,
 
-    (PS_Unicode_ValueFunc)     ps_unicode_value,        /* unicode_value         */
-    (PS_Unicodes_InitFunc)     ps_unicodes_init,        /* unicodes_init         */
-    (PS_Unicodes_CharIndexFunc)ps_unicodes_char_index,  /* unicodes_char_index   */
-    (PS_Unicodes_CharNextFunc) ps_unicodes_char_next,   /* unicodes_char_next    */
+    ps_unicode_value,         /* PS_Unicode_ValueFunc      unicode_value         */
+    ps_unicodes_init,         /* PS_Unicodes_InitFunc      unicodes_init         */
+    ps_unicodes_char_index,   /* PS_Unicodes_CharIndexFunc unicodes_char_index   */
+    ps_unicodes_char_next,    /* PS_Unicodes_CharNextFunc  unicodes_char_next    */
 
-    (PS_Macintosh_NameFunc)    ps_get_macintosh_name,   /* macintosh_name        */
-    (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, /* adobe_std_strings     */
+    ps_get_macintosh_name,    /* PS_Macintosh_NameFunc     macintosh_name        */
+    ps_get_standard_strings,  /* PS_Adobe_Std_StringsFunc  adobe_std_strings     */
 
     t1_standard_encoding,                               /* adobe_std_encoding    */
     t1_expert_encoding                                  /* adobe_expert_encoding */
@@ -560,13 +560,13 @@
   FT_DEFINE_SERVICE_PSCMAPSREC(
     pscmaps_interface,
 
-    NULL,                                               /* unicode_value         */
-    NULL,                                               /* unicodes_init         */
-    NULL,                                               /* unicodes_char_index   */
-    NULL,                                               /* unicodes_char_next    */
+    NULL,                     /* PS_Unicode_ValueFunc      unicode_value         */
+    NULL,                     /* PS_Unicodes_InitFunc      unicodes_init         */
+    NULL,                     /* PS_Unicodes_CharIndexFunc unicodes_char_index   */
+    NULL,                     /* PS_Unicodes_CharNextFunc  unicodes_char_next    */
 
-    (PS_Macintosh_NameFunc)    ps_get_macintosh_name,   /* macintosh_name        */
-    (PS_Adobe_Std_StringsFunc) ps_get_standard_strings, /* adobe_std_strings     */
+    ps_get_macintosh_name,    /* PS_Macintosh_NameFunc     macintosh_name        */
+    ps_get_standard_strings,  /* PS_Adobe_Std_StringsFunc  adobe_std_strings     */
 
     t1_standard_encoding,                               /* adobe_std_encoding    */
     t1_expert_encoding                                  /* adobe_expert_encoding */
@@ -612,9 +612,9 @@
     PUT_PS_NAMES_SERVICE(
       (void*)&pscmaps_interface ),   /* module specific interface */
 
-    (FT_Module_Constructor)NULL,                                       /* module_init   */
-    (FT_Module_Destructor) NULL,                                       /* module_done   */
-    (FT_Module_Requester)  PUT_PS_NAMES_SERVICE( psnames_get_service ) /* get_interface */
+    NULL,                                        /* FT_Module_Constructor module_init   */
+    NULL,                                        /* FT_Module_Destructor  module_done   */
+    PUT_PS_NAMES_SERVICE( psnames_get_service )  /* FT_Module_Requester   get_interface */
   )
 
 
diff --git a/src/java.desktop/share/native/libfreetype/src/raster/ftraster.c b/src/java.desktop/share/native/libfreetype/src/raster/ftraster.c
index 67cbfd5..192ca07 100644
--- a/src/java.desktop/share/native/libfreetype/src/raster/ftraster.c
+++ b/src/java.desktop/share/native/libfreetype/src/raster/ftraster.c
@@ -1742,9 +1742,9 @@
    *   SUCCESS on success, FAILURE on error.
    */
   static Bool
-  Decompose_Curve( RAS_ARGS UShort  first,
-                            UShort  last,
-                            Int     flipped )
+  Decompose_Curve( RAS_ARGS Int  first,
+                            Int  last,
+                            Int  flipped )
   {
     FT_Vector   v_last;
     FT_Vector   v_control;
@@ -1969,8 +1969,8 @@
   static Bool
   Convert_Glyph( RAS_ARGS Int  flipped )
   {
-    Int   i;
-    UInt  start;
+    Int  i;
+    Int  first, last;
 
 
     ras.fProfile = NULL;
@@ -1985,8 +1985,7 @@
     ras.cProfile->offset = ras.top;
     ras.num_Profs        = 0;
 
-    start = 0;
-
+    last = -1;
     for ( i = 0; i < ras.outline.n_contours; i++ )
     {
       PProfile  lastProfile;
@@ -1996,12 +1995,11 @@
       ras.state    = Unknown_State;
       ras.gProfile = NULL;
 
-      if ( Decompose_Curve( RAS_VARS (UShort)start,
-                                     (UShort)ras.outline.contours[i],
-                                     flipped ) )
-        return FAILURE;
+      first = last + 1;
+      last  = ras.outline.contours[i];
 
-      start = (UShort)ras.outline.contours[i] + 1;
+      if ( Decompose_Curve( RAS_VARS first, last, flipped ) )
+        return FAILURE;
 
       /* we must now check whether the extreme arcs join or not */
       if ( FRAC( ras.lastY ) == 0 &&
@@ -3167,9 +3165,12 @@
 
 
   static int
-  ft_black_new( FT_Memory       memory,
-                black_PRaster  *araster )
+  ft_black_new( void*       memory_,    /* FT_Memory     */
+                FT_Raster  *araster_ )  /* black_PRaster */
   {
+    FT_Memory       memory = (FT_Memory)memory_;
+    black_PRaster  *araster = (black_PRaster*)araster_;
+
     FT_Error       error;
     black_PRaster  raster = NULL;
 
@@ -3184,9 +3185,10 @@
 
 
   static void
-  ft_black_done( black_PRaster  raster )
+  ft_black_done( FT_Raster  raster_ )   /* black_PRaster */
   {
-    FT_Memory  memory = (FT_Memory)raster->memory;
+    black_PRaster  raster = (black_PRaster)raster_;
+    FT_Memory      memory = (FT_Memory)raster->memory;
 
 
     FT_FREE( raster );
@@ -3281,11 +3283,11 @@
 
     FT_GLYPH_FORMAT_OUTLINE,
 
-    (FT_Raster_New_Func)     ft_black_new,       /* raster_new      */
-    (FT_Raster_Reset_Func)   ft_black_reset,     /* raster_reset    */
-    (FT_Raster_Set_Mode_Func)ft_black_set_mode,  /* raster_set_mode */
-    (FT_Raster_Render_Func)  ft_black_render,    /* raster_render   */
-    (FT_Raster_Done_Func)    ft_black_done       /* raster_done     */
+    ft_black_new,       /* FT_Raster_New_Func      raster_new      */
+    ft_black_reset,     /* FT_Raster_Reset_Func    raster_reset    */
+    ft_black_set_mode,  /* FT_Raster_Set_Mode_Func raster_set_mode */
+    ft_black_render,    /* FT_Raster_Render_Func   raster_render   */
+    ft_black_done       /* FT_Raster_Done_Func     raster_done     */
   )
 
 
diff --git a/src/java.desktop/share/native/libfreetype/src/raster/ftrend1.c b/src/java.desktop/share/native/libfreetype/src/raster/ftrend1.c
index 0b5d867..6d442b1 100644
--- a/src/java.desktop/share/native/libfreetype/src/raster/ftrend1.c
+++ b/src/java.desktop/share/native/libfreetype/src/raster/ftrend1.c
@@ -27,8 +27,11 @@
 
   /* initialize renderer -- init its raster */
   static FT_Error
-  ft_raster1_init( FT_Renderer  render )
+  ft_raster1_init( FT_Module  module )   /* FT_Renderer */
   {
+    FT_Renderer  render = (FT_Renderer)module;
+
+
     render->clazz->raster_class->raster_reset( render->raster, NULL, 0 );
 
     return FT_Err_Ok;
@@ -188,18 +191,18 @@
 
       NULL,    /* module specific interface */
 
-      (FT_Module_Constructor)ft_raster1_init,  /* module_init   */
-      (FT_Module_Destructor) NULL,             /* module_done   */
-      (FT_Module_Requester)  NULL,             /* get_interface */
+      ft_raster1_init,  /* FT_Module_Constructor module_init   */
+      NULL,             /* FT_Module_Destructor  module_done   */
+      NULL,             /* FT_Module_Requester   get_interface */
 
     FT_GLYPH_FORMAT_OUTLINE,
 
-    (FT_Renderer_RenderFunc)   ft_raster1_render,     /* render_glyph    */
-    (FT_Renderer_TransformFunc)ft_raster1_transform,  /* transform_glyph */
-    (FT_Renderer_GetCBoxFunc)  ft_raster1_get_cbox,   /* get_glyph_cbox  */
-    (FT_Renderer_SetModeFunc)  ft_raster1_set_mode,   /* set_mode        */
+    ft_raster1_render,     /* FT_Renderer_RenderFunc    render_glyph    */
+    ft_raster1_transform,  /* FT_Renderer_TransformFunc transform_glyph */
+    ft_raster1_get_cbox,   /* FT_Renderer_GetCBoxFunc   get_glyph_cbox  */
+    ft_raster1_set_mode,   /* FT_Renderer_SetModeFunc   set_mode        */
 
-    (FT_Raster_Funcs*)&ft_standard_raster             /* raster_class    */
+    &ft_standard_raster    /* FT_Raster_Funcs*          raster_class    */
   )
 
 
diff --git a/src/java.desktop/share/native/libfreetype/src/sfnt/pngshim.c b/src/java.desktop/share/native/libfreetype/src/sfnt/pngshim.c
index 423b07b..3371216 100644
--- a/src/java.desktop/share/native/libfreetype/src/sfnt/pngshim.c
+++ b/src/java.desktop/share/native/libfreetype/src/sfnt/pngshim.c
@@ -406,10 +406,7 @@
 
     switch ( color_type )
     {
-    default:
-      /* Shouldn't happen, but ... */
-      FALL_THROUGH;
-
+    default:  /* Shouldn't happen, but ... */
     case PNG_COLOR_TYPE_RGB_ALPHA:
       png_set_read_user_transform_fn( png, premultiply_data );
       break;
@@ -457,7 +454,7 @@
 #else /* !(TT_CONFIG_OPTION_EMBEDDED_BITMAPS && FT_CONFIG_OPTION_USE_PNG) */
 
   /* ANSI C doesn't like empty source files */
-  typedef int  _pngshim_dummy;
+  typedef int  pngshim_dummy_;
 
 #endif /* !(TT_CONFIG_OPTION_EMBEDDED_BITMAPS && FT_CONFIG_OPTION_USE_PNG) */
 
diff --git a/src/java.desktop/share/native/libfreetype/src/sfnt/sfdriver.c b/src/java.desktop/share/native/libfreetype/src/sfnt/sfdriver.c
index 762883d..0925940 100644
--- a/src/java.desktop/share/native/libfreetype/src/sfnt/sfdriver.c
+++ b/src/java.desktop/share/native/libfreetype/src/sfnt/sfdriver.c
@@ -79,41 +79,57 @@
    *
    */
 
-  static void*
-  get_sfnt_table( TT_Face      face,
+  FT_CALLBACK_DEF( FT_Error )
+  sfnt_load_table( FT_Face    face,    /* TT_Face */
+                   FT_ULong   tag,
+                   FT_Long    offset,
+                   FT_Byte*   buffer,
+                   FT_ULong*  length )
+  {
+    TT_Face  ttface = (TT_Face)face;
+
+
+    return tt_face_load_any( ttface, tag, offset, buffer, length );
+  }
+
+
+  FT_CALLBACK_DEF( void* )
+  get_sfnt_table( FT_Face      face,  /* TT_Face */
                   FT_Sfnt_Tag  tag )
   {
+    TT_Face  ttface = (TT_Face)face;
+
     void*  table;
 
 
     switch ( tag )
     {
     case FT_SFNT_HEAD:
-      table = &face->header;
+      table = &ttface->header;
       break;
 
     case FT_SFNT_HHEA:
-      table = &face->horizontal;
+      table = &ttface->horizontal;
       break;
 
     case FT_SFNT_VHEA:
-      table = face->vertical_info ? &face->vertical : NULL;
+      table = ttface->vertical_info ? &ttface->vertical : NULL;
       break;
 
     case FT_SFNT_OS2:
-      table = ( face->os2.version == 0xFFFFU ) ? NULL : &face->os2;
+      table = ( ttface->os2.version == 0xFFFFU ) ? NULL : &ttface->os2;
       break;
 
     case FT_SFNT_POST:
-      table = &face->postscript;
+      table = &ttface->postscript;
       break;
 
     case FT_SFNT_MAXP:
-      table = &face->max_profile;
+      table = &ttface->max_profile;
       break;
 
     case FT_SFNT_PCLT:
-      table = face->pclt.Version ? &face->pclt : NULL;
+      table = ttface->pclt.Version ? &ttface->pclt : NULL;
       break;
 
     default:
@@ -124,26 +140,29 @@
   }
 
 
-  static FT_Error
-  sfnt_table_info( TT_Face    face,
+  FT_CALLBACK_DEF( FT_Error )
+  sfnt_table_info( FT_Face    face,    /* TT_Face */
                    FT_UInt    idx,
                    FT_ULong  *tag,
                    FT_ULong  *offset,
                    FT_ULong  *length )
   {
+    TT_Face  ttface = (TT_Face)face;
+
+
     if ( !offset || !length )
       return FT_THROW( Invalid_Argument );
 
     if ( !tag )
-      *length = face->num_tables;
+      *length = ttface->num_tables;
     else
     {
-      if ( idx >= face->num_tables )
+      if ( idx >= ttface->num_tables )
         return FT_THROW( Table_Missing );
 
-      *tag    = face->dir_tables[idx].Tag;
-      *offset = face->dir_tables[idx].Offset;
-      *length = face->dir_tables[idx].Length;
+      *tag    = ttface->dir_tables[idx].Tag;
+      *offset = ttface->dir_tables[idx].Offset;
+      *length = ttface->dir_tables[idx].Length;
     }
 
     return FT_Err_Ok;
@@ -153,9 +172,9 @@
   FT_DEFINE_SERVICE_SFNT_TABLEREC(
     sfnt_service_sfnt_table,
 
-    (FT_SFNT_TableLoadFunc)tt_face_load_any,     /* load_table */
-    (FT_SFNT_TableGetFunc) get_sfnt_table,       /* get_table  */
-    (FT_SFNT_TableInfoFunc)sfnt_table_info       /* table_info */
+    sfnt_load_table,  /* FT_SFNT_TableLoadFunc load_table */
+    get_sfnt_table,   /* FT_SFNT_TableGetFunc  get_table  */
+    sfnt_table_info   /* FT_SFNT_TableInfoFunc table_info */
   )
 
 
@@ -166,7 +185,7 @@
    *
    */
 
-  static FT_Error
+  FT_CALLBACK_DEF( FT_Error )
   sfnt_get_glyph_name( FT_Face     face,
                        FT_UInt     glyph_index,
                        FT_Pointer  buffer,
@@ -184,7 +203,7 @@
   }
 
 
-  static FT_UInt
+  FT_CALLBACK_DEF( FT_UInt )
   sfnt_get_name_index( FT_Face           face,
                        const FT_String*  glyph_name )
   {
@@ -221,8 +240,8 @@
   FT_DEFINE_SERVICE_GLYPHDICTREC(
     sfnt_service_glyph_dict,
 
-    (FT_GlyphDict_GetNameFunc)  sfnt_get_glyph_name,    /* get_name   */
-    (FT_GlyphDict_NameIndexFunc)sfnt_get_name_index     /* name_index */
+    sfnt_get_glyph_name,  /* FT_GlyphDict_GetNameFunc   get_name   */
+    sfnt_get_name_index   /* FT_GlyphDict_NameIndexFunc name_index */
   )
 
 #endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */
@@ -523,15 +542,14 @@
           FT_TRACE0(( "get_win_string:"
                       " Character 0x%X invalid in PS name string\n",
                       ((unsigned)p[0])*256 + (unsigned)p[1] ));
-        break;
+        continue;
       }
     }
-    if ( !len )
-      *r = '\0';
+    *r = '\0';
 
     FT_FRAME_EXIT();
 
-    if ( !len )
+    if ( r != result )
       return result;
 
   get_win_string_error:
@@ -580,15 +598,14 @@
           FT_TRACE0(( "get_apple_string:"
                       " Character `%c' (0x%X) invalid in PS name string\n",
                       *p, *p ));
-        break;
+        continue;
       }
     }
-    if ( !len )
-      *r = '\0';
+    *r = '\0';
 
     FT_FRAME_EXIT();
 
-    if ( !len )
+    if ( r != result )
       return result;
 
   get_apple_string_error:
@@ -602,7 +619,7 @@
   }
 
 
-  static FT_Bool
+  FT_CALLBACK_DEF( FT_Bool )
   sfnt_get_name_id( TT_Face    face,
                     FT_UShort  id,
                     FT_Int    *win,
@@ -819,9 +836,9 @@
 
       if ( !found )
       {
-        /* as a last resort we try the family name; note that this is */
-        /* not in the Adobe TechNote, but GX fonts (which predate the */
-        /* TechNote) benefit from this behaviour                      */
+        /* according to the 'name' documentation in the OpenType   */
+        /* specification the font family name is to be used if the */
+        /* typographic family name is missing, so let's do that    */
         found = sfnt_get_name_id( face,
                                   TT_NAME_ID_FONT_FAMILY,
                                   &win,
@@ -853,6 +870,10 @@
       {
         FT_TRACE0(( "sfnt_get_var_ps_name:"
                     " No valid PS name prefix for font instances found\n" ));
+        /* XXX It probably makes sense to never let this fail */
+        /*     since an arbitrary prefix should work, too.    */
+        /*     On the other hand, it is very unlikely that    */
+        /*     we ever reach this code at all.                */
         return NULL;
       }
 
@@ -1041,47 +1062,49 @@
 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
 
 
-  static const char*
-  sfnt_get_ps_name( TT_Face  face )
+  FT_CALLBACK_DEF( const char* )
+  sfnt_get_ps_name( FT_Face  face )    /* TT_Face */
   {
+    TT_Face  ttface = (TT_Face)face;
+
     FT_Int       found, win, apple;
     const char*  result = NULL;
 
 
-    if ( face->postscript_name )
-      return face->postscript_name;
+    if ( ttface->postscript_name )
+      return ttface->postscript_name;
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
-    if ( face->blend                                 &&
-         ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) ||
-           FT_IS_VARIATION( FT_FACE( face ) )      ) )
+    if ( ttface->blend                    &&
+         ( FT_IS_NAMED_INSTANCE( face ) ||
+           FT_IS_VARIATION( face )      ) )
     {
-      face->postscript_name = sfnt_get_var_ps_name( face );
-      return face->postscript_name;
+      ttface->postscript_name = sfnt_get_var_ps_name( ttface );
+      return ttface->postscript_name;
     }
 #endif
 
     /* scan the name table to see whether we have a Postscript name here, */
     /* either in Macintosh or Windows platform encodings                  */
-    found = sfnt_get_name_id( face, TT_NAME_ID_PS_NAME, &win, &apple );
+    found = sfnt_get_name_id( ttface, TT_NAME_ID_PS_NAME, &win, &apple );
     if ( !found )
       return NULL;
 
     /* prefer Windows entries over Apple */
     if ( win != -1 )
-      result = get_win_string( face->root.memory,
-                               face->name_table.stream,
-                               face->name_table.names + win,
+      result = get_win_string( FT_FACE_MEMORY( face ),
+                               ttface->name_table.stream,
+                               ttface->name_table.names + win,
                                sfnt_is_postscript,
                                1 );
     if ( !result && apple != -1 )
-      result = get_apple_string( face->root.memory,
-                                 face->name_table.stream,
-                                 face->name_table.names + apple,
+      result = get_apple_string( FT_FACE_MEMORY( face ),
+                                 ttface->name_table.stream,
+                                 ttface->name_table.names + apple,
                                  sfnt_is_postscript,
                                  1 );
 
-    face->postscript_name = result;
+    ttface->postscript_name = result;
 
     return result;
   }
@@ -1090,7 +1113,7 @@
   FT_DEFINE_SERVICE_PSFONTNAMEREC(
     sfnt_service_ps_name,
 
-    (FT_PsName_GetFunc)sfnt_get_ps_name       /* get_ps_font_name */
+    sfnt_get_ps_name  /* FT_PsName_GetFunc get_ps_font_name */
   )
 
 
@@ -1100,14 +1123,14 @@
   FT_DEFINE_SERVICE_TTCMAPSREC(
     tt_service_get_cmap_info,
 
-    (TT_CMap_Info_GetFunc)tt_get_cmap_info    /* get_cmap_info */
+    tt_get_cmap_info  /* TT_CMap_Info_GetFunc get_cmap_info */
   )
 
 
 #ifdef TT_CONFIG_OPTION_BDF
 
   static FT_Error
-  sfnt_get_charset_id( TT_Face       face,
+  sfnt_get_charset_id( FT_Face       face,
                        const char*  *acharset_encoding,
                        const char*  *acharset_registry )
   {
@@ -1145,8 +1168,8 @@
   FT_DEFINE_SERVICE_BDFRec(
     sfnt_service_bdf,
 
-    (FT_BDF_GetCharsetIdFunc)sfnt_get_charset_id,     /* get_charset_id */
-    (FT_BDF_GetPropertyFunc) tt_face_find_bdf_prop    /* get_property   */
+    sfnt_get_charset_id,   /* FT_BDF_GetCharsetIdFunc get_charset_id */
+    tt_face_find_bdf_prop  /* FT_BDF_GetPropertyFunc  get_property   */
   )
 
 
@@ -1337,9 +1360,9 @@
 
     (const void*)&sfnt_interface,  /* module specific interface */
 
-    (FT_Module_Constructor)NULL,               /* module_init   */
-    (FT_Module_Destructor) NULL,               /* module_done   */
-    (FT_Module_Requester)  sfnt_get_interface  /* get_interface */
+    NULL,               /* FT_Module_Constructor module_init   */
+    NULL,               /* FT_Module_Destructor  module_done   */
+    sfnt_get_interface  /* FT_Module_Requester   get_interface */
   )
 
 
diff --git a/src/java.desktop/share/native/libfreetype/src/sfnt/sfobjs.c b/src/java.desktop/share/native/libfreetype/src/sfnt/sfobjs.c
index e018934..f5d66ef 100644
--- a/src/java.desktop/share/native/libfreetype/src/sfnt/sfobjs.c
+++ b/src/java.desktop/share/native/libfreetype/src/sfnt/sfobjs.c
@@ -534,17 +534,23 @@
                                         0 );
     }
 
-    if ( !face->var )
+    if ( !face->tt_var )
     {
       /* we want the metrics variations interface */
       /* from the `truetype' module only          */
       FT_Module  tt_module = FT_Get_Module( library, "truetype" );
 
 
-      face->var = ft_module_get_service( tt_module,
-                                         FT_SERVICE_ID_METRICS_VARIATIONS,
-                                         0 );
+      face->tt_var = ft_module_get_service( tt_module,
+                                            FT_SERVICE_ID_METRICS_VARIATIONS,
+                                            0 );
     }
+
+    if ( !face->face_var )
+      face->face_var = ft_module_get_service(
+                         &face->root.driver->root,
+                         FT_SERVICE_ID_METRICS_VARIATIONS,
+                         0 );
 #endif
 
     FT_TRACE2(( "SFNT driver\n" ));
@@ -692,6 +698,9 @@
           instance_offset += instance_size;
         }
 
+        /* named instance indices start with value 1 */
+        face->var_default_named_instance = i + 1;
+
         if ( i == num_instances )
         {
           /* no default instance in named instance table; */
@@ -1054,6 +1063,16 @@
         GET_NAME( FONT_SUBFAMILY, &face->root.style_name );
     }
 
+#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
+    {
+      FT_Memory  memory = face->root.memory;
+
+
+      if ( FT_STRDUP( face->non_var_style_name, face->root.style_name ) )
+        goto Exit;
+    }
+#endif
+
     /* now set up root fields */
     {
       FT_Face  root  = &face->root;
@@ -1221,7 +1240,7 @@
 
         if ( count > 0 )
         {
-          FT_Memory        memory   = face->root.stream->memory;
+          FT_Memory        memory   = face->root.memory;
           FT_UShort        em_size  = face->header.Units_Per_EM;
           FT_Short         avgwidth = face->os2.xAvgCharWidth;
           FT_Size_Metrics  metrics;
@@ -1500,6 +1519,7 @@
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
     FT_FREE( face->var_postscript_prefix );
+    FT_FREE( face->non_var_style_name );
 #endif
 
     /* freeing glyph color palette data */
diff --git a/src/java.desktop/share/native/libfreetype/src/sfnt/sfwoff.c b/src/java.desktop/share/native/libfreetype/src/sfnt/sfwoff.c
index 9559bf3..7c0ce22 100644
--- a/src/java.desktop/share/native/libfreetype/src/sfnt/sfwoff.c
+++ b/src/java.desktop/share/native/libfreetype/src/sfnt/sfwoff.c
@@ -426,7 +426,7 @@
 #else /* !FT_CONFIG_OPTION_USE_ZLIB */
 
   /* ANSI C doesn't like empty source files */
-  typedef int  _sfwoff_dummy;
+  typedef int  sfwoff_dummy_;
 
 #endif /* !FT_CONFIG_OPTION_USE_ZLIB */
 
diff --git a/src/java.desktop/share/native/libfreetype/src/sfnt/sfwoff2.c b/src/java.desktop/share/native/libfreetype/src/sfnt/sfwoff2.c
index 7a01977..2be44a3 100644
--- a/src/java.desktop/share/native/libfreetype/src/sfnt/sfwoff2.c
+++ b/src/java.desktop/share/native/libfreetype/src/sfnt/sfwoff2.c
@@ -36,6 +36,8 @@
 #undef  FT_COMPONENT
 #define FT_COMPONENT  sfwoff2
 
+  /* An arbitrary, heuristic size limit (67MByte) for expanded WOFF2 data. */
+#define MAX_SFNT_SIZE  ( 1 << 26 )
 
 #define READ_255USHORT( var )  FT_SET_ERROR( Read255UShort( stream, &var ) )
 
@@ -2180,9 +2182,8 @@
       else
         sfnt_size = woff2.totalSfntSize;
 
-      /* Value 1<<26 = 67108864 is heuristic. */
-      if (sfnt_size >= (1 << 26))
-        sfnt_size = 1 << 26;
+      if ( sfnt_size >= MAX_SFNT_SIZE )
+        sfnt_size = MAX_SFNT_SIZE;
 
 #ifdef FT_DEBUG_LEVEL_TRACE
       if ( sfnt_size != woff2.totalSfntSize )
@@ -2257,10 +2258,15 @@
       goto Exit;
     }
 
-    if ( woff2.uncompressed_size > sfnt_size )
+    /* We must not blindly trust `uncompressed_size` since its   */
+    /* value might be corrupted.  If it is too large, reject the */
+    /* font.  In other words, we don't accept a WOFF2 font that  */
+    /* expands to something larger than MAX_SFNT_SIZE.  If ever  */
+    /* necessary, this limit can be easily adjusted.             */
+    if ( woff2.uncompressed_size > MAX_SFNT_SIZE )
     {
-      FT_ERROR(( "woff2_open_font: SFNT table lengths are too large.\n" ));
-      error = FT_THROW( Invalid_Table );
+      FT_ERROR(( "Uncompressed font too large.\n" ));
+      error = FT_THROW( Array_Too_Large );
       goto Exit;
     }
 
@@ -2378,7 +2384,7 @@
 #else /* !FT_CONFIG_OPTION_USE_BROTLI */
 
   /* ANSI C doesn't like empty source files */
-  typedef int  _sfwoff2_dummy;
+  typedef int  sfwoff2_dummy_;
 
 #endif /* !FT_CONFIG_OPTION_USE_BROTLI */
 
diff --git a/src/java.desktop/share/native/libfreetype/src/sfnt/ttcmap.c b/src/java.desktop/share/native/libfreetype/src/sfnt/ttcmap.c
index 820cd08..9ba25dc 100644
--- a/src/java.desktop/share/native/libfreetype/src/sfnt/ttcmap.c
+++ b/src/java.desktop/share/native/libfreetype/src/sfnt/ttcmap.c
@@ -59,10 +59,14 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  tt_cmap_init( TT_CMap   cmap,
-                FT_Byte*  table )
+  tt_cmap_init( FT_CMap  cmap,    /* TT_CMap */
+                void*    table_ )
   {
-    cmap->data = table;
+    TT_CMap   ttcmap = (TT_CMap)cmap;
+    FT_Byte*  table  = (FT_Byte*)table_;
+
+
+    ttcmap->data = table;
     return FT_Err_Ok;
   }
 
@@ -128,21 +132,23 @@
 
 
   FT_CALLBACK_DEF( FT_UInt )
-  tt_cmap0_char_index( TT_CMap    cmap,
+  tt_cmap0_char_index( FT_CMap    cmap,       /* TT_CMap */
                        FT_UInt32  char_code )
   {
-    FT_Byte*  table = cmap->data;
+    TT_CMap   ttcmap = (TT_CMap)cmap;
+    FT_Byte*  table  = ttcmap->data;
 
 
     return char_code < 256 ? table[6 + char_code] : 0;
   }
 
 
-  FT_CALLBACK_DEF( FT_UInt32 )
-  tt_cmap0_char_next( TT_CMap     cmap,
+  FT_CALLBACK_DEF( FT_UInt )
+  tt_cmap0_char_next( FT_CMap     cmap,        /* TT_CMap */
                       FT_UInt32  *pchar_code )
   {
-    FT_Byte*   table    = cmap->data;
+    TT_CMap    ttcmap   = (TT_CMap)cmap;
+    FT_Byte*   table    = ttcmap->data;
     FT_UInt32  charcode = *pchar_code;
     FT_UInt32  result   = 0;
     FT_UInt    gindex   = 0;
@@ -165,10 +171,11 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  tt_cmap0_get_info( TT_CMap       cmap,
+  tt_cmap0_get_info( FT_CharMap    cmap,       /* TT_CMap */
                      TT_CMapInfo  *cmap_info )
   {
-    FT_Byte*  p = cmap->data + 4;
+    TT_CMap   ttcmap = (TT_CMap)cmap;
+    FT_Byte*  p      = ttcmap->data + 4;
 
 
     cmap_info->format   = 0;
@@ -453,10 +460,11 @@
 
 
   FT_CALLBACK_DEF( FT_UInt )
-  tt_cmap2_char_index( TT_CMap    cmap,
+  tt_cmap2_char_index( FT_CMap    cmap,       /* TT_CMap */
                        FT_UInt32  char_code )
   {
-    FT_Byte*  table   = cmap->data;
+    TT_CMap   ttcmap  = (TT_CMap)cmap;
+    FT_Byte*  table   = ttcmap->data;
     FT_UInt   result  = 0;
     FT_Byte*  subheader;
 
@@ -491,11 +499,12 @@
   }
 
 
-  FT_CALLBACK_DEF( FT_UInt32 )
-  tt_cmap2_char_next( TT_CMap     cmap,
+  FT_CALLBACK_DEF( FT_UInt )
+  tt_cmap2_char_next( FT_CMap     cmap,       /* TT_CMap */
                       FT_UInt32  *pcharcode )
   {
-    FT_Byte*   table    = cmap->data;
+    TT_CMap    ttcmap   = (TT_CMap)cmap;
+    FT_Byte*   table    = ttcmap->data;
     FT_UInt    gindex   = 0;
     FT_UInt32  result   = 0;
     FT_UInt32  charcode = *pcharcode + 1;
@@ -579,10 +588,11 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  tt_cmap2_get_info( TT_CMap       cmap,
+  tt_cmap2_get_info( FT_CharMap    cmap,       /* TT_CMap */
                      TT_CMapInfo  *cmap_info )
   {
-    FT_Byte*  p = cmap->data + 4;
+    TT_CMap   ttcmap = (TT_CMap)cmap;
+    FT_Byte*  p      = ttcmap->data + 4;
 
 
     cmap_info->format   = 2;
@@ -706,18 +716,20 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  tt_cmap4_init( TT_CMap4  cmap,
-                 FT_Byte*  table )
+  tt_cmap4_init( FT_CMap  cmap,    /* TT_CMap4 */
+                 void*    table_ )
   {
+    TT_CMap4  ttcmap = (TT_CMap4)cmap;
+    FT_Byte*  table  = (FT_Byte*)table_;
     FT_Byte*  p;
 
 
-    cmap->cmap.data    = table;
+    ttcmap->cmap.data = table;
 
-    p                  = table + 6;
-    cmap->num_ranges   = FT_PEEK_USHORT( p ) >> 1;
-    cmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL;
-    cmap->cur_gindex   = 0;
+    p                    = table + 6;
+    ttcmap->num_ranges   = FT_PEEK_USHORT( p ) >> 1;
+    ttcmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL;
+    ttcmap->cur_gindex   = 0;
 
     return FT_Err_Ok;
   }
@@ -755,7 +767,7 @@
            cmap->cur_start == 0xFFFFU        &&
            cmap->cur_end   == 0xFFFFU        )
       {
-        TT_Face   face  = (TT_Face)cmap->cmap.cmap.charmap.face;
+        TT_Face   face  = (TT_Face)FT_CMAP_FACE( cmap );
         FT_Byte*  limit = face->cmap_table + face->cmap_size;
 
 
@@ -788,15 +800,12 @@
   static void
   tt_cmap4_next( TT_CMap4  cmap )
   {
-    TT_Face   face  = (TT_Face)cmap->cmap.cmap.charmap.face;
+    TT_Face   face  = (TT_Face)FT_CMAP_FACE( cmap );
     FT_Byte*  limit = face->cmap_table + face->cmap_size;
 
     FT_UInt  charcode;
 
 
-    if ( cmap->cur_charcode >= 0xFFFFUL )
-      goto Fail;
-
     charcode = (FT_UInt)cmap->cur_charcode + 1;
 
     if ( charcode < cmap->cur_start )
@@ -882,7 +891,6 @@
         charcode = cmap->cur_start;
     }
 
-  Fail:
     cmap->cur_charcode = (FT_UInt32)0xFFFFFFFFUL;
     cmap->cur_gindex   = 0;
   }
@@ -1097,32 +1105,26 @@
                             FT_UInt32*  pcharcode,
                             FT_Bool     next )
   {
-    TT_Face   face  = (TT_Face)cmap->cmap.charmap.face;
+    TT_Face   face  = (TT_Face)FT_CMAP_FACE( cmap );
     FT_Byte*  limit = face->cmap_table + face->cmap_size;
 
 
     FT_UInt    num_segs2, start, end, offset;
     FT_Int     delta;
     FT_UInt    i, num_segs;
-    FT_UInt32  charcode = *pcharcode;
+    FT_UInt32  charcode = *pcharcode + next;
     FT_UInt    gindex   = 0;
     FT_Byte*   p;
     FT_Byte*   q;
 
 
     p = cmap->data + 6;
-    num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 2 );
-
-    num_segs = num_segs2 >> 1;
+    num_segs = TT_PEEK_USHORT( p ) >> 1;
 
     if ( !num_segs )
       return 0;
 
-    if ( next )
-      charcode++;
-
-    if ( charcode > 0xFFFFU )
-      return 0;
+    num_segs2 = num_segs << 1;
 
     /* linear search */
     p = cmap->data + 14;               /* ends table   */
@@ -1232,37 +1234,30 @@
                             FT_UInt32*  pcharcode,
                             FT_Bool     next )
   {
-    TT_Face   face  = (TT_Face)cmap->cmap.charmap.face;
+    TT_Face   face  = (TT_Face)FT_CMAP_FACE( cmap );
     FT_Byte*  limit = face->cmap_table + face->cmap_size;
 
     FT_UInt   num_segs2, start, end, offset;
     FT_Int    delta;
     FT_UInt   max, min, mid, num_segs;
-    FT_UInt   charcode = (FT_UInt)*pcharcode;
+    FT_UInt   charcode = (FT_UInt)*pcharcode + next;
     FT_UInt   gindex   = 0;
     FT_Byte*  p;
 
 
     p = cmap->data + 6;
-    num_segs2 = FT_PAD_FLOOR( TT_PEEK_USHORT( p ), 2 );
+    num_segs = TT_PEEK_USHORT( p ) >> 1;
 
-    if ( !num_segs2 )
+    if ( !num_segs )
       return 0;
 
-    num_segs = num_segs2 >> 1;
-
-    /* make compiler happy */
-    mid = num_segs;
-    end = 0xFFFFU;
-
-    if ( next )
-      charcode++;
+    num_segs2 = num_segs << 1;
 
     min = 0;
     max = num_segs;
 
     /* binary search */
-    while ( min < max )
+    do
     {
       mid    = ( min + max ) >> 1;
       p      = cmap->data + 14 + mid * 2;
@@ -1445,6 +1440,7 @@
         break;
       }
     }
+    while ( min < max );
 
     if ( next )
     {
@@ -1454,12 +1450,8 @@
       /* if `charcode' is not in any segment, then `mid' is */
       /* the segment nearest to `charcode'                  */
 
-      if ( charcode > end )
-      {
-        mid++;
-        if ( mid == num_segs )
-          return 0;
-      }
+      if ( charcode > end && ++mid == num_segs )
+        return 0;
 
       if ( tt_cmap4_set_range( cmap4, mid ) )
       {
@@ -1474,7 +1466,6 @@
           cmap4->cur_gindex = gindex;
         else
         {
-          cmap4->cur_charcode = charcode;
           tt_cmap4_next( cmap4 );
           gindex = cmap4->cur_gindex;
         }
@@ -1489,31 +1480,35 @@
 
 
   FT_CALLBACK_DEF( FT_UInt )
-  tt_cmap4_char_index( TT_CMap    cmap,
+  tt_cmap4_char_index( FT_CMap    cmap,       /* TT_CMap */
                        FT_UInt32  char_code )
   {
+    TT_CMap  ttcmap = (TT_CMap)cmap;
+
+
     if ( char_code >= 0x10000UL )
       return 0;
 
-    if ( cmap->flags & TT_CMAP_FLAG_UNSORTED )
-      return tt_cmap4_char_map_linear( cmap, &char_code, 0 );
+    if ( ttcmap->flags & TT_CMAP_FLAG_UNSORTED )
+      return tt_cmap4_char_map_linear( ttcmap, &char_code, 0 );
     else
-      return tt_cmap4_char_map_binary( cmap, &char_code, 0 );
+      return tt_cmap4_char_map_binary( ttcmap, &char_code, 0 );
   }
 
 
-  FT_CALLBACK_DEF( FT_UInt32 )
-  tt_cmap4_char_next( TT_CMap     cmap,
+  FT_CALLBACK_DEF( FT_UInt )
+  tt_cmap4_char_next( FT_CMap     cmap,        /* TT_CMap */
                       FT_UInt32  *pchar_code )
   {
+    TT_CMap  ttcmap = (TT_CMap)cmap;
     FT_UInt  gindex;
 
 
     if ( *pchar_code >= 0xFFFFU )
       return 0;
 
-    if ( cmap->flags & TT_CMAP_FLAG_UNSORTED )
-      gindex = tt_cmap4_char_map_linear( cmap, pchar_code, 1 );
+    if ( ttcmap->flags & TT_CMAP_FLAG_UNSORTED )
+      gindex = tt_cmap4_char_map_linear( ttcmap, pchar_code, 1 );
     else
     {
       TT_CMap4  cmap4 = (TT_CMap4)cmap;
@@ -1528,7 +1523,7 @@
           *pchar_code = cmap4->cur_charcode;
       }
       else
-        gindex = tt_cmap4_char_map_binary( cmap, pchar_code, 1 );
+        gindex = tt_cmap4_char_map_binary( ttcmap, pchar_code, 1 );
     }
 
     return gindex;
@@ -1536,10 +1531,11 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  tt_cmap4_get_info( TT_CMap       cmap,
+  tt_cmap4_get_info( FT_CharMap    cmap,       /* TT_CMap */
                      TT_CMapInfo  *cmap_info )
   {
-    FT_Byte*  p = cmap->data + 4;
+    TT_CMap   ttcmap = (TT_CMap)cmap;
+    FT_Byte*  p      = ttcmap->data + 4;
 
 
     cmap_info->format   = 4;
@@ -1640,10 +1636,11 @@
 
 
   FT_CALLBACK_DEF( FT_UInt )
-  tt_cmap6_char_index( TT_CMap    cmap,
+  tt_cmap6_char_index( FT_CMap    cmap,       /* TT_CMap */
                        FT_UInt32  char_code )
   {
-    FT_Byte*  table  = cmap->data;
+    TT_CMap   ttcmap = (TT_CMap)cmap;
+    FT_Byte*  table  = ttcmap->data;
     FT_UInt   result = 0;
     FT_Byte*  p      = table + 6;
     FT_UInt   start  = TT_NEXT_USHORT( p );
@@ -1661,11 +1658,12 @@
   }
 
 
-  FT_CALLBACK_DEF( FT_UInt32 )
-  tt_cmap6_char_next( TT_CMap     cmap,
+  FT_CALLBACK_DEF( FT_UInt )
+  tt_cmap6_char_next( FT_CMap     cmap,        /* TT_CMap */
                       FT_UInt32  *pchar_code )
   {
-    FT_Byte*   table     = cmap->data;
+    TT_CMap    ttcmap    = (TT_CMap)cmap;
+    FT_Byte*   table     = ttcmap->data;
     FT_UInt32  result    = 0;
     FT_UInt32  char_code = *pchar_code + 1;
     FT_UInt    gindex    = 0;
@@ -1706,10 +1704,11 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  tt_cmap6_get_info( TT_CMap       cmap,
+  tt_cmap6_get_info( FT_CharMap    cmap,       /* TT_CMap */
                      TT_CMapInfo  *cmap_info )
   {
-    FT_Byte*  p = cmap->data + 4;
+    TT_CMap   ttcmap = (TT_CMap)cmap;
+    FT_Byte*  p      = ttcmap->data + 4;
 
 
     cmap_info->format   = 6;
@@ -1900,10 +1899,11 @@
 
 
   FT_CALLBACK_DEF( FT_UInt )
-  tt_cmap8_char_index( TT_CMap    cmap,
+  tt_cmap8_char_index( FT_CMap    cmap,       /* TT_CMap */
                        FT_UInt32  char_code )
   {
-    FT_Byte*   table      = cmap->data;
+    TT_CMap    ttcmap     = (TT_CMap)cmap;
+    FT_Byte*   table      = ttcmap->data;
     FT_UInt    result     = 0;
     FT_Byte*   p          = table + 8204;
     FT_UInt32  num_groups = TT_NEXT_ULONG( p );
@@ -1932,15 +1932,16 @@
   }
 
 
-  FT_CALLBACK_DEF( FT_UInt32 )
-  tt_cmap8_char_next( TT_CMap     cmap,
+  FT_CALLBACK_DEF( FT_UInt )
+  tt_cmap8_char_next( FT_CMap     cmap,        /* TT_CMap */
                       FT_UInt32  *pchar_code )
   {
-    FT_Face    face       = cmap->cmap.charmap.face;
+    TT_CMap    ttcmap     = (TT_CMap)cmap;
+    FT_Face    face       = FT_CMAP_FACE( cmap );
     FT_UInt32  result     = 0;
     FT_UInt32  char_code;
     FT_UInt    gindex     = 0;
-    FT_Byte*   table      = cmap->data;
+    FT_Byte*   table      = ttcmap->data;
     FT_Byte*   p          = table + 8204;
     FT_UInt32  num_groups = TT_NEXT_ULONG( p );
     FT_UInt32  start, end, start_id;
@@ -2000,10 +2001,11 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  tt_cmap8_get_info( TT_CMap       cmap,
+  tt_cmap8_get_info( FT_CharMap    cmap,       /* TT_CMap */
                      TT_CMapInfo  *cmap_info )
   {
-    FT_Byte*  p = cmap->data + 8;
+    TT_CMap   ttcmap = (TT_CMap)cmap;
+    FT_Byte*  p      = ttcmap->data + 8;
 
 
     cmap_info->format   = 8;
@@ -2104,10 +2106,11 @@
 
 
   FT_CALLBACK_DEF( FT_UInt )
-  tt_cmap10_char_index( TT_CMap    cmap,
+  tt_cmap10_char_index( FT_CMap    cmap,       /* TT_CMap */
                         FT_UInt32  char_code )
   {
-    FT_Byte*   table  = cmap->data;
+    TT_CMap    ttcmap = (TT_CMap)cmap;
+    FT_Byte*   table  = ttcmap->data;
     FT_UInt    result = 0;
     FT_Byte*   p      = table + 12;
     FT_UInt32  start  = TT_NEXT_ULONG( p );
@@ -2130,11 +2133,12 @@
   }
 
 
-  FT_CALLBACK_DEF( FT_UInt32 )
-  tt_cmap10_char_next( TT_CMap     cmap,
+  FT_CALLBACK_DEF( FT_UInt )
+  tt_cmap10_char_next( FT_CMap     cmap,        /* TT_CMap */
                        FT_UInt32  *pchar_code )
   {
-    FT_Byte*   table     = cmap->data;
+    TT_CMap    ttcmap    = (TT_CMap)cmap;
+    FT_Byte*   table     = ttcmap->data;
     FT_UInt32  char_code;
     FT_UInt    gindex    = 0;
     FT_Byte*   p         = table + 12;
@@ -2172,10 +2176,11 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  tt_cmap10_get_info( TT_CMap       cmap,
+  tt_cmap10_get_info( FT_CharMap    cmap,       /* TT_CMap */
                       TT_CMapInfo  *cmap_info )
   {
-    FT_Byte*  p = cmap->data + 8;
+    TT_CMap   ttcmap = (TT_CMap)cmap;
+    FT_Byte*  p      = ttcmap->data + 8;
 
 
     cmap_info->format   = 10;
@@ -2253,15 +2258,19 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  tt_cmap12_init( TT_CMap12  cmap,
-                  FT_Byte*   table )
+  tt_cmap12_init( FT_CMap  cmap,    /* TT_CMap12 */
+                  void*    table_ )
   {
-    cmap->cmap.data  = table;
+    TT_CMap12  ttcmap = (TT_CMap12)cmap;
+    FT_Byte*   table  = (FT_Byte*)table_;
 
-    table           += 12;
-    cmap->num_groups = FT_PEEK_ULONG( table );
 
-    cmap->valid      = 0;
+    ttcmap->cmap.data  = table;
+
+    table             += 12;
+    ttcmap->num_groups = FT_PEEK_ULONG( table );
+
+    ttcmap->valid      = 0;
 
     return FT_Err_Ok;
   }
@@ -2331,23 +2340,21 @@
   /* cmap->cur_group should be set up properly by caller         */
   /*                                                             */
   static void
-  tt_cmap12_next( TT_CMap12  cmap )
+  tt_cmap12_next( FT_CMap  cmap )    /* TT_CMap12 */
   {
-    FT_Face   face = cmap->cmap.cmap.charmap.face;
-    FT_Byte*  p;
-    FT_ULong  start, end, start_id, char_code;
-    FT_ULong  n;
-    FT_UInt   gindex;
+    TT_CMap12  ttcmap = (TT_CMap12)cmap;
+    FT_Face    face   = FT_CMAP_FACE( cmap );
+    FT_Byte*   p;
+    FT_ULong   start, end, start_id, char_code;
+    FT_ULong   n;
+    FT_UInt    gindex;
 
 
-    if ( cmap->cur_charcode >= 0xFFFFFFFFUL )
-      goto Fail;
+    char_code = ttcmap->cur_charcode + 1;
 
-    char_code = cmap->cur_charcode + 1;
-
-    for ( n = cmap->cur_group; n < cmap->num_groups; n++ )
+    for ( n = ttcmap->cur_group; n < ttcmap->num_groups; n++ )
     {
-      p        = cmap->cmap.data + 16 + 12 * n;
+      p        = ttcmap->cmap.data + 16 + 12 * n;
       start    = TT_NEXT_ULONG( p );
       end      = TT_NEXT_ULONG( p );
       start_id = TT_PEEK_ULONG( p );
@@ -2379,16 +2386,16 @@
         if ( gindex >= (FT_UInt)face->num_glyphs )
           continue;
 
-        cmap->cur_charcode = char_code;
-        cmap->cur_gindex   = gindex;
-        cmap->cur_group    = n;
+        ttcmap->cur_charcode = char_code;
+        ttcmap->cur_gindex   = gindex;
+        ttcmap->cur_group    = n;
 
         return;
       }
     }
 
   Fail:
-    cmap->valid = 0;
+    ttcmap->valid = 0;
   }
 
 
@@ -2400,7 +2407,7 @@
     FT_UInt    gindex     = 0;
     FT_Byte*   p          = cmap->data + 12;
     FT_UInt32  num_groups = TT_PEEK_ULONG( p );
-    FT_UInt32  char_code  = *pchar_code;
+    FT_UInt32  char_code  = *pchar_code + next;
     FT_UInt32  start, end, start_id;
     FT_UInt32  max, min, mid;
 
@@ -2408,23 +2415,11 @@
     if ( !num_groups )
       return 0;
 
-    /* make compiler happy */
-    mid = num_groups;
-    end = 0xFFFFFFFFUL;
-
-    if ( next )
-    {
-      if ( char_code >= 0xFFFFFFFFUL )
-        return 0;
-
-      char_code++;
-    }
-
     min = 0;
     max = num_groups;
 
     /* binary search */
-    while ( min < max )
+    do
     {
       mid = ( min + max ) >> 1;
       p   = cmap->data + 16 + 12 * mid;
@@ -2448,22 +2443,19 @@
         break;
       }
     }
+    while ( min < max );
 
     if ( next )
     {
-      FT_Face    face   = cmap->cmap.charmap.face;
+      FT_Face    face   = FT_CMAP_FACE( cmap );
       TT_CMap12  cmap12 = (TT_CMap12)cmap;
 
 
       /* if `char_code' is not in any group, then `mid' is */
       /* the group nearest to `char_code'                  */
 
-      if ( char_code > end )
-      {
-        mid++;
-        if ( mid == num_groups )
-          return 0;
-      }
+      if ( char_code > end && ++mid == num_groups )
+        return 0;
 
       cmap12->valid        = 1;
       cmap12->cur_charcode = char_code;
@@ -2474,7 +2466,7 @@
 
       if ( !gindex )
       {
-        tt_cmap12_next( cmap12 );
+        tt_cmap12_next( FT_CMAP( cmap12 ) );
 
         if ( cmap12->valid )
           gindex = cmap12->cur_gindex;
@@ -2490,25 +2482,28 @@
 
 
   FT_CALLBACK_DEF( FT_UInt )
-  tt_cmap12_char_index( TT_CMap    cmap,
+  tt_cmap12_char_index( FT_CMap    cmap,       /* TT_CMap */
                         FT_UInt32  char_code )
   {
-    return tt_cmap12_char_map_binary( cmap, &char_code, 0 );
+    return tt_cmap12_char_map_binary( (TT_CMap)cmap, &char_code, 0 );
   }
 
 
-  FT_CALLBACK_DEF( FT_UInt32 )
-  tt_cmap12_char_next( TT_CMap     cmap,
+  FT_CALLBACK_DEF( FT_UInt )
+  tt_cmap12_char_next( FT_CMap     cmap,        /* TT_CMap12 */
                        FT_UInt32  *pchar_code )
   {
     TT_CMap12  cmap12 = (TT_CMap12)cmap;
     FT_UInt    gindex;
 
 
+    if ( *pchar_code >= 0xFFFFFFFFUL )
+      return 0;
+
     /* no need to search */
     if ( cmap12->valid && cmap12->cur_charcode == *pchar_code )
     {
-      tt_cmap12_next( cmap12 );
+      tt_cmap12_next( FT_CMAP( cmap12 ) );
       if ( cmap12->valid )
       {
         gindex      = cmap12->cur_gindex;
@@ -2518,17 +2513,18 @@
         gindex = 0;
     }
     else
-      gindex = tt_cmap12_char_map_binary( cmap, pchar_code, 1 );
+      gindex = tt_cmap12_char_map_binary( (TT_CMap)cmap, pchar_code, 1 );
 
     return gindex;
   }
 
 
   FT_CALLBACK_DEF( FT_Error )
-  tt_cmap12_get_info( TT_CMap       cmap,
+  tt_cmap12_get_info( FT_CharMap    cmap,       /* TT_CMap */
                       TT_CMapInfo  *cmap_info )
   {
-    FT_Byte*  p = cmap->data + 8;
+    TT_CMap   ttcmap = (TT_CMap)cmap;
+    FT_Byte*  p      = ttcmap->data + 8;
 
 
     cmap_info->format   = 12;
@@ -2606,15 +2602,19 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  tt_cmap13_init( TT_CMap13  cmap,
-                  FT_Byte*   table )
+  tt_cmap13_init( FT_CMap  cmap,    /* TT_CMap13 */
+                  void*    table_ )
   {
-    cmap->cmap.data  = table;
+    TT_CMap13  ttcmap = (TT_CMap13)cmap;
+    FT_Byte*   table  = (FT_Byte*)table_;
 
-    table           += 12;
-    cmap->num_groups = FT_PEEK_ULONG( table );
 
-    cmap->valid      = 0;
+    ttcmap->cmap.data  = table;
+
+    table             += 12;
+    ttcmap->num_groups = FT_PEEK_ULONG( table );
+
+    ttcmap->valid      = 0;
 
     return FT_Err_Ok;
   }
@@ -2679,23 +2679,21 @@
   /* cmap->cur_group should be set up properly by caller         */
   /*                                                             */
   static void
-  tt_cmap13_next( TT_CMap13  cmap )
+  tt_cmap13_next( FT_CMap  cmap )    /* TT_CMap13 */
   {
-    FT_Face   face = cmap->cmap.cmap.charmap.face;
-    FT_Byte*  p;
-    FT_ULong  start, end, glyph_id, char_code;
-    FT_ULong  n;
-    FT_UInt   gindex;
+    TT_CMap13  ttcmap = (TT_CMap13)cmap;
+    FT_Face    face = FT_CMAP_FACE( cmap );
+    FT_Byte*   p;
+    FT_ULong   start, end, glyph_id, char_code;
+    FT_ULong   n;
+    FT_UInt    gindex;
 
 
-    if ( cmap->cur_charcode >= 0xFFFFFFFFUL )
-      goto Fail;
+    char_code = ttcmap->cur_charcode + 1;
 
-    char_code = cmap->cur_charcode + 1;
-
-    for ( n = cmap->cur_group; n < cmap->num_groups; n++ )
+    for ( n = ttcmap->cur_group; n < ttcmap->num_groups; n++ )
     {
-      p        = cmap->cmap.data + 16 + 12 * n;
+      p        = ttcmap->cmap.data + 16 + 12 * n;
       start    = TT_NEXT_ULONG( p );
       end      = TT_NEXT_ULONG( p );
       glyph_id = TT_PEEK_ULONG( p );
@@ -2709,17 +2707,16 @@
 
         if ( gindex && gindex < (FT_UInt)face->num_glyphs )
         {
-          cmap->cur_charcode = char_code;
-          cmap->cur_gindex   = gindex;
-          cmap->cur_group    = n;
+          ttcmap->cur_charcode = char_code;
+          ttcmap->cur_gindex   = gindex;
+          ttcmap->cur_group    = n;
 
           return;
         }
       }
     }
 
-  Fail:
-    cmap->valid = 0;
+    ttcmap->valid = 0;
   }
 
 
@@ -2731,7 +2728,7 @@
     FT_UInt    gindex     = 0;
     FT_Byte*   p          = cmap->data + 12;
     FT_UInt32  num_groups = TT_PEEK_ULONG( p );
-    FT_UInt32  char_code  = *pchar_code;
+    FT_UInt32  char_code  = *pchar_code + next;
     FT_UInt32  start, end;
     FT_UInt32  max, min, mid;
 
@@ -2739,23 +2736,11 @@
     if ( !num_groups )
       return 0;
 
-    /* make compiler happy */
-    mid = num_groups;
-    end = 0xFFFFFFFFUL;
-
-    if ( next )
-    {
-      if ( char_code >= 0xFFFFFFFFUL )
-        return 0;
-
-      char_code++;
-    }
-
     min = 0;
     max = num_groups;
 
     /* binary search */
-    while ( min < max )
+    do
     {
       mid = ( min + max ) >> 1;
       p   = cmap->data + 16 + 12 * mid;
@@ -2774,6 +2759,7 @@
         break;
       }
     }
+    while ( min < max );
 
     if ( next )
     {
@@ -2784,12 +2770,8 @@
       /* if `char_code' is not in any group, then `mid' is */
       /* the group nearest to `char_code'                  */
 
-      if ( char_code > end )
-      {
-        mid++;
-        if ( mid == num_groups )
-          return 0;
-      }
+      if ( char_code > end && ++mid == num_groups )
+        return 0;
 
       cmap13->valid        = 1;
       cmap13->cur_charcode = char_code;
@@ -2800,7 +2782,7 @@
 
       if ( !gindex )
       {
-        tt_cmap13_next( cmap13 );
+        tt_cmap13_next( FT_CMAP( cmap13 ) );
 
         if ( cmap13->valid )
           gindex = cmap13->cur_gindex;
@@ -2816,25 +2798,28 @@
 
 
   FT_CALLBACK_DEF( FT_UInt )
-  tt_cmap13_char_index( TT_CMap    cmap,
+  tt_cmap13_char_index( FT_CMap    cmap,       /* TT_CMap */
                         FT_UInt32  char_code )
   {
-    return tt_cmap13_char_map_binary( cmap, &char_code, 0 );
+    return tt_cmap13_char_map_binary( (TT_CMap)cmap, &char_code, 0 );
   }
 
 
-  FT_CALLBACK_DEF( FT_UInt32 )
-  tt_cmap13_char_next( TT_CMap     cmap,
+  FT_CALLBACK_DEF( FT_UInt )
+  tt_cmap13_char_next( FT_CMap     cmap,        /* TT_CMap13 */
                        FT_UInt32  *pchar_code )
   {
     TT_CMap13  cmap13 = (TT_CMap13)cmap;
     FT_UInt    gindex;
 
 
+    if ( *pchar_code >= 0xFFFFFFFFUL )
+      return 0;
+
     /* no need to search */
     if ( cmap13->valid && cmap13->cur_charcode == *pchar_code )
     {
-      tt_cmap13_next( cmap13 );
+      tt_cmap13_next( FT_CMAP( cmap13 ) );
       if ( cmap13->valid )
       {
         gindex      = cmap13->cur_gindex;
@@ -2844,17 +2829,18 @@
         gindex = 0;
     }
     else
-      gindex = tt_cmap13_char_map_binary( cmap, pchar_code, 1 );
+      gindex = tt_cmap13_char_map_binary( (TT_CMap)cmap, pchar_code, 1 );
 
     return gindex;
   }
 
 
   FT_CALLBACK_DEF( FT_Error )
-  tt_cmap13_get_info( TT_CMap       cmap,
+  tt_cmap13_get_info( FT_CharMap    cmap,       /* TT_CMap */
                       TT_CMapInfo  *cmap_info )
   {
-    FT_Byte*  p = cmap->data + 8;
+    TT_CMap   ttcmap = (TT_CMap)cmap;
+    FT_Byte*  p      = ttcmap->data + 8;
 
 
     cmap_info->format   = 13;
@@ -2969,14 +2955,15 @@
 
 
   FT_CALLBACK_DEF( void )
-  tt_cmap14_done( TT_CMap14  cmap )
+  tt_cmap14_done( FT_CMap  cmap )    /* TT_CMap14 */
   {
-    FT_Memory  memory = cmap->memory;
+    TT_CMap14  ttcmap = (TT_CMap14)cmap;
+    FT_Memory  memory = ttcmap->memory;
 
 
-    cmap->max_results = 0;
-    if ( memory && cmap->results )
-      FT_FREE( cmap->results );
+    ttcmap->max_results = 0;
+    if ( memory && ttcmap->results )
+      FT_FREE( ttcmap->results );
   }
 
 
@@ -3004,15 +2991,19 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  tt_cmap14_init( TT_CMap14  cmap,
-                  FT_Byte*   table )
+  tt_cmap14_init( FT_CMap  cmap,    /* TT_CMap14 */
+                  void*    table_ )
   {
-    cmap->cmap.data = table;
+    TT_CMap14  ttcmap = (TT_CMap14)cmap;
+    FT_Byte*   table  = (FT_Byte*)table_;
 
-    table               += 6;
-    cmap->num_selectors  = FT_PEEK_ULONG( table );
-    cmap->max_results    = 0;
-    cmap->results        = NULL;
+
+    ttcmap->cmap.data = table;
+
+    table                 += 6;
+    ttcmap->num_selectors  = FT_PEEK_ULONG( table );
+    ttcmap->max_results    = 0;
+    ttcmap->results        = NULL;
 
     return FT_Err_Ok;
   }
@@ -3142,7 +3133,7 @@
 
 
   FT_CALLBACK_DEF( FT_UInt )
-  tt_cmap14_char_index( TT_CMap    cmap,
+  tt_cmap14_char_index( FT_CMap    cmap,
                         FT_UInt32  char_code )
   {
     FT_UNUSED( cmap );
@@ -3153,8 +3144,8 @@
   }
 
 
-  FT_CALLBACK_DEF( FT_UInt32 )
-  tt_cmap14_char_next( TT_CMap     cmap,
+  FT_CALLBACK_DEF( FT_UInt )
+  tt_cmap14_char_next( FT_CMap     cmap,
                        FT_UInt32  *pchar_code )
   {
     FT_UNUSED( cmap );
@@ -3166,7 +3157,7 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  tt_cmap14_get_info( TT_CMap       cmap,
+  tt_cmap14_get_info( FT_CharMap    cmap,
                       TT_CMapInfo  *cmap_info )
   {
     FT_UNUSED( cmap );
@@ -3280,12 +3271,16 @@
 
 
   FT_CALLBACK_DEF( FT_UInt )
-  tt_cmap14_char_var_index( TT_CMap    cmap,
-                            TT_CMap    ucmap,
+  tt_cmap14_char_var_index( FT_CMap    cmap,             /* TT_CMap */
+                            FT_CMap    ucmap,            /* TT_CMap */
                             FT_UInt32  charcode,
                             FT_UInt32  variantSelector )
   {
-    FT_Byte*  p = tt_cmap14_find_variant( cmap->data + 6, variantSelector );
+    TT_CMap  ttcmap  = (TT_CMap)cmap;
+    TT_CMap  ttucmap = (TT_CMap)ucmap;
+
+    FT_Byte*  p = tt_cmap14_find_variant( ttcmap->data + 6,
+                                          variantSelector );
     FT_ULong  defOff;
     FT_ULong  nondefOff;
 
@@ -3296,16 +3291,16 @@
     defOff    = TT_NEXT_ULONG( p );
     nondefOff = TT_PEEK_ULONG( p );
 
-    if ( defOff != 0                                                    &&
-         tt_cmap14_char_map_def_binary( cmap->data + defOff, charcode ) )
+    if ( defOff != 0                                                      &&
+         tt_cmap14_char_map_def_binary( ttcmap->data + defOff, charcode ) )
     {
       /* This is the default variant of this charcode.  GID not stored */
       /* here; stored in the normal Unicode charmap instead.           */
-      return ucmap->cmap.clazz->char_index( &ucmap->cmap, charcode );
+      return ttucmap->cmap.clazz->char_index( &ttucmap->cmap, charcode );
     }
 
     if ( nondefOff != 0 )
-      return tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff,
+      return tt_cmap14_char_map_nondef_binary( ttcmap->data + nondefOff,
                                                charcode );
 
     return 0;
@@ -3313,11 +3308,13 @@
 
 
   FT_CALLBACK_DEF( FT_Int )
-  tt_cmap14_char_var_isdefault( TT_CMap    cmap,
+  tt_cmap14_char_var_isdefault( FT_CMap    cmap,             /* TT_CMap */
                                 FT_UInt32  charcode,
                                 FT_UInt32  variantSelector )
   {
-    FT_Byte*  p = tt_cmap14_find_variant( cmap->data + 6, variantSelector );
+    TT_CMap   ttcmap = (TT_CMap)cmap;
+    FT_Byte*  p      = tt_cmap14_find_variant( ttcmap->data + 6,
+                                               variantSelector );
     FT_ULong  defOff;
     FT_ULong  nondefOff;
 
@@ -3328,13 +3325,13 @@
     defOff    = TT_NEXT_ULONG( p );
     nondefOff = TT_NEXT_ULONG( p );
 
-    if ( defOff != 0                                                    &&
-         tt_cmap14_char_map_def_binary( cmap->data + defOff, charcode ) )
+    if ( defOff != 0                                                      &&
+         tt_cmap14_char_map_def_binary( ttcmap->data + defOff, charcode ) )
       return 1;
 
-    if ( nondefOff != 0                                            &&
-         tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff,
-                                           charcode ) != 0         )
+    if ( nondefOff != 0                                              &&
+         tt_cmap14_char_map_nondef_binary( ttcmap->data + nondefOff,
+                                           charcode ) != 0           )
       return 0;
 
     return -1;
@@ -3342,12 +3339,13 @@
 
 
   FT_CALLBACK_DEF( FT_UInt32* )
-  tt_cmap14_variants( TT_CMap    cmap,
+  tt_cmap14_variants( FT_CMap    cmap,    /* TT_CMap14 */
                       FT_Memory  memory )
   {
+    TT_CMap     ttcmap = (TT_CMap)cmap;
     TT_CMap14   cmap14 = (TT_CMap14)cmap;
     FT_UInt32   count  = cmap14->num_selectors;
-    FT_Byte*    p      = cmap->data + 10;
+    FT_Byte*    p      = ttcmap->data + 10;
     FT_UInt32*  result;
     FT_UInt32   i;
 
@@ -3368,13 +3366,14 @@
 
 
   FT_CALLBACK_DEF( FT_UInt32 * )
-  tt_cmap14_char_variants( TT_CMap    cmap,
+  tt_cmap14_char_variants( FT_CMap    cmap,      /* TT_CMap14 */
                            FT_Memory  memory,
                            FT_UInt32  charCode )
   {
-    TT_CMap14   cmap14 = (TT_CMap14)  cmap;
+    TT_CMap     ttcmap = (TT_CMap)cmap;
+    TT_CMap14   cmap14 = (TT_CMap14)cmap;
     FT_UInt32   count  = cmap14->num_selectors;
-    FT_Byte*    p      = cmap->data + 10;
+    FT_Byte*    p      = ttcmap->data + 10;
     FT_UInt32*  q;
 
 
@@ -3388,12 +3387,12 @@
       FT_ULong   nondefOff = TT_NEXT_ULONG( p );
 
 
-      if ( ( defOff != 0                                               &&
-             tt_cmap14_char_map_def_binary( cmap->data + defOff,
-                                            charCode )                 ) ||
-           ( nondefOff != 0                                            &&
-             tt_cmap14_char_map_nondef_binary( cmap->data + nondefOff,
-                                               charCode ) != 0         ) )
+      if ( ( defOff != 0                                                 &&
+             tt_cmap14_char_map_def_binary( ttcmap->data + defOff,
+                                            charCode )                   ) ||
+           ( nondefOff != 0                                              &&
+             tt_cmap14_char_map_nondef_binary( ttcmap->data + nondefOff,
+                                               charCode ) != 0           ) )
       {
         q[0] = varSel;
         q++;
@@ -3489,15 +3488,16 @@
 
 
   FT_CALLBACK_DEF( FT_UInt32 * )
-  tt_cmap14_variant_chars( TT_CMap    cmap,
+  tt_cmap14_variant_chars( FT_CMap    cmap,             /* TT_CMap */
                            FT_Memory  memory,
                            FT_UInt32  variantSelector )
   {
-    FT_Byte    *p  = tt_cmap14_find_variant( cmap->data + 6,
-                                             variantSelector );
-    FT_Int      i;
-    FT_ULong    defOff;
-    FT_ULong    nondefOff;
+    TT_CMap   ttcmap = (TT_CMap)cmap;
+    FT_Byte  *p      = tt_cmap14_find_variant( ttcmap->data + 6,
+                                               variantSelector );
+    FT_Int    i;
+    FT_ULong  defOff;
+    FT_ULong  nondefOff;
 
 
     if ( !p )
@@ -3510,16 +3510,16 @@
       return NULL;
 
     if ( defOff == 0 )
-      return tt_cmap14_get_nondef_chars( cmap, cmap->data + nondefOff,
+      return tt_cmap14_get_nondef_chars( ttcmap, ttcmap->data + nondefOff,
                                          memory );
     else if ( nondefOff == 0 )
-      return tt_cmap14_get_def_chars( cmap, cmap->data + defOff,
+      return tt_cmap14_get_def_chars( ttcmap, ttcmap->data + defOff,
                                       memory );
     else
     {
       /* Both a default and a non-default glyph set?  That's probably not */
       /* good font design, but the spec allows for it...                  */
-      TT_CMap14  cmap14 = (TT_CMap14) cmap;
+      TT_CMap14  cmap14 = (TT_CMap14)cmap;
       FT_UInt32  numRanges;
       FT_UInt32  numMappings;
       FT_UInt32  duni;
@@ -3531,18 +3531,18 @@
       FT_UInt32  *ret;
 
 
-      p  = cmap->data + nondefOff;
-      dp = cmap->data + defOff;
+      p  = ttcmap->data + nondefOff;
+      dp = ttcmap->data + defOff;
 
       numMappings = (FT_UInt32)TT_NEXT_ULONG( p );
       dcnt        = tt_cmap14_def_char_count( dp );
       numRanges   = (FT_UInt32)TT_NEXT_ULONG( dp );
 
       if ( numMappings == 0 )
-        return tt_cmap14_get_def_chars( cmap, cmap->data + defOff,
+        return tt_cmap14_get_def_chars( ttcmap, ttcmap->data + defOff,
                                         memory );
       if ( dcnt == 0 )
-        return tt_cmap14_get_nondef_chars( cmap, cmap->data + nondefOff,
+        return tt_cmap14_get_nondef_chars( ttcmap, ttcmap->data + nondefOff,
                                            memory );
 
       if ( tt_cmap14_ensure( cmap14, ( dcnt + numMappings + 1 ), memory ) )
@@ -3664,9 +3664,10 @@
 #ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
 
   FT_CALLBACK_DEF( const char * )
-  tt_get_glyph_name( TT_Face  face,
+  tt_get_glyph_name( void*    face_,   /* TT_Face */
                      FT_UInt  idx )
   {
+    TT_Face     face   = (TT_Face)face_;
     FT_String*  PSname = NULL;
 
 
@@ -3677,12 +3678,13 @@
 
 
   FT_CALLBACK_DEF( FT_Error )
-  tt_cmap_unicode_init( PS_Unicodes  unicodes,
-                        FT_Pointer   pointer )
+  tt_cmap_unicode_init( FT_CMap     cmap,     /* PS_Unicodes */
+                        FT_Pointer  pointer )
   {
-    TT_Face             face    = (TT_Face)FT_CMAP_FACE( unicodes );
-    FT_Memory           memory  = FT_FACE_MEMORY( face );
-    FT_Service_PsCMaps  psnames = (FT_Service_PsCMaps)face->psnames;
+    PS_Unicodes         unicodes = (PS_Unicodes)cmap;
+    TT_Face             face     = (TT_Face)FT_CMAP_FACE( cmap );
+    FT_Memory           memory   = FT_FACE_MEMORY( face );
+    FT_Service_PsCMaps  psnames  = (FT_Service_PsCMaps)face->psnames;
 
     FT_UNUSED( pointer );
 
@@ -3693,17 +3695,18 @@
     return psnames->unicodes_init( memory,
                                    unicodes,
                                    face->root.num_glyphs,
-                                   (PS_GetGlyphNameFunc)&tt_get_glyph_name,
+                                   &tt_get_glyph_name,
                                    (PS_FreeGlyphNameFunc)NULL,
                                    (FT_Pointer)face );
   }
 
 
   FT_CALLBACK_DEF( void )
-  tt_cmap_unicode_done( PS_Unicodes  unicodes )
+  tt_cmap_unicode_done( FT_CMap  cmap )    /* PS_Unicodes */
   {
-    FT_Face    face   = FT_CMAP_FACE( unicodes );
-    FT_Memory  memory = FT_FACE_MEMORY( face );
+    PS_Unicodes  unicodes = (PS_Unicodes)cmap;
+    FT_Face      face     = FT_CMAP_FACE( cmap );
+    FT_Memory    memory   = FT_FACE_MEMORY( face );
 
 
     FT_FREE( unicodes->maps );
@@ -3712,23 +3715,25 @@
 
 
   FT_CALLBACK_DEF( FT_UInt )
-  tt_cmap_unicode_char_index( PS_Unicodes  unicodes,
-                              FT_UInt32    char_code )
+  tt_cmap_unicode_char_index( FT_CMap    cmap,       /* PS_Unicodes */
+                              FT_UInt32  char_code )
   {
-    TT_Face             face    = (TT_Face)FT_CMAP_FACE( unicodes );
-    FT_Service_PsCMaps  psnames = (FT_Service_PsCMaps)face->psnames;
+    PS_Unicodes         unicodes = (PS_Unicodes)cmap;
+    TT_Face             face     = (TT_Face)FT_CMAP_FACE( cmap );
+    FT_Service_PsCMaps  psnames  = (FT_Service_PsCMaps)face->psnames;
 
 
     return psnames->unicodes_char_index( unicodes, char_code );
   }
 
 
-  FT_CALLBACK_DEF( FT_UInt32 )
-  tt_cmap_unicode_char_next( PS_Unicodes  unicodes,
-                             FT_UInt32   *pchar_code )
+  FT_CALLBACK_DEF( FT_UInt )
+  tt_cmap_unicode_char_next( FT_CMap     cmap,        /* PS_Unicodes */
+                             FT_UInt32  *pchar_code )
   {
-    TT_Face             face    = (TT_Face)FT_CMAP_FACE( unicodes );
-    FT_Service_PsCMaps  psnames = (FT_Service_PsCMaps)face->psnames;
+    PS_Unicodes         unicodes = (PS_Unicodes)cmap;
+    TT_Face             face     = (TT_Face)FT_CMAP_FACE( cmap );
+    FT_Service_PsCMaps  psnames  = (FT_Service_PsCMaps)face->psnames;
 
 
     return psnames->unicodes_char_next( unicodes, pchar_code );
@@ -3883,7 +3888,7 @@
   tt_get_cmap_info( FT_CharMap    charmap,
                     TT_CMapInfo  *cmap_info )
   {
-    FT_CMap        cmap  = (FT_CMap)charmap;
+    FT_CMap        cmap  = FT_CMAP( charmap );
     TT_CMap_Class  clazz = (TT_CMap_Class)cmap->clazz;
 
 
diff --git a/src/java.desktop/share/native/libfreetype/src/sfnt/ttcolr.c b/src/java.desktop/share/native/libfreetype/src/sfnt/ttcolr.c
index 5d98dca..281e713 100644
--- a/src/java.desktop/share/native/libfreetype/src/sfnt/ttcolr.c
+++ b/src/java.desktop/share/native/libfreetype/src/sfnt/ttcolr.c
@@ -229,7 +229,7 @@
 
       base_glyphs_offset_v1 = FT_NEXT_ULONG( p );
 
-      if ( base_glyphs_offset_v1 + 4 >= table_size )
+      if ( base_glyphs_offset_v1 >= table_size - 4 )
         goto InvalidTable;
 
       p1                 = (FT_Byte*)( table + base_glyphs_offset_v1 );
@@ -249,7 +249,7 @@
 
       if ( layer_offset_v1 )
       {
-        if ( layer_offset_v1 + 4 >= table_size )
+        if ( layer_offset_v1 >= table_size - 4 )
           goto InvalidTable;
 
         p1            = (FT_Byte*)( table + layer_offset_v1 );
@@ -699,7 +699,7 @@
                                              item_deltas ) )
           return 0;
 
-        apaint->u.solid.color.alpha += item_deltas[0];
+        apaint->u.solid.color.alpha += (FT_F2Dot14)item_deltas[0];
       }
 #endif
 
@@ -1646,7 +1646,7 @@
           return 0;
 
         color_stop->stop_offset += F2DOT14_TO_FIXED( item_deltas[0] );
-        color_stop->color.alpha += item_deltas[1];
+        color_stop->color.alpha += (FT_F2Dot14)item_deltas[1];
       }
 #else
       FT_UNUSED( var_index_base );
@@ -1914,7 +1914,7 @@
 #else /* !TT_CONFIG_OPTION_COLOR_LAYERS */
 
   /* ANSI C doesn't like empty source files */
-  typedef int  _tt_colr_dummy;
+  typedef int  tt_colr_dummy_;
 
 #endif /* !TT_CONFIG_OPTION_COLOR_LAYERS */
 
diff --git a/src/java.desktop/share/native/libfreetype/src/sfnt/ttcpal.c b/src/java.desktop/share/native/libfreetype/src/sfnt/ttcpal.c
index 4279bc0..46ae085 100644
--- a/src/java.desktop/share/native/libfreetype/src/sfnt/ttcpal.c
+++ b/src/java.desktop/share/native/libfreetype/src/sfnt/ttcpal.c
@@ -303,7 +303,7 @@
 #else /* !TT_CONFIG_OPTION_COLOR_LAYERS */
 
   /* ANSI C doesn't like empty source files */
-  typedef int  _tt_cpal_dummy;
+  typedef int  tt_cpal_dummy_;
 
 #endif /* !TT_CONFIG_OPTION_COLOR_LAYERS */
 
diff --git a/src/java.desktop/share/native/libfreetype/src/sfnt/ttload.c b/src/java.desktop/share/native/libfreetype/src/sfnt/ttload.c
index 14f625c..7b44e9c 100644
--- a/src/java.desktop/share/native/libfreetype/src/sfnt/ttload.c
+++ b/src/java.desktop/share/native/libfreetype/src/sfnt/ttload.c
@@ -504,6 +504,13 @@
 
     FT_FRAME_EXIT();
 
+    if ( !valid_entries )
+    {
+      FT_TRACE2(( "tt_face_load_font_dir: no valid tables found\n" ));
+      error = FT_THROW( Unknown_File_Format );
+      goto Exit;
+    }
+
     FT_TRACE2(( "table directory loaded\n" ));
     FT_TRACE2(( "\n" ));
 
diff --git a/src/java.desktop/share/native/libfreetype/src/sfnt/ttmtx.c b/src/java.desktop/share/native/libfreetype/src/sfnt/ttmtx.c
index 5e53e6d..38ee9ae 100644
--- a/src/java.desktop/share/native/libfreetype/src/sfnt/ttmtx.c
+++ b/src/java.desktop/share/native/libfreetype/src/sfnt/ttmtx.c
@@ -239,7 +239,7 @@
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
     FT_Service_MetricsVariations  var =
-      (FT_Service_MetricsVariations)face->var;
+      (FT_Service_MetricsVariations)face->tt_var;
 #endif
 
 
diff --git a/src/java.desktop/share/native/libfreetype/src/sfnt/ttpost.c b/src/java.desktop/share/native/libfreetype/src/sfnt/ttpost.c
index 0e17c6f..1dfad42 100644
--- a/src/java.desktop/share/native/libfreetype/src/sfnt/ttpost.c
+++ b/src/java.desktop/share/native/libfreetype/src/sfnt/ttpost.c
@@ -156,86 +156,66 @@
 
 
   static FT_Error
-  load_format_20( TT_Face    face,
-                  FT_Stream  stream,
-                  FT_ULong   post_len )
+  load_format_20( TT_Post_Names  names,
+                  FT_Stream      stream,
+                  FT_UShort      num_glyphs,
+                  FT_ULong       post_len )
   {
     FT_Memory   memory = stream->memory;
     FT_Error    error;
 
-    FT_Int      num_glyphs;
-    FT_UShort   num_names;
+    FT_UShort   n;
+    FT_UShort   num_names = 0;
 
     FT_UShort*  glyph_indices = NULL;
-    FT_Char**   name_strings  = NULL;
-    FT_Byte*    strings       = NULL;
+    FT_Byte**   name_strings  = NULL;
+    FT_Byte*    q;
 
 
-    if ( FT_READ_USHORT( num_glyphs ) )
-      goto Exit;
-
-    /* UNDOCUMENTED!  The number of glyphs in this table can be smaller */
-    /* than the value in the maxp table (cf. cyberbit.ttf).             */
-
-    /* There already exist fonts which have more than 32768 glyph names */
-    /* in this table, so the test for this threshold has been dropped.  */
-
-    if ( num_glyphs > face->max_profile.numGlyphs  ||
-         (FT_ULong)num_glyphs * 2UL > post_len - 2 )
+    if ( (FT_ULong)num_glyphs * 2 > post_len )
     {
       error = FT_THROW( Invalid_File_Format );
       goto Exit;
     }
 
-    /* load the indices */
+    /* load the indices and note their maximum */
+    if ( FT_QNEW_ARRAY( glyph_indices, num_glyphs ) ||
+         FT_FRAME_ENTER( num_glyphs * 2 )           )
+      goto Fail;
+
+    q = (FT_Byte*)stream->cursor;
+
+    for ( n = 0; n < num_glyphs; n++ )
     {
-      FT_Int  n;
+      FT_UShort  idx = FT_NEXT_USHORT( q );
 
 
-      if ( FT_QNEW_ARRAY( glyph_indices, num_glyphs ) ||
-           FT_FRAME_ENTER( num_glyphs * 2L )          )
-        goto Fail;
+      if ( idx > num_names )
+        num_names = idx;
 
-      for ( n = 0; n < num_glyphs; n++ )
-        glyph_indices[n] = FT_GET_USHORT();
-
-      FT_FRAME_EXIT();
+      glyph_indices[n] = idx;
     }
 
-    /* compute number of names stored in table */
-    {
-      FT_Int  n;
+    FT_FRAME_EXIT();
 
-
-      num_names = 0;
-
-      for ( n = 0; n < num_glyphs; n++ )
-      {
-        FT_Int  idx;
-
-
-        idx = glyph_indices[n];
-        if ( idx >= 258 )
-        {
-          idx -= 257;
-          if ( idx > num_names )
-            num_names = (FT_UShort)idx;
-        }
-      }
-    }
+    /* compute number of names stored in the table */
+    num_names = num_names > 257 ? num_names - 257 : 0;
 
     /* now load the name strings */
     if ( num_names )
     {
-      FT_UShort  n;
       FT_ULong   p;
+      FT_Byte*   strings;
 
 
-      post_len -= (FT_ULong)num_glyphs * 2UL + 2;
+      post_len -= (FT_ULong)num_glyphs * 2;
 
-      if ( FT_QALLOC( strings, post_len + 1 )       ||
-           FT_STREAM_READ( strings, post_len )      ||
-           FT_QNEW_ARRAY( name_strings, num_names ) )
+      if ( FT_QALLOC( name_strings, num_names * sizeof ( FT_Byte* ) +
+                                    post_len + 1 ) )
+        goto Fail;
+
+      strings = (FT_Byte*)( name_strings + num_names );
+      if ( FT_STREAM_READ( strings, post_len ) )
         goto Fail;
 
       /* convert from Pascal- to C-strings and set pointers */
@@ -251,7 +231,7 @@
         }
 
         strings[p]      = 0;
-        name_strings[n] = (FT_Char*)strings + p + 1;
+        name_strings[n] = strings + p + 1;
         p              += len + 1;
       }
       strings[post_len] = 0;
@@ -259,40 +239,24 @@
       /* deal with missing or insufficient string data */
       if ( n < num_names )
       {
-        if ( post_len == 0 )
-        {
-          /* fake empty string */
-          if ( FT_QREALLOC( strings, 1, 2 ) )
-            goto Fail;
+        FT_TRACE4(( "load_format_20: %hu PostScript names are truncated\n",
+                    num_names - n ));
 
-          post_len          = 1;
-          strings[post_len] = 0;
-        }
-
-        FT_ERROR(( "load_format_20:"
-                   " all entries in post table are already parsed,"
-                   " using NULL names for gid %d - %d\n",
-                    n, num_names - 1 ));
         for ( ; n < num_names; n++ )
-          name_strings[n] = (FT_Char*)strings + post_len;
+          name_strings[n] = strings + post_len;
       }
     }
 
     /* all right, set table fields and exit successfully */
-    {
-      TT_Post_20  table = &face->postscript_names.names.format_20;
+    names->num_glyphs    = num_glyphs;
+    names->num_names     = num_names;
+    names->glyph_indices = glyph_indices;
+    names->glyph_names   = name_strings;
 
-
-      table->num_glyphs    = (FT_UShort)num_glyphs;
-      table->num_names     = (FT_UShort)num_names;
-      table->glyph_indices = glyph_indices;
-      table->glyph_names   = name_strings;
-    }
     return FT_Err_Ok;
 
   Fail:
     FT_FREE( name_strings );
-    FT_FREE( strings );
     FT_FREE( glyph_indices );
 
   Exit:
@@ -301,66 +265,55 @@
 
 
   static FT_Error
-  load_format_25( TT_Face    face,
-                  FT_Stream  stream,
-                  FT_ULong   post_len )
+  load_format_25( TT_Post_Names  names,
+                  FT_Stream      stream,
+                  FT_UShort      num_glyphs,
+                  FT_ULong       post_len )
   {
     FT_Memory  memory = stream->memory;
     FT_Error   error;
 
-    FT_Int     num_glyphs;
-    FT_Char*   offset_table = NULL;
-
-    FT_UNUSED( post_len );
+    FT_UShort   n;
+    FT_UShort*  glyph_indices = NULL;
+    FT_Byte*    q;
 
 
-    if ( FT_READ_USHORT( num_glyphs ) )
-      goto Exit;
-
-    /* check the number of glyphs */
-    if ( num_glyphs > face->max_profile.numGlyphs ||
-         num_glyphs > 258                         ||
-         num_glyphs < 1                           )
+    /* check the number of glyphs, including the theoretical limit */
+    if ( num_glyphs > post_len  ||
+         num_glyphs > 258 + 128 )
     {
       error = FT_THROW( Invalid_File_Format );
       goto Exit;
     }
 
-    if ( FT_QNEW_ARRAY( offset_table, num_glyphs )  ||
-         FT_STREAM_READ( offset_table, num_glyphs ) )
+    /* load the indices and check their Mac range */
+    if ( FT_QNEW_ARRAY( glyph_indices, num_glyphs ) ||
+         FT_FRAME_ENTER( num_glyphs )               )
       goto Fail;
 
-    /* now check the offset table */
+    q = (FT_Byte*)stream->cursor;
+
+    for ( n = 0; n < num_glyphs; n++ )
     {
-      FT_Int  n;
+      FT_Int  idx = n + FT_NEXT_CHAR( q );
 
 
-      for ( n = 0; n < num_glyphs; n++ )
-      {
-        FT_Long  idx = (FT_Long)n + offset_table[n];
+      if ( idx < 0 || idx > 257 )
+        idx = 0;
 
-
-        if ( idx < 0 || idx > num_glyphs )
-        {
-          error = FT_THROW( Invalid_File_Format );
-          goto Fail;
-        }
-      }
+      glyph_indices[n] = (FT_UShort)idx;
     }
 
+    FT_FRAME_EXIT();
+
     /* OK, set table fields and exit successfully */
-    {
-      TT_Post_25  table = &face->postscript_names.names.format_25;
-
-
-      table->num_glyphs = (FT_UShort)num_glyphs;
-      table->offsets    = offset_table;
-    }
+    names->num_glyphs    = num_glyphs;
+    names->glyph_indices = glyph_indices;
 
     return FT_Err_Ok;
 
   Fail:
-    FT_FREE( offset_table );
+    FT_FREE( glyph_indices );
 
   Exit:
     return error;
@@ -370,37 +323,37 @@
   static FT_Error
   load_post_names( TT_Face  face )
   {
-    FT_Stream  stream;
-    FT_Error   error;
-    FT_Fixed   format;
+    FT_Error   error = FT_Err_Ok;
+    FT_Stream  stream = face->root.stream;
+    FT_Fixed   format = face->postscript.FormatType;
     FT_ULong   post_len;
+    FT_UShort  num_glyphs;
 
 
-    /* get a stream for the face's resource */
-    stream = face->root.stream;
-
     /* seek to the beginning of the PS names table */
     error = face->goto_table( face, TTAG_post, stream, &post_len );
     if ( error )
       goto Exit;
 
-    format = face->postscript.FormatType;
-
-    /* go to beginning of subtable */
-    if ( FT_STREAM_SKIP( 32 ) )
+    /* UNDOCUMENTED!  The number of glyphs in this table can be smaller */
+    /* than the value in the maxp table (cf. cyberbit.ttf).             */
+    if ( post_len < 34                            ||
+         FT_STREAM_SKIP( 32 )                     ||
+         FT_READ_USHORT( num_glyphs )             ||
+         num_glyphs > face->max_profile.numGlyphs ||
+         num_glyphs == 0 )
       goto Exit;
 
-    /* now read postscript table */
-    if ( format == 0x00020000L && post_len >= 34 )
-      error = load_format_20( face, stream, post_len - 32 );
-    else if ( format == 0x00025000L && post_len >= 34 )
-      error = load_format_25( face, stream, post_len - 32 );
-    else
-      error = FT_THROW( Invalid_File_Format );
-
-    face->postscript_names.loaded = 1;
+    /* now read postscript names data */
+    if ( format == 0x00020000L )
+      error = load_format_20( &face->postscript_names, stream,
+                              num_glyphs, post_len - 34 );
+    else if ( format == 0x00025000L )
+      error = load_format_25( &face->postscript_names, stream,
+                              num_glyphs, post_len - 34 );
 
   Exit:
+    face->postscript_names.loaded = 1;  /* even if failed */
     return error;
   }
 
@@ -410,39 +363,20 @@
   {
     FT_Memory      memory = face->root.memory;
     TT_Post_Names  names  = &face->postscript_names;
-    FT_Fixed       format;
 
 
-    if ( names->loaded )
+    if ( names->num_glyphs )
     {
-      format = face->postscript.FormatType;
-
-      if ( format == 0x00020000L )
-      {
-        TT_Post_20  table = &names->names.format_20;
-
-
-        FT_FREE( table->glyph_indices );
-        table->num_glyphs = 0;
-
-        if ( table->num_names )
-        {
-          table->glyph_names[0]--;
-          FT_FREE( table->glyph_names[0] );
-
-          FT_FREE( table->glyph_names );
-          table->num_names = 0;
-        }
-      }
-      else if ( format == 0x00025000L )
-      {
-        TT_Post_25  table = &names->names.format_25;
-
-
-        FT_FREE( table->offsets );
-        table->num_glyphs = 0;
-      }
+      FT_FREE( names->glyph_indices );
+      names->num_glyphs = 0;
     }
+
+    if ( names->num_names )
+    {
+      FT_FREE( names->glyph_names );
+      names->num_names = 0;
+    }
+
     names->loaded = 0;
   }
 
@@ -478,7 +412,6 @@
                        FT_String**  PSname )
   {
     FT_Error       error;
-    TT_Post_Names  names;
     FT_Fixed       format;
 
 #ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
@@ -498,8 +431,6 @@
       return FT_THROW( Unimplemented_Feature );
 #endif
 
-    names = &face->postscript_names;
-
     /* `.notdef' by default */
     *PSname = MAC_NAME( 0 );
 
@@ -510,9 +441,10 @@
       if ( idx < 258 )                    /* paranoid checking */
         *PSname = MAC_NAME( idx );
     }
-    else if ( format == 0x00020000L )
+    else if ( format == 0x00020000L ||
+              format == 0x00025000L )
     {
-      TT_Post_20  table = &names->names.format_20;
+      TT_Post_Names  names = &face->postscript_names;
 
 
       if ( !names->loaded )
@@ -522,43 +454,29 @@
           goto End;
       }
 
-      if ( idx < (FT_UInt)table->num_glyphs )
+      if ( idx < (FT_UInt)names->num_glyphs )
       {
-        FT_UShort  name_index = table->glyph_indices[idx];
+        FT_UShort  name_index = names->glyph_indices[idx];
 
 
         if ( name_index < 258 )
           *PSname = MAC_NAME( name_index );
-        else
-          *PSname = (FT_String*)table->glyph_names[name_index - 258];
+        else  /* only for version 2.0 */
+          *PSname = (FT_String*)names->glyph_names[name_index - 258];
       }
     }
-    else if ( format == 0x00025000L )
-    {
-      TT_Post_25  table = &names->names.format_25;
-
-
-      if ( !names->loaded )
-      {
-        error = load_post_names( face );
-        if ( error )
-          goto End;
-      }
-
-      if ( idx < (FT_UInt)table->num_glyphs )    /* paranoid checking */
-        *PSname = MAC_NAME( (FT_Int)idx + table->offsets[idx] );
-    }
 
     /* nothing to do for format == 0x00030000L */
 
   End:
+    /* post format errors ignored */
     return FT_Err_Ok;
   }
 
 #else /* !TT_CONFIG_OPTION_POSTSCRIPT_NAMES */
 
   /* ANSI C doesn't like empty source files */
-  typedef int  _tt_post_dummy;
+  typedef int  tt_post_dummy_;
 
 #endif /* !TT_CONFIG_OPTION_POSTSCRIPT_NAMES */
 
diff --git a/src/java.desktop/share/native/libfreetype/src/sfnt/ttsbit.c b/src/java.desktop/share/native/libfreetype/src/sfnt/ttsbit.c
index 3c06955..03f90a6 100644
--- a/src/java.desktop/share/native/libfreetype/src/sfnt/ttsbit.c
+++ b/src/java.desktop/share/native/libfreetype/src/sfnt/ttsbit.c
@@ -1677,7 +1677,7 @@
 #else /* !TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
 
   /* ANSI C doesn't like empty source files */
-  typedef int  _tt_sbit_dummy;
+  typedef int  tt_sbit_dummy_;
 
 #endif /* !TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
 
diff --git a/src/java.desktop/share/native/libfreetype/src/sfnt/woff2tags.c b/src/java.desktop/share/native/libfreetype/src/sfnt/woff2tags.c
index 7a0a351..eeedd99 100644
--- a/src/java.desktop/share/native/libfreetype/src/sfnt/woff2tags.c
+++ b/src/java.desktop/share/native/libfreetype/src/sfnt/woff2tags.c
@@ -111,7 +111,7 @@
 #else /* !FT_CONFIG_OPTION_USE_BROTLI */
 
   /* ANSI C doesn't like empty source files */
-  typedef int  _woff2tags_dummy;
+  typedef int  woff2tags_dummy_;
 
 #endif /* !FT_CONFIG_OPTION_USE_BROTLI */
 
diff --git a/src/java.desktop/share/native/libfreetype/src/smooth/ftgrays.c b/src/java.desktop/share/native/libfreetype/src/smooth/ftgrays.c
index d9f20ee..0918272 100644
--- a/src/java.desktop/share/native/libfreetype/src/smooth/ftgrays.c
+++ b/src/java.desktop/share/native/libfreetype/src/smooth/ftgrays.c
@@ -1006,10 +1006,11 @@
    *
    * For other cases, using binary splits is actually slightly faster.
    */
-#if defined( __SSE2__ )                          || \
-    defined( __x86_64__ )                        || \
-    defined( _M_AMD64 )                          || \
-    ( defined( _M_IX86_FP ) && _M_IX86_FP >= 2 )
+#if ( defined( __SSE2__ )                          ||   \
+      defined( __x86_64__ )                        ||   \
+      defined( _M_AMD64 )                          ||   \
+      ( defined( _M_IX86_FP ) && _M_IX86_FP >= 2 ) ) && \
+    !defined( __VMS )
 #  define FT_SSE2 1
 #else
 #  define FT_SSE2 0
@@ -1427,8 +1428,10 @@
 
   static int
   gray_move_to( const FT_Vector*  to,
-                gray_PWorker      worker )
+                void*             worker_ )  /* gray_PWorker */
   {
+    gray_PWorker  worker = (gray_PWorker)worker_;
+
     TPos  x, y;
 
 
@@ -1446,8 +1449,11 @@
 
   static int
   gray_line_to( const FT_Vector*  to,
-                gray_PWorker      worker )
+                void*             worker_ )   /* gray_PWorker */
   {
+    gray_PWorker  worker = (gray_PWorker)worker_;
+
+
     gray_render_line( RAS_VAR_ UPSCALE( to->x ), UPSCALE( to->y ) );
     return 0;
   }
@@ -1456,8 +1462,11 @@
   static int
   gray_conic_to( const FT_Vector*  control,
                  const FT_Vector*  to,
-                 gray_PWorker      worker )
+                 void*             worker_ )   /* gray_PWorker */
   {
+    gray_PWorker  worker = (gray_PWorker)worker_;
+
+
     gray_render_conic( RAS_VAR_ control, to );
     return 0;
   }
@@ -1467,8 +1476,11 @@
   gray_cubic_to( const FT_Vector*  control1,
                  const FT_Vector*  control2,
                  const FT_Vector*  to,
-                 gray_PWorker      worker )
+                 void*             worker_ )   /* gray_PWorker */
   {
+    gray_PWorker  worker = (gray_PWorker)worker_;
+
+
     gray_render_cubic( RAS_VAR_ control1, control2, to );
     return 0;
   }
@@ -1666,6 +1678,8 @@
 
     int   n;         /* index of contour in outline     */
     int   first;     /* index of first point in contour */
+    int   last;      /* index of last point in contour  */
+
     char  tag;       /* current point's state           */
 
     int   shift;
@@ -1680,18 +1694,17 @@
 
     shift = func_interface->shift;
     delta = func_interface->delta;
-    first = 0;
 
+    last = -1;
     for ( n = 0; n < outline->n_contours; n++ )
     {
-      int  last;  /* index of last point in contour */
+      FT_TRACE5(( "FT_Outline_Decompose: Contour %d\n", n ));
 
-
-      FT_TRACE5(( "FT_Outline_Decompose: Outline %d\n", n ));
-
+      first = last + 1;
       last  = outline->contours[n];
-      if ( last < 0 )
+      if ( last < first )
         goto Invalid_Outline;
+
       limit = outline->points + last;
 
       v_start   = outline->points[first];
@@ -1874,11 +1887,9 @@
                   v_start.x / 64.0, v_start.y / 64.0 ));
       error = func_interface->line_to( &v_start, user );
 
-   Close:
+    Close:
       if ( error )
         goto Exit;
-
-      first = last + 1;
     }
 
     FT_TRACE5(( "FT_Outline_Decompose: Done\n", n ));
@@ -1923,7 +1934,7 @@
       if ( continued )
         FT_Trace_Enable();
 
-      FT_TRACE7(( "band [%d..%d]: %ld cell%s remaining/\n",
+      FT_TRACE7(( "band [%d..%d]: %td cell%s remaining/\n",
                   ras.min_ey,
                   ras.max_ey,
                   ras.cell_null - ras.cell_free,
@@ -2156,9 +2167,12 @@
 #else /* !STANDALONE_ */
 
   static int
-  gray_raster_new( FT_Memory      memory,
-                   gray_PRaster*  araster )
+  gray_raster_new( void*       memory_,
+                   FT_Raster*  araster_ )
   {
+    FT_Memory      memory  = (FT_Memory)memory_;
+    gray_PRaster*  araster = (gray_PRaster*)araster_;
+
     FT_Error      error;
     gray_PRaster  raster = NULL;
 
diff --git a/src/java.desktop/share/native/libfreetype/src/smooth/ftsmooth.c b/src/java.desktop/share/native/libfreetype/src/smooth/ftsmooth.c
index cdbc78c..9b0e888 100644
--- a/src/java.desktop/share/native/libfreetype/src/smooth/ftsmooth.c
+++ b/src/java.desktop/share/native/libfreetype/src/smooth/ftsmooth.c
@@ -87,8 +87,10 @@
 
   /* initialize renderer -- init its raster */
   static FT_Error
-  ft_smooth_init( FT_Renderer  render )
+  ft_smooth_init( FT_Module  module )   /* FT_Renderer */
   {
+    FT_Renderer  render = (FT_Renderer)module;
+
     FT_Vector*  sub = render->root.library->lcd_geometry;
 
 
@@ -111,8 +113,10 @@
   ft_smooth_lcd_spans( int             y,
                        int             count,
                        const FT_Span*  spans,
-                       TOrigin*        target )
+                       void*           target_ )   /* TOrigin* */
   {
+    TOrigin*  target = (TOrigin*)target_;
+
     unsigned char*  dst_line = target->origin - y * target->pitch;
     unsigned char*  dst;
     unsigned short  w;
@@ -141,7 +145,7 @@
     /* Set up direct rendering to record them on each third byte. */
     params.source     = outline;
     params.flags      = FT_RASTER_FLAG_AA | FT_RASTER_FLAG_DIRECT;
-    params.gray_spans = (FT_SpanFunc)ft_smooth_lcd_spans;
+    params.gray_spans = ft_smooth_lcd_spans;
     params.user       = &target;
 
     params.clip_box.xMin = 0;
@@ -256,8 +260,11 @@
 
   /* initialize renderer -- init its raster */
   static FT_Error
-  ft_smooth_init( FT_Renderer  render )
+  ft_smooth_init( FT_Module  module )   /* FT_Renderer */
   {
+    FT_Renderer  render = (FT_Renderer)module;
+
+
     /* set up default LCD filtering */
     FT_Library_SetLcdFilter( render->root.library, FT_LCD_FILTER_DEFAULT );
 
@@ -340,8 +347,11 @@
   ft_smooth_overlap_spans( int             y,
                            int             count,
                            const FT_Span*  spans,
-                           TOrigin*        target )
+                           void*           target_ )
   {
+    TOrigin*  target = (TOrigin*)target_;
+
+
     unsigned char*  dst = target->origin - ( y / SCALE ) * target->pitch;
     unsigned short  x;
     unsigned int    cover, sum;
@@ -386,7 +396,7 @@
     /* Set up direct rendering to average oversampled spans. */
     params.source     = outline;
     params.flags      = FT_RASTER_FLAG_AA | FT_RASTER_FLAG_DIRECT;
-    params.gray_spans = (FT_SpanFunc)ft_smooth_overlap_spans;
+    params.gray_spans = ft_smooth_overlap_spans;
     params.user       = &target;
 
     params.clip_box.xMin = 0;
diff --git a/src/java.desktop/share/native/libfreetype/src/truetype/ttdriver.c b/src/java.desktop/share/native/libfreetype/src/truetype/ttdriver.c
index 4bea63e..d1496fe 100644
--- a/src/java.desktop/share/native/libfreetype/src/truetype/ttdriver.c
+++ b/src/java.desktop/share/native/libfreetype/src/truetype/ttdriver.c
@@ -57,7 +57,7 @@
    * PROPERTY SERVICE
    *
    */
-  static FT_Error
+  FT_CALLBACK_DEF( FT_Error )
   tt_property_set( FT_Module    module,         /* TT_Driver */
                    const char*  property_name,
                    const void*  value,
@@ -93,17 +93,22 @@
         interpreter_version = *iv;
       }
 
-      if ( interpreter_version == TT_INTERPRETER_VERSION_35
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-           || interpreter_version == TT_INTERPRETER_VERSION_38
-#endif
+      switch ( interpreter_version )
+      {
+      case TT_INTERPRETER_VERSION_35:
+        driver->interpreter_version = TT_INTERPRETER_VERSION_35;
+        break;
+
+      case TT_INTERPRETER_VERSION_38:
+      case TT_INTERPRETER_VERSION_40:
 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
-           || interpreter_version == TT_INTERPRETER_VERSION_40
+        driver->interpreter_version = TT_INTERPRETER_VERSION_40;
+      break;
 #endif
-         )
-        driver->interpreter_version = interpreter_version;
-      else
+
+      default:
         error = FT_ERR( Unimplemented_Feature );
+      }
 
       return error;
     }
@@ -114,10 +119,10 @@
   }
 
 
-  static FT_Error
+  FT_CALLBACK_DEF( FT_Error )
   tt_property_get( FT_Module    module,         /* TT_Driver */
                    const char*  property_name,
-                   const void*  value )
+                   void*        value )
   {
     FT_Error   error  = FT_Err_Ok;
     TT_Driver  driver = (TT_Driver)module;
@@ -144,8 +149,8 @@
   FT_DEFINE_SERVICE_PROPERTIESREC(
     tt_service_properties,
 
-    (FT_Properties_SetFunc)tt_property_set,     /* set_property */
-    (FT_Properties_GetFunc)tt_property_get      /* get_property */
+    tt_property_set,  /* FT_Properties_SetFunc set_property */
+    tt_property_get   /* FT_Properties_GetFunc get_property */
   )
 
 
@@ -198,35 +203,35 @@
    *
    *   They can be implemented by format-specific interfaces.
    */
-  static FT_Error
-  tt_get_kerning( FT_Face     ttface,          /* TT_Face */
+  FT_CALLBACK_DEF( FT_Error )
+  tt_get_kerning( FT_Face     face,        /* TT_Face */
                   FT_UInt     left_glyph,
                   FT_UInt     right_glyph,
                   FT_Vector*  kerning )
   {
-    TT_Face       face = (TT_Face)ttface;
-    SFNT_Service  sfnt = (SFNT_Service)face->sfnt;
+    TT_Face       ttface = (TT_Face)face;
+    SFNT_Service  sfnt   = (SFNT_Service)ttface->sfnt;
 
 
     kerning->x = 0;
     kerning->y = 0;
 
     if ( sfnt )
-      kerning->x = sfnt->get_kerning( face, left_glyph, right_glyph );
+      kerning->x = sfnt->get_kerning( ttface, left_glyph, right_glyph );
 
     return 0;
   }
 
 
-  static FT_Error
-  tt_get_advances( FT_Face    ttface,
+  FT_CALLBACK_DEF( FT_Error )
+  tt_get_advances( FT_Face    face,      /* TT_Face */
                    FT_UInt    start,
                    FT_UInt    count,
                    FT_Int32   flags,
                    FT_Fixed  *advances )
   {
     FT_UInt  nn;
-    TT_Face  face = (TT_Face)ttface;
+    TT_Face  ttface = (TT_Face)face;
 
 
     /* XXX: TODO: check for sbits */
@@ -235,8 +240,8 @@
     {
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
       /* no fast retrieval for blended MM fonts without VVAR table */
-      if ( ( FT_IS_NAMED_INSTANCE( ttface ) || FT_IS_VARIATION( ttface ) ) &&
-           !( face->variation_support & TT_FACE_FLAG_VAR_VADVANCE )        )
+      if ( ( FT_IS_NAMED_INSTANCE( face ) || FT_IS_VARIATION( face ) ) &&
+           !( ttface->variation_support & TT_FACE_FLAG_VAR_VADVANCE )  )
         return FT_THROW( Unimplemented_Feature );
 #endif
 
@@ -247,7 +252,7 @@
 
 
         /* since we don't need `tsb', we use zero for `yMax' parameter */
-        TT_Get_VMetrics( face, start + nn, 0, &tsb, &ah );
+        TT_Get_VMetrics( ttface, start + nn, 0, &tsb, &ah );
         advances[nn] = ah;
       }
     }
@@ -255,8 +260,8 @@
     {
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
       /* no fast retrieval for blended MM fonts without HVAR table */
-      if ( ( FT_IS_NAMED_INSTANCE( ttface ) || FT_IS_VARIATION( ttface ) ) &&
-           !( face->variation_support & TT_FACE_FLAG_VAR_HADVANCE )        )
+      if ( ( FT_IS_NAMED_INSTANCE( face ) || FT_IS_VARIATION( face ) ) &&
+           !( ttface->variation_support & TT_FACE_FLAG_VAR_HADVANCE )  )
         return FT_THROW( Unimplemented_Feature );
 #endif
 
@@ -266,7 +271,7 @@
         FT_UShort  aw;
 
 
-        TT_Get_HMetrics( face, start + nn, &lsb, &aw );
+        TT_Get_HMetrics( ttface, start + nn, &lsb, &aw );
         advances[nn] = aw;
       }
     }
@@ -290,7 +295,7 @@
 
 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
 
-  static FT_Error
+  FT_CALLBACK_DEF( FT_Error )
   tt_size_select( FT_Size   size,
                   FT_ULong  strike_index )
   {
@@ -306,7 +311,7 @@
       /* use the scaled metrics, even when tt_size_reset fails */
       FT_Select_Metrics( size->face, strike_index );
 
-      tt_size_reset( ttsize, 0 ); /* ignore return value */
+      tt_size_reset( ttsize ); /* ignore return value */
     }
     else
     {
@@ -327,7 +332,7 @@
 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
 
 
-  static FT_Error
+  FT_CALLBACK_DEF( FT_Error )
   tt_size_request( FT_Size          size,
                    FT_Size_Request  req )
   {
@@ -367,7 +372,7 @@
 
     if ( FT_IS_SCALABLE( size->face ) )
     {
-      error = tt_size_reset( ttsize, 0 );
+      error = tt_size_reset( ttsize );
 
 #ifdef TT_USE_BYTECODE_INTERPRETER
       /* for the `MPS' bytecode instruction we need the point size */
@@ -426,15 +431,15 @@
    * @Return:
    *   FreeType error code.  0 means success.
    */
-  static FT_Error
-  tt_glyph_load( FT_GlyphSlot  ttslot,      /* TT_GlyphSlot */
-                 FT_Size       ttsize,      /* TT_Size      */
+  FT_CALLBACK_DEF( FT_Error )
+  tt_glyph_load( FT_GlyphSlot  slot,        /* TT_GlyphSlot */
+                 FT_Size       size,        /* TT_Size      */
                  FT_UInt       glyph_index,
                  FT_Int32      load_flags )
   {
-    TT_GlyphSlot  slot = (TT_GlyphSlot)ttslot;
-    TT_Size       size = (TT_Size)ttsize;
-    FT_Face       face = ttslot->face;
+    TT_GlyphSlot  ttslot = (TT_GlyphSlot)slot;
+    TT_Size       ttsize = (TT_Size)size;
+    FT_Face       face   = ttslot->face;
     FT_Error      error;
 
 
@@ -476,12 +481,12 @@
     }
 
     /* use hinted metrics only if we load a glyph with hinting */
-    size->metrics = ( load_flags & FT_LOAD_NO_HINTING )
-                      ? &ttsize->metrics
-                      : &size->hinted_metrics;
+    ttsize->metrics = ( load_flags & FT_LOAD_NO_HINTING )
+                        ? &size->metrics
+                        : &ttsize->hinted_metrics;
 
     /* now fill in the glyph slot with outline/bitmap/layered */
-    error = TT_Load_Glyph( size, slot, glyph_index, load_flags );
+    error = TT_Load_Glyph( ttsize, ttslot, glyph_index, load_flags );
 
     /* force drop-out mode to 2 - irrelevant now */
     /* slot->outline.dropout_mode = 2; */
@@ -507,49 +512,47 @@
   FT_DEFINE_SERVICE_MULTIMASTERSREC(
     tt_service_gx_multi_masters,
 
-    (FT_Get_MM_Func)        NULL,                  /* get_mm                    */
-    (FT_Set_MM_Design_Func) NULL,                  /* set_mm_design             */
-    (FT_Set_MM_Blend_Func)  TT_Set_MM_Blend,       /* set_mm_blend              */
-    (FT_Get_MM_Blend_Func)  TT_Get_MM_Blend,       /* get_mm_blend              */
-    (FT_Get_MM_Var_Func)    TT_Get_MM_Var,         /* get_mm_var                */
-    (FT_Set_Var_Design_Func)TT_Set_Var_Design,     /* set_var_design            */
-    (FT_Get_Var_Design_Func)TT_Get_Var_Design,     /* get_var_design            */
-    (FT_Set_Instance_Func)  TT_Set_Named_Instance, /* set_instance              */
-    (FT_Set_MM_WeightVector_Func)
-                            NULL,                  /* set_mm_weightvector       */
-    (FT_Get_MM_WeightVector_Func)
-                            NULL,                  /* get_mm_weightvector       */
-    (FT_Var_Load_Delta_Set_Idx_Map_Func)
-                            tt_var_load_delta_set_index_mapping,
-                                                   /* load_delta_set_idx_map    */
-    (FT_Var_Load_Item_Var_Store_Func)
-                            tt_var_load_item_variation_store,
-                                                   /* load_item_variation_store */
-    (FT_Var_Get_Item_Delta_Func)
-                            tt_var_get_item_delta, /* get_item_delta            */
-    (FT_Var_Done_Item_Var_Store_Func)
-                            tt_var_done_item_variation_store,
-                                                   /* done_item_variation_store */
-    (FT_Var_Done_Delta_Set_Idx_Map_Func)
-                            tt_var_done_delta_set_index_map,
-                                                   /* done_delta_set_index_map  */
-    (FT_Get_Var_Blend_Func) tt_get_var_blend,      /* get_var_blend             */
-    (FT_Done_Blend_Func)    tt_done_blend          /* done_blend                */
+    NULL,                  /* FT_Get_MM_Func              get_mm                     */
+    NULL,                  /* FT_Set_MM_Design_Func       set_mm_design              */
+    TT_Set_MM_Blend,       /* FT_Set_MM_Blend_Func        set_mm_blend               */
+    TT_Get_MM_Blend,       /* FT_Get_MM_Blend_Func        get_mm_blend               */
+    TT_Get_MM_Var,         /* FT_Get_MM_Var_Func          get_mm_var                 */
+    TT_Set_Var_Design,     /* FT_Set_Var_Design_Func      set_var_design             */
+    TT_Get_Var_Design,     /* FT_Get_Var_Design_Func      get_var_design             */
+    TT_Set_Named_Instance, /* FT_Set_Named_Instance_Func  set_named_instance         */
+    TT_Get_Default_Named_Instance,
+                    /* FT_Get_Default_Named_Instance_Func get_default_named_instance */
+    NULL,                  /* FT_Set_MM_WeightVector_Func set_mm_weightvector        */
+    NULL,                  /* FT_Get_MM_WeightVector_Func get_mm_weightvector        */
+
+    tt_construct_ps_name,  /* FT_Construct_PS_Name_Func   construct_ps_name          */
+    tt_var_load_delta_set_index_mapping,
+                    /* FT_Var_Load_Delta_Set_Idx_Map_Func load_delta_set_idx_map     */
+    tt_var_load_item_variation_store,
+                    /* FT_Var_Load_Item_Var_Store_Func    load_item_variation_store  */
+    tt_var_get_item_delta, /* FT_Var_Get_Item_Delta_Func  get_item_delta             */
+    tt_var_done_item_variation_store,
+                    /* FT_Var_Done_Item_Var_Store_Func    done_item_variation_store  */
+    tt_var_done_delta_set_index_map,
+                    /* FT_Var_Done_Delta_Set_Idx_Map_Func done_delta_set_index_map   */
+    tt_get_var_blend,      /* FT_Get_Var_Blend_Func       get_var_blend              */
+    tt_done_blend          /* FT_Done_Blend_Func          done_blend                 */
   )
 
   FT_DEFINE_SERVICE_METRICSVARIATIONSREC(
     tt_service_metrics_variations,
 
-    (FT_HAdvance_Adjust_Func)tt_hadvance_adjust,     /* hadvance_adjust */
-    (FT_LSB_Adjust_Func)     NULL,                   /* lsb_adjust      */
-    (FT_RSB_Adjust_Func)     NULL,                   /* rsb_adjust      */
+    tt_hadvance_adjust,   /* FT_HAdvance_Adjust_Func hadvance_adjust */
+    NULL,                 /* FT_LSB_Adjust_Func      lsb_adjust      */
+    NULL,                 /* FT_RSB_Adjust_Func      rsb_adjust      */
 
-    (FT_VAdvance_Adjust_Func)tt_vadvance_adjust,     /* vadvance_adjust */
-    (FT_TSB_Adjust_Func)     NULL,                   /* tsb_adjust      */
-    (FT_BSB_Adjust_Func)     NULL,                   /* bsb_adjust      */
-    (FT_VOrg_Adjust_Func)    NULL,                   /* vorg_adjust     */
+    tt_vadvance_adjust,   /* FT_VAdvance_Adjust_Func vadvance_adjust */
+    NULL,                 /* FT_TSB_Adjust_Func      tsb_adjust      */
+    NULL,                 /* FT_BSB_Adjust_Func      bsb_adjust      */
+    NULL,                 /* FT_VOrg_Adjust_Func     vorg_adjust     */
 
-    (FT_Metrics_Adjust_Func) tt_apply_mvar           /* metrics_adjust  */
+    tt_apply_mvar,        /* FT_Metrics_Adjust_Func  metrics_adjust  */
+    tt_size_reset_height  /* FT_Size_Reset_Func      size_reset      */
   )
 
 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
diff --git a/src/java.desktop/share/native/libfreetype/src/truetype/ttgload.c b/src/java.desktop/share/native/libfreetype/src/truetype/ttgload.c
index d33bdad..dc427e8 100644
--- a/src/java.desktop/share/native/libfreetype/src/truetype/ttgload.c
+++ b/src/java.desktop/share/native/libfreetype/src/truetype/ttgload.c
@@ -35,7 +35,6 @@
 #endif
 
 #include "tterrors.h"
-#include "ttsubpix.h"
 
 
   /**************************************************************************
@@ -152,9 +151,6 @@
                   FT_UInt    glyph_index )
   {
     TT_Face    face   = loader->face;
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    TT_Driver  driver = (TT_Driver)FT_FACE_DRIVER( face );
-#endif
 
     FT_Error   error;
     FT_Stream  stream = loader->stream;
@@ -183,20 +179,6 @@
     loader->top_bearing  = top_bearing;
     loader->vadvance     = advance_height;
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 &&
-         loader->exec                                             )
-    {
-      loader->exec->sph_tweak_flags = 0;
-
-      /* This may not be the right place for this, but it works...  */
-      /* Note that we have to unconditionally load the tweaks since */
-      /* it is possible that glyphs individually switch ClearType's */
-      /* backward compatibility mode on and off.                    */
-      sph_set_tweaks( loader, glyph_index );
-    }
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
 #ifdef FT_CONFIG_OPTION_INCREMENTAL
     /* With the incremental interface, these values are set by  */
     /* a call to `tt_get_metrics_incremental'.                  */
@@ -362,17 +344,16 @@
     FT_Byte*        p          = load->cursor;
     FT_Byte*        limit      = load->limit;
     FT_GlyphLoader  gloader    = load->gloader;
+    FT_Outline*     outline    = &gloader->current.outline;
     FT_Int          n_contours = load->n_contours;
-    FT_Outline*     outline;
-    FT_UShort       n_ins;
     FT_Int          n_points;
+    FT_UShort       n_ins;
 
     FT_Byte         *flag, *flag_limit;
     FT_Byte         c, count;
     FT_Vector       *vec, *vec_limit;
     FT_Pos          x, y;
-    FT_Short        *cont, *cont_limit, prev_cont;
-    FT_Int          xy_size = 0;
+    FT_Short        *cont, *cont_limit, last;
 
 
     /* check that we can add the contours to the glyph */
@@ -380,40 +361,26 @@
     if ( error )
       goto Fail;
 
+    /* check space for contours array + instructions count */
+    if ( n_contours >= 0xFFF || p + 2 * n_contours + 2 > limit )
+      goto Invalid_Outline;
+
     /* reading the contours' endpoints & number of points */
-    cont       = gloader->current.outline.contours;
+    cont       = outline->contours;
     cont_limit = cont + n_contours;
 
-    /* check space for contours array + instructions count */
-    if ( n_contours >= 0xFFF || p + ( n_contours + 1 ) * 2 > limit )
-      goto Invalid_Outline;
-
-    prev_cont = FT_NEXT_SHORT( p );
-
-    if ( n_contours > 0 )
-      cont[0] = prev_cont;
-
-    if ( prev_cont < 0 )
-      goto Invalid_Outline;
-
-    for ( cont++; cont < cont_limit; cont++ )
+    last = -1;
+    for ( ; cont < cont_limit; cont++ )
     {
-      cont[0] = FT_NEXT_SHORT( p );
-      if ( cont[0] <= prev_cont )
-      {
-        /* unordered contours: this is invalid */
+      *cont = FT_NEXT_SHORT( p );
+
+      if ( *cont <= last )
         goto Invalid_Outline;
-      }
-      prev_cont = cont[0];
+
+      last = *cont;
     }
 
-    n_points = 0;
-    if ( n_contours > 0 )
-    {
-      n_points = cont[-1] + 1;
-      if ( n_points < 0 )
-        goto Invalid_Outline;
-    }
+    n_points = last + 1;
 
     FT_TRACE5(( "  # of points: %d\n", n_points ));
 
@@ -422,59 +389,48 @@
     if ( error )
       goto Fail;
 
-    /* reading the bytecode instructions */
-    load->glyph->control_len  = 0;
-    load->glyph->control_data = NULL;
-
-    if ( p + 2 > limit )
-      goto Invalid_Outline;
-
+    /* space checked above */
     n_ins = FT_NEXT_USHORT( p );
 
     FT_TRACE5(( "  Instructions size: %u\n", n_ins ));
 
+    /* check instructions size */
+    if ( p + n_ins > limit )
+    {
+      FT_TRACE1(( "TT_Load_Simple_Glyph: excessive instruction count\n" ));
+      error = FT_THROW( Too_Many_Hints );
+      goto Fail;
+    }
+
 #ifdef TT_USE_BYTECODE_INTERPRETER
 
     if ( IS_HINTED( load->load_flags ) )
     {
-      FT_ULong  tmp;
+      TT_ExecContext  exec = load->exec;
+      FT_Memory       memory = exec->memory;
 
 
-      /* check instructions size */
-      if ( ( limit - p ) < n_ins )
-      {
-        FT_TRACE1(( "TT_Load_Simple_Glyph: instruction count mismatch\n" ));
-        error = FT_THROW( Too_Many_Hints );
-        goto Fail;
-      }
+      if ( exec->glyphSize )
+        FT_FREE( exec->glyphIns );
+      exec->glyphSize = 0;
 
       /* we don't trust `maxSizeOfInstructions' in the `maxp' table */
-      /* and thus update the bytecode array size by ourselves       */
-
-      tmp   = load->exec->glyphSize;
-      error = Update_Max( load->exec->memory,
-                          &tmp,
-                          sizeof ( FT_Byte ),
-                          (void*)&load->exec->glyphIns,
-                          n_ins );
-
-      load->exec->glyphSize = (FT_UInt)tmp;
-      if ( error )
-        return error;
-
-      load->glyph->control_len  = n_ins;
-      load->glyph->control_data = load->exec->glyphIns;
-
+      /* and thus allocate the bytecode array size by ourselves     */
       if ( n_ins )
-        FT_MEM_COPY( load->exec->glyphIns, p, (FT_Long)n_ins );
+      {
+        if ( FT_QNEW_ARRAY( exec->glyphIns, n_ins ) )
+          return error;
+
+        FT_MEM_COPY( exec->glyphIns, p, (FT_Long)n_ins );
+
+        exec->glyphSize  = n_ins;
+      }
     }
 
 #endif /* TT_USE_BYTECODE_INTERPRETER */
 
     p += n_ins;
 
-    outline = &gloader->current.outline;
-
     /* reading the point tags */
     flag       = (FT_Byte*)outline->tags;
     flag_limit = flag + n_points;
@@ -512,9 +468,6 @@
     flag      = (FT_Byte*)outline->tags;
     x         = 0;
 
-    if ( p + xy_size > limit )
-      goto Invalid_Outline;
-
     for ( ; vec < vec_limit; vec++, flag++ )
     {
       FT_Pos   delta = 0;
@@ -544,7 +497,7 @@
 
     /* reading the Y coordinates */
 
-    vec       = gloader->current.outline.points;
+    vec       = outline->points;
     vec_limit = vec + n_points;
     flag      = (FT_Byte*)outline->tags;
     y         = 0;
@@ -827,8 +780,7 @@
   TT_Hint_Glyph( TT_Loader  loader,
                  FT_Bool    is_composite )
   {
-#if defined TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || \
-    defined TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
     TT_Face    face   = loader->face;
     TT_Driver  driver = (TT_Driver)FT_FACE_DRIVER( face );
 #endif
@@ -836,35 +788,34 @@
     TT_GlyphZone  zone = &loader->zone;
 
 #ifdef TT_USE_BYTECODE_INTERPRETER
-    FT_Long       n_ins;
+    TT_ExecContext  exec  = loader->exec;
+    FT_Long         n_ins = exec->glyphSize;
 #else
     FT_UNUSED( is_composite );
 #endif
 
 
 #ifdef TT_USE_BYTECODE_INTERPRETER
-    n_ins = loader->glyph->control_len;
-
     /* save original point positions in `org' array */
     if ( n_ins > 0 )
       FT_ARRAY_COPY( zone->org, zone->cur, zone->n_points );
 
     /* Reset graphics state. */
-    loader->exec->GS = loader->size->GS;
+    exec->GS = loader->size->GS;
 
     /* XXX: UNDOCUMENTED! Hinting instructions of a composite glyph */
     /*      completely refer to the (already) hinted subglyphs.     */
     if ( is_composite )
     {
-      loader->exec->metrics.x_scale = 1 << 16;
-      loader->exec->metrics.y_scale = 1 << 16;
+      exec->metrics.x_scale = 1 << 16;
+      exec->metrics.y_scale = 1 << 16;
 
       FT_ARRAY_COPY( zone->orus, zone->cur, zone->n_points );
     }
     else
     {
-      loader->exec->metrics.x_scale = loader->size->metrics->x_scale;
-      loader->exec->metrics.y_scale = loader->size->metrics->y_scale;
+      exec->metrics.x_scale = loader->size->metrics->x_scale;
+      exec->metrics.y_scale = loader->size->metrics->y_scale;
     }
 #endif
 
@@ -884,53 +835,37 @@
     {
       FT_Error  error;
 
-      FT_GlyphLoader  gloader         = loader->gloader;
-      FT_Outline      current_outline = gloader->current.outline;
 
+      TT_Set_CodeRange( exec, tt_coderange_glyph, exec->glyphIns, n_ins );
 
-      TT_Set_CodeRange( loader->exec, tt_coderange_glyph,
-                        loader->exec->glyphIns, n_ins );
+      exec->is_composite = is_composite;
+      exec->pts          = *zone;
 
-      loader->exec->is_composite = is_composite;
-      loader->exec->pts          = *zone;
-
-      error = TT_Run_Context( loader->exec );
-      if ( error && loader->exec->pedantic_hinting )
+      error = TT_Run_Context( exec );
+      if ( error && exec->pedantic_hinting )
         return error;
 
       /* store drop-out mode in bits 5-7; set bit 2 also as a marker */
-      current_outline.tags[0] |=
-        ( loader->exec->GS.scan_type << 5 ) | FT_CURVE_TAG_HAS_SCANMODE;
+      loader->gloader->current.outline.tags[0] |=
+        ( exec->GS.scan_type << 5 ) | FT_CURVE_TAG_HAS_SCANMODE;
     }
 
 #endif
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
     /* Save possibly modified glyph phantom points unless in v40 backward  */
     /* compatibility mode, where no movement on the x axis means no reason */
     /* to change bearings or advance widths.                               */
-    if ( !( driver->interpreter_version == TT_INTERPRETER_VERSION_40 &&
-            loader->exec->backward_compatibility ) )
-    {
-#endif
-      loader->pp1 = zone->cur[zone->n_points - 4];
-      loader->pp2 = zone->cur[zone->n_points - 3];
-      loader->pp3 = zone->cur[zone->n_points - 2];
-      loader->pp4 = zone->cur[zone->n_points - 1];
+
 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
-    }
+    if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 &&
+         exec->backward_compatibility )
+      return FT_Err_Ok;
 #endif
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
-    {
-      if ( loader->exec->sph_tweak_flags & SPH_TWEAK_DEEMBOLDEN )
-        FT_Outline_EmboldenXY( &loader->gloader->current.outline, -24, 0 );
-
-      else if ( loader->exec->sph_tweak_flags & SPH_TWEAK_EMBOLDEN )
-        FT_Outline_EmboldenXY( &loader->gloader->current.outline, 24, 0 );
-    }
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
+    loader->pp1 = zone->cur[zone->n_points - 4];
+    loader->pp2 = zone->cur[zone->n_points - 3];
+    loader->pp3 = zone->cur[zone->n_points - 2];
+    loader->pp4 = zone->cur[zone->n_points - 1];
 
     return FT_Err_Ok;
   }
@@ -949,10 +884,10 @@
   static FT_Error
   TT_Process_Simple_Glyph( TT_Loader  loader )
   {
-    FT_GlyphLoader  gloader = loader->gloader;
-    FT_Error        error   = FT_Err_Ok;
-    FT_Outline*     outline;
-    FT_Int          n_points;
+    FT_Error        error    = FT_Err_Ok;
+    FT_GlyphLoader  gloader  = loader->gloader;
+    FT_Outline*     outline  = &gloader->current.outline;
+    FT_Int          n_points = outline->n_points;
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
     FT_Memory   memory    = loader->face->root.memory;
@@ -960,11 +895,7 @@
 #endif
 
 
-    outline  = &gloader->current.outline;
-    n_points = outline->n_points;
-
     /* set phantom points */
-
     outline->points[n_points    ] = loader->pp1;
     outline->points[n_points + 1] = loader->pp2;
     outline->points[n_points + 2] = loader->pp3;
@@ -976,7 +907,7 @@
 
     if ( !IS_DEFAULT_INSTANCE( FT_FACE( loader->face ) ) )
     {
-      if ( FT_NEW_ARRAY( unrounded, n_points ) )
+      if ( FT_QNEW_ARRAY( unrounded, n_points ) )
         goto Exit;
 
       /* Deltas apply to the unscaled data. */
@@ -998,16 +929,6 @@
     }
 
     {
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-      TT_Face    face   = loader->face;
-      TT_Driver  driver = (TT_Driver)FT_FACE_DRIVER( face );
-
-      FT_String*  family         = face->root.family_name;
-      FT_UInt     ppem           = loader->size->metrics->x_ppem;
-      FT_String*  style          = face->root.style_name;
-      FT_UInt     x_scale_factor = 1000;
-#endif
-
       FT_Vector*  vec   = outline->points;
       FT_Vector*  limit = outline->points + n_points;
 
@@ -1017,52 +938,6 @@
       FT_Bool  do_scale = FALSE;
 
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-
-      if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
-      {
-        /* scale, but only if enabled and only if TT hinting is being used */
-        if ( IS_HINTED( loader->load_flags ) )
-          x_scale_factor = sph_test_tweak_x_scaling( face,
-                                                     family,
-                                                     ppem,
-                                                     style,
-                                                     loader->glyph_index );
-        /* scale the glyph */
-        if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ||
-             x_scale_factor != 1000                         )
-        {
-          x_scale = FT_MulDiv( loader->size->metrics->x_scale,
-                               (FT_Long)x_scale_factor, 1000 );
-          y_scale = loader->size->metrics->y_scale;
-
-          /* compensate for any scaling by de/emboldening; */
-          /* the amount was determined via experimentation */
-          if ( x_scale_factor != 1000 && ppem > 11 )
-          {
-#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
-            FT_Vector*  orig_points = outline->points;
-
-
-            if ( !IS_DEFAULT_INSTANCE( FT_FACE( loader->face ) ) )
-              outline->points = unrounded;
-#endif
-            FT_Outline_EmboldenXY( outline,
-                                   FT_MulFix( 1280 * ppem,
-                                              1000 - x_scale_factor ),
-                                   0 );
-#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
-            if ( !IS_DEFAULT_INSTANCE( FT_FACE( loader->face ) ) )
-              outline->points = orig_points;
-#endif
-          }
-          do_scale = TRUE;
-        }
-      }
-      else
-
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
       {
         /* scale the glyph */
         if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
@@ -1331,12 +1206,12 @@
                               FT_UInt    start_contour )
   {
     FT_Error     error;
-    FT_Outline*  outline;
+    FT_Outline*  outline = &loader->gloader->base.outline;
+    FT_Stream    stream = loader->stream;
+    FT_UShort    n_ins;
     FT_UInt      i;
 
 
-    outline = &loader->gloader->base.outline;
-
     /* make room for phantom points */
     error = FT_GLYPHLOADER_CHECK_POINTS( loader->gloader,
                                          outline->n_points + 4,
@@ -1352,11 +1227,14 @@
 #ifdef TT_USE_BYTECODE_INTERPRETER
 
     {
-      FT_Stream  stream = loader->stream;
-      FT_UShort  n_ins, max_ins;
-      FT_ULong   tmp;
+      TT_ExecContext  exec = loader->exec;
+      FT_Memory       memory = exec->memory;
 
 
+      if ( exec->glyphSize )
+        FT_FREE( exec->glyphIns );
+      exec->glyphSize = 0;
+
       /* TT_Load_Composite_Glyph only gives us the offset of instructions */
       /* so we read them here                                             */
       if ( FT_STREAM_SEEK( loader->ins_pos ) ||
@@ -1365,39 +1243,24 @@
 
       FT_TRACE5(( "  Instructions size = %hu\n", n_ins ));
 
-      /* check it */
-      max_ins = loader->face->max_profile.maxSizeOfInstructions;
-      if ( n_ins > max_ins )
-      {
-        /* don't trust `maxSizeOfInstructions'; */
-        /* only do a rough safety check         */
-        if ( n_ins > loader->byte_len )
-        {
-          FT_TRACE1(( "TT_Process_Composite_Glyph:"
-                      " too many instructions (%hu) for glyph with length %u\n",
-                      n_ins, loader->byte_len ));
-          return FT_THROW( Too_Many_Hints );
-        }
-
-        tmp   = loader->exec->glyphSize;
-        error = Update_Max( loader->exec->memory,
-                            &tmp,
-                            sizeof ( FT_Byte ),
-                            (void*)&loader->exec->glyphIns,
-                            n_ins );
-
-        loader->exec->glyphSize = (FT_UShort)tmp;
-        if ( error )
-          return error;
-      }
-      else if ( n_ins == 0 )
+      if ( !n_ins )
         return FT_Err_Ok;
 
-      if ( FT_STREAM_READ( loader->exec->glyphIns, n_ins ) )
+      /* don't trust `maxSizeOfInstructions'; */
+      /* only do a rough safety check         */
+      if ( n_ins > loader->byte_len )
+      {
+        FT_TRACE1(( "TT_Process_Composite_Glyph:"
+                    " too many instructions (%hu) for glyph with length %u\n",
+                    n_ins, loader->byte_len ));
+        return FT_THROW( Too_Many_Hints );
+      }
+
+      if ( FT_QNEW_ARRAY( exec->glyphIns, n_ins )  ||
+           FT_STREAM_READ( exec->glyphIns, n_ins ) )
         return error;
 
-      loader->glyph->control_data = loader->exec->glyphIns;
-      loader->glyph->control_len  = n_ins;
+      exec->glyphSize = n_ins;
     }
 
 #endif
@@ -1501,45 +1364,31 @@
   static void
   tt_loader_set_pp( TT_Loader  loader )
   {
-    FT_Bool  subpixel_hinting = 0;
-    FT_Bool  grayscale        = 0;
-    FT_Bool  use_aw_2         = 0;
-
-#ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
-    TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( loader->face );
-#endif
-
-
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
-    {
-      subpixel_hinting = loader->exec ? loader->exec->subpixel_hinting
-                                      : 0;
-      grayscale        = loader->exec ? loader->exec->grayscale
-                                      : 0;
-    }
-#endif
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
-    if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 )
-    {
-      subpixel_hinting = loader->exec ? loader->exec->subpixel_hinting_lean
-                                      : 0;
-      grayscale        = loader->exec ? loader->exec->grayscale_cleartype
-                                      : 0;
-    }
-#endif
-
-    use_aw_2 = FT_BOOL( subpixel_hinting && grayscale );
-
     loader->pp1.x = loader->bbox.xMin - loader->left_bearing;
     loader->pp1.y = 0;
     loader->pp2.x = loader->pp1.x + loader->advance;
     loader->pp2.y = 0;
 
-    loader->pp3.x = use_aw_2 ? loader->advance / 2 : 0;
+    loader->pp3.x = 0;
     loader->pp3.y = loader->bbox.yMax + loader->top_bearing;
-    loader->pp4.x = use_aw_2 ? loader->advance / 2 : 0;
+    loader->pp4.x = 0;
     loader->pp4.y = loader->pp3.y - loader->vadvance;
+
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+    {
+      TT_Driver driver = (TT_Driver)FT_FACE_DRIVER( loader->face );
+
+
+      if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 &&
+           loader->exec                                             &&
+           loader->exec->subpixel_hinting_lean                      &&
+           loader->exec->grayscale_cleartype                        )
+      {
+        loader->pp3.x = loader->advance / 2;
+        loader->pp4.x = loader->advance / 2;
+      }
+    }
+#endif
   }
 
 
@@ -1662,8 +1511,14 @@
     else
 
 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
+    {
+      FT_ULong  len;
 
-      offset = tt_face_get_location( face, glyph_index, &loader->byte_len );
+
+      offset = tt_face_get_location( FT_FACE( face ), glyph_index, &len );
+
+      loader->byte_len = (FT_UInt)len;
+    }
 
     if ( loader->byte_len > 0 )
     {
@@ -1889,10 +1744,7 @@
         short        i, limit;
         FT_SubGlyph  subglyph;
 
-        FT_Outline  outline;
-        FT_Vector*  points    = NULL;
-        char*       tags      = NULL;
-        short*      contours  = NULL;
+        FT_Outline  outline = { 0, 0, NULL, NULL, NULL, 0 };
         FT_Vector*  unrounded = NULL;
 
 
@@ -1900,18 +1752,14 @@
 
         /* construct an outline structure for              */
         /* communication with `TT_Vary_Apply_Glyph_Deltas' */
-        outline.n_contours = outline.n_points = limit;
-
-        outline.points   = NULL;
-        outline.tags     = NULL;
-        outline.contours = NULL;
-
-        if ( FT_NEW_ARRAY( points, limit + 4 )    ||
-             FT_NEW_ARRAY( tags, limit + 4 )      ||
-             FT_NEW_ARRAY( contours, limit + 4 )  ||
-             FT_NEW_ARRAY( unrounded, limit + 4 ) )
+        if ( FT_QNEW_ARRAY( outline.points, limit + 4 ) ||
+             FT_QNEW_ARRAY( outline.tags, limit )       ||
+             FT_QNEW_ARRAY( outline.contours, limit )   ||
+             FT_QNEW_ARRAY( unrounded, limit + 4 )      )
           goto Exit1;
 
+        outline.n_contours = outline.n_points = limit;
+
         subglyph = gloader->current.subglyphs;
 
         for ( i = 0; i < limit; i++, subglyph++ )
@@ -1919,20 +1767,16 @@
           /* applying deltas for anchor points doesn't make sense, */
           /* but we don't have to specially check this since       */
           /* unused delta values are zero anyways                  */
-          points[i].x = subglyph->arg1;
-          points[i].y = subglyph->arg2;
-          tags[i]     = 1;
-          contours[i] = i;
+          outline.points[i].x = subglyph->arg1;
+          outline.points[i].y = subglyph->arg2;
+          outline.tags[i]     = ON_CURVE_POINT;
+          outline.contours[i] = i;
         }
 
-        points[i++] = loader->pp1;
-        points[i++] = loader->pp2;
-        points[i++] = loader->pp3;
-        points[i  ] = loader->pp4;
-
-        outline.points   = points;
-        outline.tags     = tags;
-        outline.contours = contours;
+        outline.points[i++] = loader->pp1;
+        outline.points[i++] = loader->pp2;
+        outline.points[i++] = loader->pp3;
+        outline.points[i  ] = loader->pp4;
 
         /* this call provides additional offsets */
         /* for each component's translation      */
@@ -1947,8 +1791,8 @@
         {
           if ( subglyph->flags & ARGS_ARE_XY_VALUES )
           {
-            subglyph->arg1 = (FT_Int16)points[i].x;
-            subglyph->arg2 = (FT_Int16)points[i].y;
+            subglyph->arg1 = (FT_Int16)outline.points[i].x;
+            subglyph->arg2 = (FT_Int16)outline.points[i].y;
           }
         }
 
@@ -2332,8 +2176,7 @@
 #ifdef TT_USE_BYTECODE_INTERPRETER
     FT_Error   error;
     FT_Bool    pedantic = FT_BOOL( load_flags & FT_LOAD_PEDANTIC );
-#if defined TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || \
-    defined TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
+#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
     TT_Driver  driver   = (TT_Driver)FT_FACE_DRIVER( glyph->face );
 #endif
 #endif
@@ -2353,20 +2196,6 @@
       FT_Bool         grayscale_cleartype;
 #endif
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-      FT_Bool  subpixel_hinting = FALSE;
-
-#if 0
-      /* not used yet */
-      FT_Bool  compatible_widths;
-      FT_Bool  symmetrical_smoothing;
-      FT_Bool  bgr;
-      FT_Bool  vertical_lcd;
-      FT_Bool  subpixel_positioned;
-      FT_Bool  gray_cleartype;
-#endif
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
       FT_Bool  reexecute = FALSE;
 
 
@@ -2386,6 +2215,9 @@
       if ( !exec )
         return FT_THROW( Could_Not_Find_Context );
 
+      grayscale = FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
+                             FT_RENDER_MODE_MONO             );
+
 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
       if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 )
       {
@@ -2402,6 +2234,7 @@
           FT_BOOL( subpixel_hinting_lean    &&
                    ( load_flags           &
                      FT_LOAD_TARGET_LCD_V ) );
+        grayscale = FT_BOOL( grayscale && !subpixel_hinting_lean );
       }
       else
       {
@@ -2411,111 +2244,11 @@
       }
 #endif
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-
-      if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
-      {
-        subpixel_hinting = FT_BOOL( ( FT_LOAD_TARGET_MODE( load_flags ) !=
-                                      FT_RENDER_MODE_MONO               )  &&
-                                    SPH_OPTION_SET_SUBPIXEL                );
-
-        if ( subpixel_hinting )
-          grayscale = FALSE;
-        else if ( SPH_OPTION_SET_GRAYSCALE )
-        {
-          grayscale        = TRUE;
-          subpixel_hinting = FALSE;
-        }
-        else
-          grayscale = FALSE;
-
-        if ( FT_IS_TRICKY( glyph->face ) )
-          subpixel_hinting = FALSE;
-
-        exec->ignore_x_mode      = subpixel_hinting || grayscale;
-        exec->rasterizer_version = SPH_OPTION_SET_RASTERIZER_VERSION;
-        if ( exec->sph_tweak_flags & SPH_TWEAK_RASTERIZER_35 )
-          exec->rasterizer_version = TT_INTERPRETER_VERSION_35;
-
-#if 1
-        exec->compatible_widths     = SPH_OPTION_SET_COMPATIBLE_WIDTHS;
-        exec->symmetrical_smoothing = TRUE;
-        exec->bgr                   = FALSE;
-        exec->vertical_lcd          = FALSE;
-        exec->subpixel_positioned   = TRUE;
-        exec->gray_cleartype        = FALSE;
-#else /* 0 */
-        exec->compatible_widths =
-          FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
-                   TT_LOAD_COMPATIBLE_WIDTHS );
-        exec->symmetrical_smoothing =
-          FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
-                   TT_LOAD_SYMMETRICAL_SMOOTHING );
-        exec->bgr =
-          FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
-                   TT_LOAD_BGR );
-        exec->vertical_lcd =
-          FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
-                   TT_LOAD_VERTICAL_LCD );
-        exec->subpixel_positioned =
-          FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
-                   TT_LOAD_SUBPIXEL_POSITIONED );
-        exec->gray_cleartype =
-          FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
-                   TT_LOAD_GRAY_CLEARTYPE );
-#endif /* 0 */
-
-      }
-      else
-
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
-      if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 )
-        grayscale = FT_BOOL( !subpixel_hinting_lean               &&
-                             FT_LOAD_TARGET_MODE( load_flags ) !=
-                               FT_RENDER_MODE_MONO                );
-      else
-#endif
-        grayscale = FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
-                               FT_RENDER_MODE_MONO             );
-
       error = TT_Load_Context( exec, face, size );
       if ( error )
         return error;
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-
-      if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
       {
-        /* a change from mono to subpixel rendering (and vice versa) */
-        /* requires a re-execution of the CVT program                */
-        if ( subpixel_hinting != exec->subpixel_hinting )
-        {
-          FT_TRACE4(( "tt_loader_init: subpixel hinting change,"
-                      " re-executing `prep' table\n" ));
-
-          exec->subpixel_hinting = subpixel_hinting;
-          reexecute              = TRUE;
-        }
-
-        /* a change from mono to grayscale rendering (and vice versa) */
-        /* requires a re-execution of the CVT program                 */
-        if ( grayscale != exec->grayscale )
-        {
-          FT_TRACE4(( "tt_loader_init: grayscale hinting change,"
-                      " re-executing `prep' table\n" ));
-
-          exec->grayscale = grayscale;
-          reexecute       = TRUE;
-        }
-      }
-      else
-
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
-      {
-
 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
         if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 )
         {
@@ -2573,14 +2306,6 @@
       if ( exec->GS.instruct_control & 2 )
         exec->GS = tt_default_graphics_state;
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-      /* check whether we have a font hinted for ClearType --           */
-      /* note that this flag can also be modified in a glyph's bytecode */
-      if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 &&
-           exec->GS.instruct_control & 4                            )
-        exec->ignore_x_mode = FALSE;
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
       /*
        * Toggle backward compatibility according to what font wants, except
@@ -2617,13 +2342,6 @@
            !( driver->interpreter_version == TT_INTERPRETER_VERSION_40  &&
               exec->backward_compatibility                              ) &&
 #endif
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-           !( driver->interpreter_version == TT_INTERPRETER_VERSION_38  &&
-              !SPH_OPTION_BITMAP_WIDTHS                                 &&
-              FT_LOAD_TARGET_MODE( loader->load_flags ) !=
-                                                   FT_RENDER_MODE_MONO  &&
-              exec->compatible_widths                                   ) &&
-#endif
            !face->postscript.isFixedPitch                                 )
       {
         loader->widthp = size->widthp;
@@ -2857,7 +2575,9 @@
 #ifdef FT_CONFIG_OPTION_SVG
 
     /* check for OT-SVG */
-    if ( ( load_flags & FT_LOAD_COLOR ) && face->svg )
+    if ( ( load_flags & FT_LOAD_NO_SVG ) == 0 &&
+         ( load_flags & FT_LOAD_COLOR )       &&
+         face->svg                            )
     {
       SFNT_Service  sfnt = (SFNT_Service)face->sfnt;
 
@@ -2955,6 +2675,9 @@
 
       if ( IS_HINTED( load_flags ) )
       {
+        glyph->control_data = loader.exec->glyphIns;
+        glyph->control_len  = loader.exec->glyphSize;
+
         if ( loader.exec->GS.scan_control )
         {
           /* convert scan conversion mode to FT_OUTLINE_XXX flags */
diff --git a/src/java.desktop/share/native/libfreetype/src/truetype/ttgxvar.c b/src/java.desktop/share/native/libfreetype/src/truetype/ttgxvar.c
index fc95732..9d149ea 100644
--- a/src/java.desktop/share/native/libfreetype/src/truetype/ttgxvar.c
+++ b/src/java.desktop/share/native/libfreetype/src/truetype/ttgxvar.c
@@ -45,6 +45,7 @@
 #include <freetype/internal/ftcalc.h>
 #include <freetype/internal/ftstream.h>
 #include <freetype/internal/sfnt.h>
+#include <freetype/internal/services/svmetric.h>
 #include <freetype/tttags.h>
 #include <freetype/ttnameid.h>
 #include <freetype/ftmm.h>
@@ -465,7 +466,7 @@
     if ( store_offset )
     {
       error = tt_var_load_item_variation_store(
-                face,
+                FT_FACE( face ),
                 table_offset + store_offset,
                 &table->itemStore );
       if ( error )
@@ -475,7 +476,7 @@
     if ( axisMap_offset )
     {
       error = tt_var_load_delta_set_index_mapping(
-                face,
+                FT_FACE( face ),
                 table_offset + axisMap_offset,
                 &table->axisMap,
                 &table->itemStore,
@@ -492,10 +493,11 @@
 
 
   FT_LOCAL_DEF( FT_Error )
-  tt_var_load_item_variation_store( TT_Face          face,
+  tt_var_load_item_variation_store( FT_Face          face,      /* TT_Face */
                                     FT_ULong         offset,
                                     GX_ItemVarStore  itemStore )
   {
+    TT_Face    ttface = (TT_Face)face;
     FT_Stream  stream = FT_FACE_STREAM( face );
     FT_Memory  memory = stream->memory;
 
@@ -507,10 +509,10 @@
     FT_UShort  axis_count;
     FT_UInt    region_count;
 
-    FT_UInt  i, j, k;
+    FT_UInt  i, j;
     FT_Bool  long_words;
 
-    GX_Blend   blend           = face->blend;
+    GX_Blend   blend           = ttface->blend;
     FT_ULong*  dataOffsetArray = NULL;
 
 
@@ -619,9 +621,10 @@
     {
       GX_ItemVarData  varData = &itemStore->varData[i];
 
-      FT_UInt  item_count;
-      FT_UInt  word_delta_count;
-      FT_UInt  region_idx_count;
+      FT_UInt    item_count;
+      FT_UShort  word_delta_count;
+      FT_UInt    region_idx_count;
+      FT_UInt    per_region_size;
 
 
       if ( FT_STREAM_SEEK( offset + dataOffsetArray[i] ) )
@@ -658,6 +661,8 @@
       if ( FT_NEW_ARRAY( varData->regionIndices, region_idx_count ) )
         goto Exit;
       varData->regionIdxCount = region_idx_count;
+      varData->wordDeltaCount = word_delta_count;
+      varData->longWords      = long_words;
 
       for ( j = 0; j < varData->regionIdxCount; j++ )
       {
@@ -673,37 +678,22 @@
         }
       }
 
-      /* Parse delta set.                                                  */
-      /*                                                                   */
-      /* On input, deltas are (word_delta_count + region_idx_count) bytes  */
-      /* each if `long_words` isn't set, and twice as much otherwise.      */
-      /*                                                                   */
-      /* On output, deltas are expanded to `region_idx_count` shorts each. */
-      if ( FT_NEW_ARRAY( varData->deltaSet, item_count * region_idx_count ) )
-        goto Exit;
-      varData->itemCount = item_count;
+      per_region_size = word_delta_count + region_idx_count;
+      if ( long_words )
+        per_region_size *= 2;
 
-      for ( j = 0; j < item_count * region_idx_count; )
+      if ( FT_NEW_ARRAY( varData->deltaSet, per_region_size * item_count ) )
+        goto Exit;
+      if ( FT_Stream_Read( stream,
+                           varData->deltaSet,
+                           per_region_size * item_count ) )
       {
-        if ( long_words )
-        {
-          for ( k = 0; k < word_delta_count; k++, j++ )
-            if ( FT_READ_LONG( varData->deltaSet[j] ) )
-              goto Exit;
-          for ( ; k < region_idx_count; k++, j++ )
-            if ( FT_READ_SHORT( varData->deltaSet[j] ) )
-              goto Exit;
-        }
-        else
-        {
-          for ( k = 0; k < word_delta_count; k++, j++ )
-            if ( FT_READ_SHORT( varData->deltaSet[j] ) )
-              goto Exit;
-          for ( ; k < region_idx_count; k++, j++ )
-            if ( FT_READ_CHAR( varData->deltaSet[j] ) )
-              goto Exit;
-        }
+        FT_TRACE2(( "deltaSet read failed." ));
+        error = FT_THROW( Invalid_Table );
+        goto Exit;
       }
+
+      varData->itemCount = item_count;
     }
 
   Exit:
@@ -714,7 +704,7 @@
 
 
   FT_LOCAL_DEF( FT_Error )
-  tt_var_load_delta_set_index_mapping( TT_Face            face,
+  tt_var_load_delta_set_index_mapping( FT_Face            face, /* TT_Face */
                                        FT_ULong           offset,
                                        GX_DeltaSetIdxMap  map,
                                        GX_ItemVarStore    itemStore,
@@ -941,7 +931,7 @@
     }
 
     error = tt_var_load_item_variation_store(
-              face,
+              FT_FACE( face ),
               table_offset + store_offset,
               &table->itemStore );
     if ( error )
@@ -950,7 +940,7 @@
     if ( widthMap_offset )
     {
       error = tt_var_load_delta_set_index_mapping(
-                face,
+                FT_FACE( face ),
                 table_offset + widthMap_offset,
                 &table->widthMap,
                 &table->itemStore,
@@ -992,24 +982,30 @@
 
 
   FT_LOCAL_DEF( FT_ItemVarDelta )
-  tt_var_get_item_delta( TT_Face          face,
+  tt_var_get_item_delta( FT_Face          face,        /* TT_Face */
                          GX_ItemVarStore  itemStore,
                          FT_UInt          outerIndex,
                          FT_UInt          innerIndex )
   {
+    TT_Face    ttface = (TT_Face)face;
     FT_Stream  stream = FT_FACE_STREAM( face );
     FT_Memory  memory = stream->memory;
     FT_Error   error  = FT_Err_Ok;
 
     GX_ItemVarData    varData;
-    FT_ItemVarDelta*  deltaSet;
+    FT_ItemVarDelta*  deltaSet = NULL;
+    FT_ItemVarDelta   deltaSetStack[16];
+
+    FT_Fixed*  scalars = NULL;
+    FT_Fixed   scalarsStack[16];
 
     FT_UInt          master, j;
-    FT_Fixed*        scalars = NULL;
-    FT_ItemVarDelta  returnValue;
+    FT_ItemVarDelta  returnValue = 0;
+    FT_UInt          per_region_size;
+    FT_Byte*         bytes;
 
 
-    if ( !face->blend || !face->blend->normalizedcoords )
+    if ( !ttface->blend || !ttface->blend->normalizedcoords )
       return 0;
 
     /* OpenType 1.8.4+: No variation data for this item */
@@ -1023,15 +1019,48 @@
     if ( outerIndex >= itemStore->dataCount )
       return 0; /* Out of range. */
 
-    varData  = &itemStore->varData[outerIndex];
-    deltaSet = FT_OFFSET( varData->deltaSet,
-                          varData->regionIdxCount * innerIndex );
+    varData = &itemStore->varData[outerIndex];
 
     if ( innerIndex >= varData->itemCount )
       return 0; /* Out of range. */
 
-    if ( FT_QNEW_ARRAY( scalars, varData->regionIdxCount ) )
-      return 0;
+    if ( varData->regionIdxCount < 16 )
+    {
+      deltaSet = deltaSetStack;
+      scalars  = scalarsStack;
+    }
+    else
+    {
+      if ( FT_QNEW_ARRAY( deltaSet, varData->regionIdxCount ) )
+        goto Exit;
+      if ( FT_QNEW_ARRAY( scalars, varData->regionIdxCount ) )
+        goto Exit;
+    }
+
+    /* Parse delta set.                                            */
+    /*                                                             */
+    /* Deltas are (word_delta_count + region_idx_count) bytes each */
+    /* if `longWords` isn't set, and twice as much otherwise.      */
+    per_region_size = varData->wordDeltaCount + varData->regionIdxCount;
+    if ( varData->longWords )
+      per_region_size *= 2;
+
+    bytes = varData->deltaSet + per_region_size * innerIndex;
+
+    if ( varData->longWords )
+    {
+      for ( master = 0; master < varData->wordDeltaCount; master++ )
+        deltaSet[master] = FT_NEXT_LONG( bytes );
+      for ( ; master < varData->regionIdxCount; master++ )
+        deltaSet[master] = FT_NEXT_SHORT( bytes );
+    }
+    else
+    {
+      for ( master = 0; master < varData->wordDeltaCount; master++ )
+        deltaSet[master] = FT_NEXT_SHORT( bytes );
+      for ( ; master < varData->regionIdxCount; master++ )
+        deltaSet[master] = FT_NEXT_CHAR( bytes );
+    }
 
     /* outer loop steps through master designs to be blended */
     for ( master = 0; master < varData->regionIdxCount; master++ )
@@ -1060,27 +1089,27 @@
         else if ( axis->peakCoord == 0 )
           continue;
 
-        else if ( face->blend->normalizedcoords[j] == axis->peakCoord )
+        else if ( ttface->blend->normalizedcoords[j] == axis->peakCoord )
           continue;
 
         /* ignore this region if coords are out of range */
-        else if ( face->blend->normalizedcoords[j] <= axis->startCoord ||
-                  face->blend->normalizedcoords[j] >= axis->endCoord   )
+        else if ( ttface->blend->normalizedcoords[j] <= axis->startCoord ||
+                  ttface->blend->normalizedcoords[j] >= axis->endCoord   )
         {
           scalar = 0;
           break;
         }
 
         /* cumulative product of all the axis scalars */
-        else if ( face->blend->normalizedcoords[j] < axis->peakCoord )
+        else if ( ttface->blend->normalizedcoords[j] < axis->peakCoord )
           scalar =
             FT_MulDiv( scalar,
-                       face->blend->normalizedcoords[j] - axis->startCoord,
+                       ttface->blend->normalizedcoords[j] - axis->startCoord,
                        axis->peakCoord - axis->startCoord );
         else
           scalar =
             FT_MulDiv( scalar,
-                       axis->endCoord - face->blend->normalizedcoords[j],
+                       axis->endCoord - ttface->blend->normalizedcoords[j],
                        axis->endCoord - axis->peakCoord );
 
       } /* per-axis loop */
@@ -1106,7 +1135,11 @@
      */
     returnValue = FT_MulAddFix( scalars, deltaSet, varData->regionIdxCount );
 
-    FT_FREE( scalars );
+  Exit:
+    if ( scalars != scalarsStack )
+      FT_FREE( scalars );
+    if ( deltaSet != deltaSetStack )
+      FT_FREE( deltaSet );
 
     return returnValue;
   }
@@ -1206,7 +1239,7 @@
       innerIndex = gindex;
     }
 
-    delta = tt_var_get_item_delta( face,
+    delta = tt_var_get_item_delta( FT_FACE( face ),
                                    &table->itemStore,
                                    outerIndex,
                                    innerIndex );
@@ -1229,20 +1262,20 @@
 
 
   FT_LOCAL_DEF( FT_Error )
-  tt_hadvance_adjust( TT_Face  face,
+  tt_hadvance_adjust( FT_Face  face,    /* TT_Face */
                       FT_UInt  gindex,
                       FT_Int  *avalue )
   {
-    return tt_hvadvance_adjust( face, gindex, avalue, 0 );
+    return tt_hvadvance_adjust( (TT_Face)face, gindex, avalue, 0 );
   }
 
 
   FT_LOCAL_DEF( FT_Error )
-  tt_vadvance_adjust( TT_Face  face,
+  tt_vadvance_adjust( FT_Face  face,    /* TT_Face */
                       FT_UInt  gindex,
                       FT_Int  *avalue )
   {
-    return tt_hvadvance_adjust( face, gindex, avalue, 1 );
+    return tt_hvadvance_adjust( (TT_Face)face, gindex, avalue, 1 );
   }
 
 
@@ -1389,7 +1422,7 @@
     records_offset = FT_STREAM_POS();
 
     error = tt_var_load_item_variation_store(
-              face,
+              FT_FACE( face ),
               table_offset + store_offset,
               &blend->mvar_table->itemStore );
     if ( error )
@@ -1462,15 +1495,14 @@
 
 
   static FT_Error
-  tt_size_reset_iterator( FT_ListNode  node,
+  ft_size_reset_iterator( FT_ListNode  node,
                           void*        user )
   {
-    TT_Size  size = (TT_Size)node->data;
-
-    FT_UNUSED( user );
+    FT_Size                       size = (FT_Size)node->data;
+    FT_Service_MetricsVariations  var  = (FT_Service_MetricsVariations)user;
 
 
-    tt_size_reset( size, 1 );
+    var->size_reset( size );
 
     return FT_Err_Ok;
   }
@@ -1489,16 +1521,19 @@
    *     The font face.
    */
   FT_LOCAL_DEF( void )
-  tt_apply_mvar( TT_Face  face )
+  tt_apply_mvar( FT_Face  face )  /* TT_Face */
   {
-    GX_Blend  blend = face->blend;
+    TT_Face  ttface = (TT_Face)face;
+
+    GX_Blend  blend = ttface->blend;
     GX_Value  value, limit;
+
     FT_Short  mvar_hasc_delta = 0;
     FT_Short  mvar_hdsc_delta = 0;
     FT_Short  mvar_hlgp_delta = 0;
 
 
-    if ( !( face->variation_support & TT_FACE_FLAG_VAR_MVAR ) )
+    if ( !( ttface->variation_support & TT_FACE_FLAG_VAR_MVAR ) )
       return;
 
     value = blend->mvar_table->values;
@@ -1506,7 +1541,7 @@
 
     for ( ; value < limit; value++ )
     {
-      FT_Short*  p = ft_var_get_value_pointer( face, value->tag );
+      FT_Short*  p = ft_var_get_value_pointer( ttface, value->tag );
       FT_Int     delta;
 
 
@@ -1543,7 +1578,8 @@
 
     /* adjust all derived values */
     {
-      FT_Face  root = &face->root;
+      FT_Service_MetricsVariations  var =
+        (FT_Service_MetricsVariations)ttface->face_var;
 
       /*
        * Apply the deltas of hasc, hdsc and hlgp to the FT_Face's ascender,
@@ -1571,24 +1607,25 @@
        *    whether they were actually changed or the font had the OS/2 table's
        *    fsSelection's bit 7 (USE_TYPO_METRICS) set.
        */
-      FT_Short  current_line_gap = root->height - root->ascender +
-                                   root->descender;
+      FT_Short  current_line_gap = face->height - face->ascender +
+                                   face->descender;
 
 
-      root->ascender  = root->ascender + mvar_hasc_delta;
-      root->descender = root->descender + mvar_hdsc_delta;
-      root->height    = root->ascender - root->descender +
+      face->ascender  = face->ascender + mvar_hasc_delta;
+      face->descender = face->descender + mvar_hdsc_delta;
+      face->height    = face->ascender - face->descender +
                         current_line_gap + mvar_hlgp_delta;
 
-      root->underline_position  = face->postscript.underlinePosition -
-                                  face->postscript.underlineThickness / 2;
-      root->underline_thickness = face->postscript.underlineThickness;
+      face->underline_position  = ttface->postscript.underlinePosition -
+                                  ttface->postscript.underlineThickness / 2;
+      face->underline_thickness = ttface->postscript.underlineThickness;
 
-      /* iterate over all FT_Size objects and call `tt_size_reset' */
-      /* to propagate the metrics changes                          */
-      FT_List_Iterate( &root->sizes_list,
-                       tt_size_reset_iterator,
-                       NULL );
+      /* iterate over all FT_Size objects and call `var->size_reset' */
+      /* to propagate the metrics changes                            */
+      if ( var && var->size_reset )
+        FT_List_Iterate( &face->sizes_list,
+                         ft_size_reset_iterator,
+                         (void*)var );
     }
   }
 
@@ -2099,7 +2136,7 @@
             innerIndex = table->axisMap.innerIndex[idx];
           }
 
-          delta = tt_var_get_item_delta( face,
+          delta = tt_var_get_item_delta( FT_FACE( face ),
                                          &table->itemStore,
                                          outerIndex,
                                          innerIndex );
@@ -2261,11 +2298,12 @@
    *   FreeType error code.  0 means success.
    */
   FT_LOCAL_DEF( FT_Error )
-  TT_Get_MM_Var( TT_Face      face,
+  TT_Get_MM_Var( FT_Face      face,    /* TT_Face */
                  FT_MM_Var*  *master )
   {
-    FT_Stream            stream     = face->root.stream;
-    FT_Memory            memory     = face->root.memory;
+    TT_Face              ttface     = (TT_Face)face;
+    FT_Stream            stream     = FT_FACE_STREAM( face );
+    FT_Memory            memory     = FT_FACE_MEMORY( face );
     FT_ULong             table_len;
     FT_Error             error      = FT_Err_Ok;
     FT_ULong             fvar_start = 0;
@@ -2329,19 +2367,19 @@
     /* the default instance, which might be missing in the table of named */
     /* instances (in 'fvar').  This value is validated in `sfobjs.c` and  */
     /* may be reset to 0 if consistency checks fail.                      */
-    num_instances = (FT_UInt)face->root.style_flags >> 16;
+    num_instances = (FT_UInt)face->style_flags >> 16;
 
     /* read the font data and set up the internal representation */
     /* if not already done                                       */
 
-    need_init = !face->blend;
+    need_init = !ttface->blend;
 
     if ( need_init )
     {
       FT_TRACE2(( "FVAR " ));
 
-      if ( FT_SET_ERROR( face->goto_table( face, TTAG_fvar,
-                                           stream, &table_len ) ) )
+      if ( FT_SET_ERROR( ttface->goto_table( ttface, TTAG_fvar,
+                                             stream, &table_len ) ) )
       {
         FT_TRACE1(( "is missing\n" ));
         goto Exit;
@@ -2374,14 +2412,14 @@
                   fvar_head.axisCount,
                   fvar_head.axisCount == 1 ? "is" : "es" ));
 
-      if ( FT_NEW( face->blend ) )
+      if ( FT_NEW( ttface->blend ) )
         goto Exit;
 
-      num_axes              = fvar_head.axisCount;
-      face->blend->num_axis = num_axes;
+      num_axes                = fvar_head.axisCount;
+      ttface->blend->num_axis = num_axes;
     }
     else
-      num_axes = face->blend->num_axis;
+      num_axes = ttface->blend->num_axis;
 
     /* prepare storage area for MM data; this cannot overflow   */
     /* 32-bit arithmetic because of the size limits used in the */
@@ -2410,16 +2448,16 @@
 
     if ( need_init )
     {
-      face->blend->mmvar_len = mmvar_size       +
-                               axis_flags_size  +
-                               axis_size        +
-                               namedstyle_size  +
-                               next_coords_size +
-                               next_name_size;
+      ttface->blend->mmvar_len = mmvar_size       +
+                                 axis_flags_size  +
+                                 axis_size        +
+                                 namedstyle_size  +
+                                 next_coords_size +
+                                 next_name_size;
 
-      if ( FT_ALLOC( mmvar, face->blend->mmvar_len ) )
+      if ( FT_ALLOC( mmvar, ttface->blend->mmvar_len ) )
         goto Exit;
-      face->blend->mmvar = mmvar;
+      ttface->blend->mmvar = mmvar;
 
       /* set up pointers and offsets into the `mmvar' array; */
       /* the data gets filled in later on                    */
@@ -2525,27 +2563,27 @@
 
       /* named instance coordinates are stored as design coordinates; */
       /* we have to convert them to normalized coordinates also       */
-      if ( FT_NEW_ARRAY( face->blend->normalized_stylecoords,
+      if ( FT_NEW_ARRAY( ttface->blend->normalized_stylecoords,
                          num_axes * num_instances ) )
         goto Exit;
 
-      if ( fvar_head.instanceCount && !face->blend->avar_loaded )
+      if ( fvar_head.instanceCount && !ttface->blend->avar_loaded )
       {
         FT_ULong  offset = FT_STREAM_POS();
 
 
-        ft_var_load_avar( face );
+        ft_var_load_avar( ttface );
 
         if ( FT_STREAM_SEEK( offset ) )
           goto Exit;
       }
 
-      FT_TRACE5(( "%d instance%s\n",
+      FT_TRACE5(( "%d named instance%s\n",
                   fvar_head.instanceCount,
                   fvar_head.instanceCount == 1 ? "" : "s" ));
 
       ns  = mmvar->namedstyle;
-      nsc = face->blend->normalized_stylecoords;
+      nsc = ttface->blend->normalized_stylecoords;
       for ( i = 0; i < fvar_head.instanceCount; i++, ns++ )
       {
         /* PostScript names add 2 bytes to the instance record size */
@@ -2568,7 +2606,7 @@
 
 #ifdef FT_DEBUG_LEVEL_TRACE
         {
-          SFNT_Service  sfnt = (SFNT_Service)face->sfnt;
+          SFNT_Service  sfnt = (SFNT_Service)ttface->sfnt;
 
           FT_String*  strname = NULL;
           FT_String*  psname  = NULL;
@@ -2580,7 +2618,7 @@
 
           if ( ns->strid != 0xFFFF )
           {
-            (void)sfnt->get_name( face,
+            (void)sfnt->get_name( ttface,
                                   (FT_UShort)ns->strid,
                                   &strname );
             if ( strname && !ft_strcmp( strname, ".notdef" ) )
@@ -2589,7 +2627,7 @@
 
           if ( ns->psid != 0xFFFF )
           {
-            (void)sfnt->get_name( face,
+            (void)sfnt->get_name( ttface,
                                   (FT_UShort)ns->psid,
                                   &psname );
             if ( psname && !ft_strcmp( psname, ".notdef" ) )
@@ -2598,7 +2636,7 @@
 
           (void)FT_STREAM_SEEK( pos );
 
-          FT_TRACE5(( "  instance %d (%s%s%s, %s%s%s)\n",
+          FT_TRACE5(( "  named instance %d (%s%s%s, %s%s%s)\n",
                       i,
                       strname ? "name: `" : "",
                       strname ? strname : "unnamed",
@@ -2612,7 +2650,7 @@
         }
 #endif /* FT_DEBUG_LEVEL_TRACE */
 
-        ft_var_to_normalized( face, num_axes, ns->coords, nsc );
+        ft_var_to_normalized( ttface, num_axes, ns->coords, nsc );
         nsc += num_axes;
 
         FT_FRAME_EXIT();
@@ -2620,15 +2658,17 @@
 
       if ( num_instances != fvar_head.instanceCount )
       {
-        SFNT_Service  sfnt = (SFNT_Service)face->sfnt;
+        SFNT_Service  sfnt = (SFNT_Service)ttface->sfnt;
 
         FT_Int   found, dummy1, dummy2;
         FT_UInt  strid = ~0U;
 
 
-        /* the default instance is missing in array the   */
-        /* of named instances; try to synthesize an entry */
-        found = sfnt->get_name_id( face,
+        /* The default instance is missing in array the    */
+        /* of named instances; try to synthesize an entry. */
+        /* If this fails, `default_named_instance` remains */
+        /* at value zero, which doesn't do any harm.       */
+        found = sfnt->get_name_id( ttface,
                                    TT_NAME_ID_TYPOGRAPHIC_SUBFAMILY,
                                    &dummy1,
                                    &dummy2 );
@@ -2636,7 +2676,7 @@
           strid = TT_NAME_ID_TYPOGRAPHIC_SUBFAMILY;
         else
         {
-          found = sfnt->get_name_id( face,
+          found = sfnt->get_name_id( ttface,
                                      TT_NAME_ID_FONT_SUBFAMILY,
                                      &dummy1,
                                      &dummy2 );
@@ -2646,7 +2686,7 @@
 
         if ( found )
         {
-          found = sfnt->get_name_id( face,
+          found = sfnt->get_name_id( ttface,
                                      TT_NAME_ID_PS_NAME,
                                      &dummy1,
                                      &dummy2 );
@@ -2655,6 +2695,9 @@
             FT_TRACE5(( "TT_Get_MM_Var:"
                         " Adding default instance to named instances\n" ));
 
+            /* named instance indices start with value 1 */
+            ttface->var_default_named_instance = num_instances;
+
             ns = &mmvar->namedstyle[fvar_head.instanceCount];
 
             ns->strid = strid;
@@ -2668,7 +2711,7 @@
         }
       }
 
-      ft_var_load_mvar( face );
+      ft_var_load_mvar( ttface );
     }
 
     /* fill the output array if requested */
@@ -2678,9 +2721,9 @@
       FT_UInt  n;
 
 
-      if ( FT_ALLOC( mmvar, face->blend->mmvar_len ) )
+      if ( FT_ALLOC( mmvar, ttface->blend->mmvar_len ) )
         goto Exit;
-      FT_MEM_COPY( mmvar, face->blend->mmvar, face->blend->mmvar_len );
+      FT_MEM_COPY( mmvar, ttface->blend->mmvar, ttface->blend->mmvar_len );
 
       axis_flags =
         (FT_UShort*)( (char*)mmvar + mmvar_size );
@@ -2756,7 +2799,7 @@
 
     if ( !face->blend )
     {
-      if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) )
+      if ( FT_SET_ERROR( TT_Get_MM_Var( FT_FACE( face ), NULL ) ) )
         goto Exit;
     }
 
@@ -2841,26 +2884,29 @@
         }
       }
 
-      if ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) )
+      if ( !have_diff )
       {
-        FT_UInt  instance_index = (FT_UInt)face->root.face_index >> 16;
+        if ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) )
+        {
+          FT_UInt  instance_index = (FT_UInt)face->root.face_index >> 16;
 
 
-        c = blend->normalizedcoords + i;
-        n = blend->normalized_stylecoords            +
-            ( instance_index - 1 ) * mmvar->num_axis +
-            i;
+          c = blend->normalizedcoords + i;
+          n = blend->normalized_stylecoords            +
+              ( instance_index - 1 ) * mmvar->num_axis +
+              i;
 
-        for ( j = i; j < mmvar->num_axis; j++, n++, c++ )
-          if ( *c != *n )
-            have_diff = 1;
-      }
-      else
-      {
-        c = blend->normalizedcoords + i;
-        for ( j = i; j < mmvar->num_axis; j++, c++ )
-          if ( *c != 0 )
-            have_diff = 1;
+          for ( j = i; j < mmvar->num_axis; j++, n++, c++ )
+            if ( *c != *n )
+              have_diff = 1;
+        }
+        else
+        {
+          c = blend->normalizedcoords + i;
+          for ( j = i; j < mmvar->num_axis; j++, c++ )
+            if ( *c != 0 )
+              have_diff = 1;
+        }
       }
 
       /* return value -1 indicates `no change' */
@@ -2924,9 +2970,6 @@
       }
     }
 
-    /* enforce recomputation of the PostScript name; */
-    FT_FREE( face->postscript_name );
-
   Exit:
     return error;
   }
@@ -2958,26 +3001,15 @@
    *     An array of `num_coords', each between [-1,1].
    *
    * @Return:
-   *   FreeType error code.  0 means success.
+   *   FreeType error code.  0 means success, -1 means success and unchanged
+   *   axis values.
    */
   FT_LOCAL_DEF( FT_Error )
-  TT_Set_MM_Blend( TT_Face    face,
+  TT_Set_MM_Blend( FT_Face    face,       /* TT_Face */
                    FT_UInt    num_coords,
                    FT_Fixed*  coords )
   {
-    FT_Error  error;
-
-
-    error = tt_set_mm_blend( face, num_coords, coords, 1 );
-    if ( error )
-      return error;
-
-    if ( num_coords )
-      face->root.face_flags |= FT_FACE_FLAG_VARIATION;
-    else
-      face->root.face_flags &= ~FT_FACE_FLAG_VARIATION;
-
-    return FT_Err_Ok;
+    return tt_set_mm_blend( (TT_Face)face, num_coords, coords, 1 );
   }
 
 
@@ -3005,31 +3037,34 @@
    *     An array of `num_coords', each between [-1,1].
    *
    * @Return:
-   *   FreeType error code.  0 means success.
+   *   FreeType error code.  0 means success, -1 means success and unchanged
+   *   axis values.
    */
   FT_LOCAL_DEF( FT_Error )
-  TT_Get_MM_Blend( TT_Face    face,
+  TT_Get_MM_Blend( FT_Face    face,       /* TT_Face */
                    FT_UInt    num_coords,
                    FT_Fixed*  coords )
   {
+    TT_Face  ttface = (TT_Face)face;
+
     FT_Error  error = FT_Err_Ok;
     GX_Blend  blend;
     FT_UInt   i, nc;
 
 
-    if ( !face->blend )
+    if ( !ttface->blend )
     {
       if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) )
         return error;
     }
 
-    blend = face->blend;
+    blend = ttface->blend;
 
     if ( !blend->coords )
     {
       /* select default instance coordinates */
       /* if no instance is selected yet      */
-      if ( FT_SET_ERROR( tt_set_mm_blend( face, 0, NULL, 1 ) ) )
+      if ( FT_SET_ERROR( tt_set_mm_blend( ttface, 0, NULL, 1 ) ) )
         return error;
     }
 
@@ -3042,7 +3077,7 @@
       nc = blend->num_axis;
     }
 
-    if ( face->doblend )
+    if ( ttface->doblend )
     {
       for ( i = 0; i < nc; i++ )
         coords[i] = blend->normalizedcoords[i];
@@ -3089,15 +3124,16 @@
    *   FreeType error code.  0 means success.
    */
   FT_LOCAL_DEF( FT_Error )
-  TT_Set_Var_Design( TT_Face    face,
+  TT_Set_Var_Design( FT_Face    face,       /* TT_Face */
                      FT_UInt    num_coords,
                      FT_Fixed*  coords )
   {
+    TT_Face     ttface = (TT_Face)face;
     FT_Error    error  = FT_Err_Ok;
     GX_Blend    blend;
     FT_MM_Var*  mmvar;
     FT_UInt     i;
-    FT_Memory   memory = face->root.memory;
+    FT_Memory   memory = FT_FACE_MEMORY( face );
 
     FT_Fixed*  c;
     FT_Fixed*  n;
@@ -3106,13 +3142,13 @@
     FT_Bool  have_diff = 0;
 
 
-    if ( !face->blend )
+    if ( !ttface->blend )
     {
       if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) )
         goto Exit;
     }
 
-    blend = face->blend;
+    blend = ttface->blend;
     mmvar = blend->mmvar;
 
     if ( num_coords > mmvar->num_axis )
@@ -3140,13 +3176,13 @@
       }
     }
 
-    if ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) )
+    if ( FT_IS_NAMED_INSTANCE( face ) )
     {
       FT_UInt              instance_index;
       FT_Var_Named_Style*  named_style;
 
 
-      instance_index = (FT_UInt)face->root.face_index >> 16;
+      instance_index = (FT_UInt)face->face_index >> 16;
       named_style    = mmvar->namedstyle + instance_index - 1;
 
       n = named_style->coords + num_coords;
@@ -3183,22 +3219,17 @@
     if ( FT_NEW_ARRAY( normalized, mmvar->num_axis ) )
       goto Exit;
 
-    if ( !face->blend->avar_loaded )
-      ft_var_load_avar( face );
+    if ( !ttface->blend->avar_loaded )
+      ft_var_load_avar( ttface );
 
     FT_TRACE5(( "TT_Set_Var_Design:\n" ));
     FT_TRACE5(( "  normalized design coordinates:\n" ));
-    ft_var_to_normalized( face, num_coords, blend->coords, normalized );
+    ft_var_to_normalized( ttface, num_coords, blend->coords, normalized );
 
-    error = tt_set_mm_blend( face, mmvar->num_axis, normalized, 0 );
+    error = tt_set_mm_blend( ttface, mmvar->num_axis, normalized, 0 );
     if ( error )
       goto Exit;
 
-    if ( num_coords )
-      face->root.face_flags |= FT_FACE_FLAG_VARIATION;
-    else
-      face->root.face_flags &= ~FT_FACE_FLAG_VARIATION;
-
   Exit:
     FT_FREE( normalized );
     return error;
@@ -3231,28 +3262,29 @@
    *   FreeType error code.  0~means success.
    */
   FT_LOCAL_DEF( FT_Error )
-  TT_Get_Var_Design( TT_Face    face,
+  TT_Get_Var_Design( FT_Face    face,       /* TT_Face */
                      FT_UInt    num_coords,
                      FT_Fixed*  coords )
   {
-    FT_Error  error = FT_Err_Ok;
+    TT_Face   ttface = (TT_Face)face;
+    FT_Error  error  = FT_Err_Ok;
     GX_Blend  blend;
     FT_UInt   i, nc;
 
 
-    if ( !face->blend )
+    if ( !ttface->blend )
     {
       if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) )
         return error;
     }
 
-    blend = face->blend;
+    blend = ttface->blend;
 
     if ( !blend->coords )
     {
       /* select default instance coordinates */
       /* if no instance is selected yet      */
-      if ( FT_SET_ERROR( tt_set_mm_blend( face, 0, NULL, 1 ) ) )
+      if ( FT_SET_ERROR( tt_set_mm_blend( ttface, 0, NULL, 1 ) ) )
         return error;
     }
 
@@ -3265,7 +3297,7 @@
       nc = blend->num_axis;
     }
 
-    if ( face->doblend )
+    if ( ttface->doblend )
     {
       for ( i = 0; i < nc; i++ )
         coords[i] = blend->coords[i];
@@ -3301,29 +3333,33 @@
    *     Value 0 indicates to not use an instance.
    *
    * @Return:
-   *   FreeType error code.  0~means success.
+   *   FreeType error code.  0~means success, -1 means success and unchanged
+   *   axis values.
    */
   FT_LOCAL_DEF( FT_Error )
-  TT_Set_Named_Instance( TT_Face  face,
+  TT_Set_Named_Instance( FT_Face  face,            /* TT_Face */
                          FT_UInt  instance_index )
   {
+    TT_Face     ttface = (TT_Face)face;
     FT_Error    error;
     GX_Blend    blend;
     FT_MM_Var*  mmvar;
 
+    FT_Memory  memory = FT_FACE_MEMORY( face );
+
     FT_UInt  num_instances;
 
 
-    if ( !face->blend )
+    if ( !ttface->blend )
     {
       if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) )
         goto Exit;
     }
 
-    blend = face->blend;
+    blend = ttface->blend;
     mmvar = blend->mmvar;
 
-    num_instances = (FT_UInt)face->root.style_flags >> 16;
+    num_instances = (FT_UInt)face->style_flags >> 16;
 
     /* `instance_index' starts with value 1, thus `>' */
     if ( instance_index > num_instances )
@@ -3334,8 +3370,7 @@
 
     if ( instance_index > 0 )
     {
-      FT_Memory     memory = face->root.memory;
-      SFNT_Service  sfnt   = (SFNT_Service)face->sfnt;
+      SFNT_Service  sfnt = (SFNT_Service)ttface->sfnt;
 
       FT_Var_Named_Style*  named_style;
       FT_String*           style_name;
@@ -3343,40 +3378,89 @@
 
       named_style = mmvar->namedstyle + instance_index - 1;
 
-      error = sfnt->get_name( face,
+      error = sfnt->get_name( ttface,
                               (FT_UShort)named_style->strid,
                               &style_name );
       if ( error )
         goto Exit;
 
       /* set (or replace) style name */
-      FT_FREE( face->root.style_name );
-      face->root.style_name = style_name;
+      FT_FREE( face->style_name );
+      face->style_name = style_name;
 
       /* finally, select the named instance */
       error = TT_Set_Var_Design( face,
                                  mmvar->num_axis,
                                  named_style->coords );
-      if ( error )
-      {
-        /* internal error code -1 means `no change' */
-        if ( error == -1 )
-          error = FT_Err_Ok;
-        goto Exit;
-      }
     }
     else
+    {
+      /* restore non-VF style name */
+      FT_FREE( face->style_name );
+      if ( FT_STRDUP( face->style_name, ttface->non_var_style_name ) )
+        goto Exit;
       error = TT_Set_Var_Design( face, 0, NULL );
-
-    face->root.face_index  = ( instance_index << 16 )             |
-                             ( face->root.face_index & 0xFFFFL );
-    face->root.face_flags &= ~FT_FACE_FLAG_VARIATION;
+    }
 
   Exit:
     return error;
   }
 
 
+  /**************************************************************************
+   *
+   * @Function:
+   *   TT_Get_Default_Named_Instance
+   *
+   * @Description:
+   *   Get the default named instance.
+   *
+   * @Input:
+   *   face ::
+   *     A handle to the source face.
+   *
+   * @Output:
+   *   instance_index ::
+   *     The default named instance index.
+   *
+   * @Return:
+   *   FreeType error code.  0~means success.
+   */
+  FT_LOCAL_DEF( FT_Error )
+  TT_Get_Default_Named_Instance( FT_Face   face,
+                                 FT_UInt  *instance_index )
+  {
+    TT_Face   ttface = (TT_Face)face;
+    FT_Error  error  = FT_Err_Ok;
+
+
+    if ( !ttface->blend )
+    {
+      if ( FT_SET_ERROR( TT_Get_MM_Var( face, NULL ) ) )
+        goto Exit;
+    }
+
+    *instance_index = ttface->var_default_named_instance;
+
+  Exit:
+    return error;
+  }
+
+
+  /* This function triggers (lazy) recomputation of the `postscript_name` */
+  /* field in `TT_Face`.                                                  */
+
+  FT_LOCAL_DEF( void )
+  tt_construct_ps_name( FT_Face  face )
+  {
+    TT_Face    ttface = (TT_Face)face;
+    FT_Memory  memory = FT_FACE_MEMORY( face );
+
+
+    FT_FREE( ttface->postscript_name );
+  }
+
+
   /*************************************************************************/
   /*************************************************************************/
   /*****                                                               *****/
@@ -4409,22 +4493,25 @@
    *   the MM machinery in case it isn't loaded yet.
    */
   FT_LOCAL_DEF( FT_Error )
-  tt_get_var_blend( TT_Face      face,
+  tt_get_var_blend( FT_Face      face,             /* TT_Face */
                     FT_UInt     *num_coords,
                     FT_Fixed*   *coords,
                     FT_Fixed*   *normalizedcoords,
                     FT_MM_Var*  *mm_var )
   {
-    if ( face->blend )
+    TT_Face  ttface = (TT_Face)face;
+
+
+    if ( ttface->blend )
     {
       if ( num_coords )
-        *num_coords       = face->blend->num_axis;
+        *num_coords       = ttface->blend->num_axis;
       if ( coords )
-        *coords           = face->blend->coords;
+        *coords           = ttface->blend->coords;
       if ( normalizedcoords )
-        *normalizedcoords = face->blend->normalizedcoords;
+        *normalizedcoords = ttface->blend->normalizedcoords;
       if ( mm_var )
-        *mm_var           = face->blend->mmvar;
+        *mm_var           = ttface->blend->mmvar;
     }
     else
     {
@@ -4441,7 +4528,7 @@
 
 
   FT_LOCAL_DEF( void )
-  tt_var_done_item_variation_store( TT_Face          face,
+  tt_var_done_item_variation_store( FT_Face          face,
                                     GX_ItemVarStore  itemStore )
   {
     FT_Memory  memory = FT_FACE_MEMORY( face );
@@ -4470,7 +4557,7 @@
 
 
   FT_LOCAL_DEF( void )
-  tt_var_done_delta_set_index_map( TT_Face            face,
+  tt_var_done_delta_set_index_map( FT_Face            face,
                                    GX_DeltaSetIdxMap  deltaSetIdxMap )
   {
     FT_Memory  memory = FT_FACE_MEMORY( face );
@@ -4490,10 +4577,11 @@
    *   Free the blend internal data structure.
    */
   FT_LOCAL_DEF( void )
-  tt_done_blend( TT_Face  face )
+  tt_done_blend( FT_Face  face )
   {
+    TT_Face    ttface = (TT_Face)face;
     FT_Memory  memory = FT_FACE_MEMORY( face );
-    GX_Blend   blend  = face->blend;
+    GX_Blend   blend  = ttface->blend;
 
 
     if ( blend )
@@ -4565,7 +4653,7 @@
 #else /* !TT_CONFIG_OPTION_GX_VAR_SUPPORT */
 
   /* ANSI C doesn't like empty source files */
-  typedef int  _tt_gxvar_dummy;
+  typedef int  tt_gxvar_dummy_;
 
 #endif /* !TT_CONFIG_OPTION_GX_VAR_SUPPORT */
 
diff --git a/src/java.desktop/share/native/libfreetype/src/truetype/ttgxvar.h b/src/java.desktop/share/native/libfreetype/src/truetype/ttgxvar.h
index 4fec980..e3da6d1 100644
--- a/src/java.desktop/share/native/libfreetype/src/truetype/ttgxvar.h
+++ b/src/java.desktop/share/native/libfreetype/src/truetype/ttgxvar.h
@@ -347,34 +347,41 @@
 
 
   FT_LOCAL( FT_Error )
-  TT_Set_MM_Blend( TT_Face    face,
+  TT_Set_MM_Blend( FT_Face    face,
                    FT_UInt    num_coords,
                    FT_Fixed*  coords );
 
   FT_LOCAL( FT_Error )
-  TT_Get_MM_Blend( TT_Face    face,
+  TT_Get_MM_Blend( FT_Face    face,
                    FT_UInt    num_coords,
                    FT_Fixed*  coords );
 
   FT_LOCAL( FT_Error )
-  TT_Set_Var_Design( TT_Face    face,
+  TT_Set_Var_Design( FT_Face    face,
                      FT_UInt    num_coords,
                      FT_Fixed*  coords );
 
   FT_LOCAL( FT_Error )
-  TT_Get_MM_Var( TT_Face      face,
+  TT_Get_MM_Var( FT_Face      face,
                  FT_MM_Var*  *master );
 
   FT_LOCAL( FT_Error )
-  TT_Get_Var_Design( TT_Face    face,
+  TT_Get_Var_Design( FT_Face    face,
                      FT_UInt    num_coords,
                      FT_Fixed*  coords );
 
   FT_LOCAL( FT_Error )
-  TT_Set_Named_Instance( TT_Face  face,
+  TT_Set_Named_Instance( FT_Face  face,
                          FT_UInt  instance_index );
 
   FT_LOCAL( FT_Error )
+  TT_Get_Default_Named_Instance( FT_Face   face,
+                                 FT_UInt  *instance_index );
+
+  FT_LOCAL( void )
+  tt_construct_ps_name( FT_Face  face );
+
+  FT_LOCAL( FT_Error )
   tt_face_vary_cvt( TT_Face    face,
                     FT_Stream  stream );
 
@@ -385,55 +392,54 @@
                               FT_Vector*   unrounded );
 
   FT_LOCAL( FT_Error )
-  tt_hadvance_adjust( TT_Face  face,
+  tt_hadvance_adjust( FT_Face  face,
                       FT_UInt  gindex,
                       FT_Int  *adelta );
 
   FT_LOCAL( FT_Error )
-  tt_vadvance_adjust( TT_Face  face,
+  tt_vadvance_adjust( FT_Face  face,
                       FT_UInt  gindex,
                       FT_Int  *adelta );
 
   FT_LOCAL( void )
-  tt_apply_mvar( TT_Face  face );
-
+  tt_apply_mvar( FT_Face  face );
 
   FT_LOCAL( FT_Error )
-  tt_var_load_item_variation_store( TT_Face          face,
+  tt_var_load_item_variation_store( FT_Face          face,
                                     FT_ULong         offset,
                                     GX_ItemVarStore  itemStore );
 
   FT_LOCAL( FT_Error )
-  tt_var_load_delta_set_index_mapping( TT_Face            face,
+  tt_var_load_delta_set_index_mapping( FT_Face            face,
                                        FT_ULong           offset,
                                        GX_DeltaSetIdxMap  map,
                                        GX_ItemVarStore    itemStore,
                                        FT_ULong           table_len );
 
   FT_LOCAL( FT_ItemVarDelta )
-  tt_var_get_item_delta( TT_Face          face,
+  tt_var_get_item_delta( FT_Face          face,
                          GX_ItemVarStore  itemStore,
                          FT_UInt          outerIndex,
                          FT_UInt          innerIndex );
 
   FT_LOCAL( void )
-  tt_var_done_item_variation_store( TT_Face          face,
+  tt_var_done_item_variation_store( FT_Face          face,
                                     GX_ItemVarStore  itemStore );
 
   FT_LOCAL( void )
-  tt_var_done_delta_set_index_map( TT_Face            face,
+  tt_var_done_delta_set_index_map( FT_Face            face,
                                    GX_DeltaSetIdxMap  deltaSetIdxMap );
 
 
   FT_LOCAL( FT_Error )
-  tt_get_var_blend( TT_Face      face,
+  tt_get_var_blend( FT_Face      face,
                     FT_UInt     *num_coords,
                     FT_Fixed*   *coords,
                     FT_Fixed*   *normalizedcoords,
                     FT_MM_Var*  *mm_var );
 
   FT_LOCAL( void )
-  tt_done_blend( TT_Face  face );
+  tt_done_blend( FT_Face  face );
 
 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
 
diff --git a/src/java.desktop/share/native/libfreetype/src/truetype/ttinterp.c b/src/java.desktop/share/native/libfreetype/src/truetype/ttinterp.c
index 4fcfaa3..79df455 100644
--- a/src/java.desktop/share/native/libfreetype/src/truetype/ttinterp.c
+++ b/src/java.desktop/share/native/libfreetype/src/truetype/ttinterp.c
@@ -29,7 +29,6 @@
 
 #include "ttinterp.h"
 #include "tterrors.h"
-#include "ttsubpix.h"
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
 #include "ttgxvar.h"
 #endif
@@ -52,12 +51,6 @@
           ( ((TT_Driver)FT_FACE_DRIVER( exc->face ))->interpreter_version == \
             TT_INTERPRETER_VERSION_35 )
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-#define SUBPIXEL_HINTING_INFINALITY                                          \
-          ( ((TT_Driver)FT_FACE_DRIVER( exc->face ))->interpreter_version == \
-            TT_INTERPRETER_VERSION_38 )
-#endif
-
 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
 #define SUBPIXEL_HINTING_MINIMAL                                             \
           ( ((TT_Driver)FT_FACE_DRIVER( exc->face ))->interpreter_version == \
@@ -278,57 +271,6 @@
   /**************************************************************************
    *
    * @Function:
-   *   Update_Max
-   *
-   * @Description:
-   *   Checks the size of a buffer and reallocates it if necessary.
-   *
-   * @Input:
-   *   memory ::
-   *     A handle to the parent memory object.
-   *
-   *   multiplier ::
-   *     The size in bytes of each element in the buffer.
-   *
-   *   new_max ::
-   *     The new capacity (size) of the buffer.
-   *
-   * @InOut:
-   *   size ::
-   *     The address of the buffer's current size expressed
-   *     in elements.
-   *
-   *   buff ::
-   *     The address of the buffer base pointer.
-   *
-   * @Return:
-   *   FreeType error code.  0 means success.
-   */
-  FT_LOCAL_DEF( FT_Error )
-  Update_Max( FT_Memory  memory,
-              FT_ULong*  size,
-              FT_ULong   multiplier,
-              void*      _pbuff,
-              FT_ULong   new_max )
-  {
-    FT_Error  error;
-    void**    pbuff = (void**)_pbuff;
-
-
-    if ( *size < new_max )
-    {
-      if ( FT_QREALLOC( *pbuff, *size * multiplier, new_max * multiplier ) )
-        return error;
-      *size = new_max;
-    }
-
-    return FT_Err_Ok;
-  }
-
-
-  /**************************************************************************
-   *
-   * @Function:
    *   TT_Load_Context
    *
    * @Description:
@@ -359,9 +301,9 @@
                    TT_Size         size )
   {
     FT_Int          i;
-    FT_ULong        tmp;
     TT_MaxProfile*  maxp;
     FT_Error        error;
+    FT_Memory       memory = exec->memory;
 
 
     exec->face = face;
@@ -406,25 +348,15 @@
 
     /* XXX: We reserve a little more elements on the stack to deal safely */
     /*      with broken fonts like arialbs, courbs, timesbs, etc.         */
-    tmp = (FT_ULong)exec->stackSize;
-    error = Update_Max( exec->memory,
-                        &tmp,
-                        sizeof ( FT_F26Dot6 ),
-                        (void*)&exec->stack,
-                        maxp->maxStackElements + 32 );
-    exec->stackSize = (FT_Long)tmp;
-    if ( error )
+    if ( FT_QRENEW_ARRAY( exec->stack,
+                          exec->stackSize,
+                          maxp->maxStackElements + 32 ) )
       return error;
+    exec->stackSize = maxp->maxStackElements + 32;
 
-    tmp = (FT_ULong)exec->glyphSize;
-    error = Update_Max( exec->memory,
-                        &tmp,
-                        sizeof ( FT_Byte ),
-                        (void*)&exec->glyphIns,
-                        maxp->maxSizeOfInstructions );
-    exec->glyphSize = (FT_UInt)tmp;
-    if ( error )
-      return error;
+    /* free previous glyph code range */
+    FT_FREE( exec->glyphIns );
+    exec->glyphSize = 0;
 
     exec->pts.n_points   = 0;
     exec->pts.n_contours = 0;
@@ -1530,14 +1462,16 @@
     if ( exc->iniRange == tt_coderange_glyph &&
          exc->cvt != exc->glyfCvt            )
     {
-      exc->error = Update_Max( exc->memory,
-                               &exc->glyfCvtSize,
-                               sizeof ( FT_Long ),
-                               (void*)&exc->glyfCvt,
-                               exc->cvtSize );
-      if ( exc->error )
+      FT_Memory  memory = exc->memory;
+      FT_Error   error;
+
+
+      FT_MEM_QRENEW_ARRAY( exc->glyfCvt, exc->glyfCvtSize, exc->cvtSize );
+      exc->error = error;
+      if ( error )
         return;
 
+      exc->glyfCvtSize = exc->cvtSize;
       FT_ARRAY_COPY( exc->glyfCvt, exc->cvt, exc->glyfCvtSize );
       exc->cvt = exc->glyfCvt;
     }
@@ -1744,17 +1678,6 @@
 
     if ( v != 0 )
     {
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-      if ( SUBPIXEL_HINTING_INFINALITY                            &&
-           ( !exc->ignore_x_mode                                ||
-             ( exc->sph_tweak_flags & SPH_TWEAK_ALLOW_X_DMOVE ) ) )
-        zone->cur[point].x = ADD_LONG( zone->cur[point].x,
-                                       FT_MulDiv( distance,
-                                                  v,
-                                                  exc->F_dot_P ) );
-      else
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
       /* Exception to the post-IUP curfew: Allow the x component of */
       /* diagonal moves, but only post-IUP.  DejaVu tries to adjust */
@@ -1860,12 +1783,6 @@
                  FT_UShort       point,
                  FT_F26Dot6      distance )
   {
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    if ( SUBPIXEL_HINTING_INFINALITY && !exc->ignore_x_mode )
-      zone->cur[point].x = ADD_LONG( zone->cur[point].x, distance );
-    else
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
     if ( SUBPIXEL_HINTING_MINIMAL && !exc->backward_compatibility )
       zone->cur[point].x = ADD_LONG( zone->cur[point].x, distance );
@@ -3069,28 +2986,7 @@
         args[0] = 0;
     }
     else
-    {
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-      /* subpixel hinting - avoid Typeman Dstroke and */
-      /* IStroke and Vacuform rounds                  */
-      if ( SUBPIXEL_HINTING_INFINALITY                 &&
-           exc->ignore_x_mode                          &&
-           ( ( I == 24                             &&
-               ( exc->face->sph_found_func_flags &
-                 ( SPH_FDEF_SPACING_1 |
-                   SPH_FDEF_SPACING_2 )          ) ) ||
-             ( I == 22                      &&
-               ( exc->sph_in_func_flags   &
-                 SPH_FDEF_TYPEMAN_STROKES ) )        ||
-             ( I == 8                              &&
-               ( exc->face->sph_found_func_flags &
-                 SPH_FDEF_VACUFORM_ROUND_1       ) &&
-               exc->iup_called                     ) ) )
-        args[0] = 0;
-      else
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-        args[0] = exc->storage[I];
-    }
+      args[0] = exc->storage[I];
   }
 
 
@@ -3117,18 +3013,18 @@
       if ( exc->iniRange == tt_coderange_glyph &&
            exc->storage != exc->glyfStorage    )
       {
-        FT_ULong  tmp = (FT_ULong)exc->glyfStoreSize;
+        FT_Memory  memory = exc->memory;
+        FT_Error   error;
 
 
-        exc->error = Update_Max( exc->memory,
-                                 &tmp,
-                                 sizeof ( FT_Long ),
-                                 (void*)&exc->glyfStorage,
-                                 exc->storeSize );
-        exc->glyfStoreSize = (FT_UShort)tmp;
-        if ( exc->error )
+        FT_MEM_QRENEW_ARRAY( exc->glyfStorage,
+                             exc->glyfStoreSize,
+                             exc->storeSize );
+        exc->error  = error;
+        if ( error )
           return;
 
+        exc->glyfStoreSize = exc->storeSize;
         FT_ARRAY_COPY( exc->glyfStorage, exc->storage, exc->glyfStoreSize );
         exc->storage = exc->glyfStorage;
       }
@@ -3604,106 +3500,6 @@
     TT_DefRecord*  rec;
     TT_DefRecord*  limit;
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    /* arguments to opcodes are skipped by `SKIP_Code' */
-    FT_Byte    opcode_pattern[9][12] = {
-                 /* #0 inline delta function 1 */
-                 {
-                   0x4B, /* PPEM    */
-                   0x53, /* GTEQ    */
-                   0x23, /* SWAP    */
-                   0x4B, /* PPEM    */
-                   0x51, /* LTEQ    */
-                   0x5A, /* AND     */
-                   0x58, /* IF      */
-                   0x38, /*   SHPIX */
-                   0x1B, /* ELSE    */
-                   0x21, /*   POP   */
-                   0x21, /*   POP   */
-                   0x59  /* EIF     */
-                 },
-                 /* #1 inline delta function 2 */
-                 {
-                   0x4B, /* PPEM    */
-                   0x54, /* EQ      */
-                   0x58, /* IF      */
-                   0x38, /*   SHPIX */
-                   0x1B, /* ELSE    */
-                   0x21, /*   POP   */
-                   0x21, /*   POP   */
-                   0x59  /* EIF     */
-                 },
-                 /* #2 diagonal stroke function */
-                 {
-                   0x20, /* DUP     */
-                   0x20, /* DUP     */
-                   0xB0, /* PUSHB_1 */
-                         /*   1     */
-                   0x60, /* ADD     */
-                   0x46, /* GC_cur  */
-                   0xB0, /* PUSHB_1 */
-                         /*   64    */
-                   0x23, /* SWAP    */
-                   0x42  /* WS      */
-                 },
-                 /* #3 VacuFormRound function */
-                 {
-                   0x45, /* RCVT    */
-                   0x23, /* SWAP    */
-                   0x46, /* GC_cur  */
-                   0x60, /* ADD     */
-                   0x20, /* DUP     */
-                   0xB0  /* PUSHB_1 */
-                         /*   38    */
-                 },
-                 /* #4 TTFautohint bytecode (old) */
-                 {
-                   0x20, /* DUP     */
-                   0x64, /* ABS     */
-                   0xB0, /* PUSHB_1 */
-                         /*   32    */
-                   0x60, /* ADD     */
-                   0x66, /* FLOOR   */
-                   0x23, /* SWAP    */
-                   0xB0  /* PUSHB_1 */
-                 },
-                 /* #5 spacing function 1 */
-                 {
-                   0x01, /* SVTCA_x */
-                   0xB0, /* PUSHB_1 */
-                         /*   24    */
-                   0x43, /* RS      */
-                   0x58  /* IF      */
-                 },
-                 /* #6 spacing function 2 */
-                 {
-                   0x01, /* SVTCA_x */
-                   0x18, /* RTG     */
-                   0xB0, /* PUSHB_1 */
-                         /*   24    */
-                   0x43, /* RS      */
-                   0x58  /* IF      */
-                 },
-                 /* #7 TypeMan Talk DiagEndCtrl function */
-                 {
-                   0x01, /* SVTCA_x */
-                   0x20, /* DUP     */
-                   0xB0, /* PUSHB_1 */
-                         /*   3     */
-                   0x25, /* CINDEX  */
-                 },
-                 /* #8 TypeMan Talk Align */
-                 {
-                   0x06, /* SPVTL   */
-                   0x7D, /* RDTG    */
-                 },
-               };
-    FT_UShort  opcode_patterns   = 9;
-    FT_UShort  opcode_pointer[9] = {  0, 0, 0, 0, 0, 0, 0, 0, 0 };
-    FT_UShort  opcode_size[9]    = { 12, 8, 8, 6, 7, 4, 5, 4, 2 };
-    FT_UShort  i;
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
 
     /* FDEF is only allowed in `prep' or `fpgm' */
     if ( exc->iniRange == tt_coderange_glyph )
@@ -3748,136 +3544,15 @@
     rec->opc            = (FT_UInt16)n;
     rec->start          = exc->IP + 1;
     rec->active         = TRUE;
-    rec->inline_delta   = FALSE;
-    rec->sph_fdef_flags = 0x0000;
 
     if ( n > exc->maxFunc )
       exc->maxFunc = (FT_UInt16)n;
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    /* We don't know for sure these are typeman functions, */
-    /* however they are only active when RS 22 is called   */
-    if ( n >= 64 && n <= 66 )
-      rec->sph_fdef_flags |= SPH_FDEF_TYPEMAN_STROKES;
-#endif
-
     /* Now skip the whole function definition. */
     /* We don't allow nested IDEFS & FDEFs.    */
 
     while ( SkipCode( exc ) == SUCCESS )
     {
-
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-
-      if ( SUBPIXEL_HINTING_INFINALITY )
-      {
-        for ( i = 0; i < opcode_patterns; i++ )
-        {
-          if ( opcode_pointer[i] < opcode_size[i]                  &&
-               exc->opcode == opcode_pattern[i][opcode_pointer[i]] )
-          {
-            opcode_pointer[i] += 1;
-
-            if ( opcode_pointer[i] == opcode_size[i] )
-            {
-              FT_TRACE6(( "sph: Function %d, opcode ptrn: %ld, %s %s\n",
-                          i, n,
-                          exc->face->root.family_name,
-                          exc->face->root.style_name ));
-
-              switch ( i )
-              {
-              case 0:
-                rec->sph_fdef_flags             |= SPH_FDEF_INLINE_DELTA_1;
-                exc->face->sph_found_func_flags |= SPH_FDEF_INLINE_DELTA_1;
-                break;
-
-              case 1:
-                rec->sph_fdef_flags             |= SPH_FDEF_INLINE_DELTA_2;
-                exc->face->sph_found_func_flags |= SPH_FDEF_INLINE_DELTA_2;
-                break;
-
-              case 2:
-                switch ( n )
-                {
-                  /* needs to be implemented still */
-                case 58:
-                  rec->sph_fdef_flags             |= SPH_FDEF_DIAGONAL_STROKE;
-                  exc->face->sph_found_func_flags |= SPH_FDEF_DIAGONAL_STROKE;
-                }
-                break;
-
-              case 3:
-                switch ( n )
-                {
-                case 0:
-                  rec->sph_fdef_flags             |= SPH_FDEF_VACUFORM_ROUND_1;
-                  exc->face->sph_found_func_flags |= SPH_FDEF_VACUFORM_ROUND_1;
-                }
-                break;
-
-              case 4:
-                /* probably not necessary to detect anymore */
-                rec->sph_fdef_flags             |= SPH_FDEF_TTFAUTOHINT_1;
-                exc->face->sph_found_func_flags |= SPH_FDEF_TTFAUTOHINT_1;
-                break;
-
-              case 5:
-                switch ( n )
-                {
-                case 0:
-                case 1:
-                case 2:
-                case 4:
-                case 7:
-                case 8:
-                  rec->sph_fdef_flags             |= SPH_FDEF_SPACING_1;
-                  exc->face->sph_found_func_flags |= SPH_FDEF_SPACING_1;
-                }
-                break;
-
-              case 6:
-                switch ( n )
-                {
-                case 0:
-                case 1:
-                case 2:
-                case 4:
-                case 7:
-                case 8:
-                  rec->sph_fdef_flags             |= SPH_FDEF_SPACING_2;
-                  exc->face->sph_found_func_flags |= SPH_FDEF_SPACING_2;
-                }
-                break;
-
-               case 7:
-                 rec->sph_fdef_flags             |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
-                 exc->face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
-                 break;
-
-               case 8:
-#if 0
-                 rec->sph_fdef_flags             |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
-                 exc->face->sph_found_func_flags |= SPH_FDEF_TYPEMAN_DIAGENDCTRL;
-#endif
-                 break;
-              }
-              opcode_pointer[i] = 0;
-            }
-          }
-
-          else
-            opcode_pointer[i] = 0;
-        }
-
-        /* Set sph_compatibility_mode only when deltas are detected */
-        exc->face->sph_compatibility_mode =
-          ( ( exc->face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_1 ) |
-            ( exc->face->sph_found_func_flags & SPH_FDEF_INLINE_DELTA_2 ) );
-      }
-
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
       switch ( exc->opcode )
       {
       case 0x89:    /* IDEF */
@@ -3905,10 +3580,6 @@
     TT_CallRec*  pRec;
 
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    exc->sph_in_func_flags = 0x0000;
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
     if ( exc->callTop <= 0 )     /* We encountered an ENDF without a call */
     {
       exc->error = FT_THROW( ENDF_In_Exec_Stream );
@@ -3996,17 +3667,6 @@
     if ( !def->active )
       goto Fail;
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    if ( SUBPIXEL_HINTING_INFINALITY                                    &&
-         exc->ignore_x_mode                                             &&
-         ( ( exc->iup_called                                        &&
-             ( exc->sph_tweak_flags & SPH_TWEAK_NO_CALL_AFTER_IUP ) ) ||
-           ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 )        ) )
-      goto Fail;
-    else
-      exc->sph_in_func_flags = def->sph_fdef_flags;
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
     /* check the call stack */
     if ( exc->callTop >= exc->callSize )
     {
@@ -4084,15 +3744,6 @@
     if ( !def->active )
       goto Fail;
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    if ( SUBPIXEL_HINTING_INFINALITY                         &&
-         exc->ignore_x_mode                                  &&
-         ( def->sph_fdef_flags & SPH_FDEF_VACUFORM_ROUND_1 ) )
-      goto Fail;
-    else
-      exc->sph_in_func_flags = def->sph_fdef_flags;
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
     /* check stack */
     if ( exc->callTop >= exc->callSize )
     {
@@ -4998,14 +4649,6 @@
       }
     }
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    /* Disable Type 2 Vacuform Rounds - e.g. Arial Narrow */
-    if ( SUBPIXEL_HINTING_INFINALITY         &&
-         exc->ignore_x_mode                  &&
-         ( D < 0 ? NEG_LONG( D ) : D ) == 64 )
-      D += 1;
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
     args[0] = D;
   }
 
@@ -5267,13 +4910,6 @@
     /* except to change the subpixel flags temporarily */
     else if ( exc->iniRange == tt_coderange_glyph && K == 3 )
     {
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-      /* INSTCTRL modifying flag 3 also has an effect */
-      /* outside of the CVT program                   */
-      if ( SUBPIXEL_HINTING_INFINALITY )
-        exc->ignore_x_mode = !FT_BOOL( L == 4 );
-#endif
-
 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
       /* Native ClearType fonts sign a waiver that turns off all backward  */
       /* compatibility hacks and lets them program points to the grid like */
@@ -5605,12 +5241,6 @@
         }
       }
       else
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-      /* doesn't follow Cleartype spec but produces better result */
-      if ( SUBPIXEL_HINTING_INFINALITY && exc->ignore_x_mode )
-        Move_Zp2_Point( exc, point, 0, dy, TRUE );
-      else
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
         Move_Zp2_Point( exc, point, dx, dy, TRUE );
 
       exc->GS.loop--;
@@ -5771,76 +5401,6 @@
         }
       }
       else
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-      if ( SUBPIXEL_HINTING_INFINALITY &&
-           exc->ignore_x_mode          )
-      {
-        FT_Int  B1, B2;
-
-
-        /*  If not using ignore_x_mode rendering, allow ZP2 move.        */
-        /*  If inline deltas aren't allowed, skip ZP2 move.              */
-        /*  If using ignore_x_mode rendering, allow ZP2 point move if:   */
-        /*   - freedom vector is y and sph_compatibility_mode is off     */
-        /*   - the glyph is composite and the move is in the Y direction */
-        /*   - the glyph is specifically set to allow SHPIX moves        */
-        /*   - the move is on a previously Y-touched point               */
-
-        /* save point for later comparison */
-        B1 = exc->zp2.cur[point].y;
-
-        if ( exc->face->sph_compatibility_mode )
-        {
-          if ( exc->sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES )
-            dy = FT_PIX_ROUND( B1 + dy ) - B1;
-
-          /* skip post-iup deltas */
-          if ( exc->iup_called                                          &&
-               ( ( exc->sph_in_func_flags & SPH_FDEF_INLINE_DELTA_1 ) ||
-                 ( exc->sph_in_func_flags & SPH_FDEF_INLINE_DELTA_2 ) ) )
-            goto Skip;
-
-          if ( !( exc->sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) &&
-                ( ( exc->is_composite && exc->GS.freeVector.y != 0 ) ||
-                  ( exc->zp2.tags[point] & FT_CURVE_TAG_TOUCH_Y )    ||
-                  ( exc->sph_tweak_flags & SPH_TWEAK_DO_SHPIX )      )  )
-            Move_Zp2_Point( exc, point, 0, dy, TRUE );
-
-          /* save new point */
-          if ( exc->GS.freeVector.y != 0 )
-          {
-            B2 = exc->zp2.cur[point].y;
-
-            /* reverse any disallowed moves */
-            if ( ( B1 & 63 ) == 0 &&
-                 ( B2 & 63 ) != 0 &&
-                 B1 != B2         )
-              Move_Zp2_Point( exc, point, 0, NEG_LONG( dy ), TRUE );
-          }
-        }
-        else if ( exc->GS.freeVector.y != 0 )
-        {
-          Move_Zp2_Point( exc, point, dx, dy, TRUE );
-
-          /* save new point */
-          B2 = exc->zp2.cur[point].y;
-
-          /* reverse any disallowed moves */
-          if ( ( exc->sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) &&
-               ( B1 & 63 ) != 0                                           &&
-               ( B2 & 63 ) != 0                                           &&
-               B1 != B2                                                   )
-            Move_Zp2_Point( exc,
-                            point,
-                            NEG_LONG( dx ),
-                            NEG_LONG( dy ),
-                            TRUE );
-        }
-        else if ( exc->sph_in_func_flags & SPH_FDEF_TYPEMAN_DIAGENDCTRL )
-          Move_Zp2_Point( exc, point, dx, dy, TRUE );
-      }
-      else
-#endif
 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
       if ( SUBPIXEL_HINTING_MINIMAL    &&
            exc->backward_compatibility )
@@ -5860,9 +5420,6 @@
 #endif
         Move_Zp2_Point( exc, point, dx, dy, TRUE );
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    Skip:
-#endif
       exc->GS.loop--;
     }
 
@@ -5907,28 +5464,6 @@
 
     distance = PROJECT( exc->zp1.cur + point, exc->zp0.cur + exc->GS.rp0 );
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    /* subpixel hinting - make MSIRP respect CVT cut-in; */
-    if ( SUBPIXEL_HINTING_INFINALITY &&
-         exc->ignore_x_mode          &&
-         exc->GS.freeVector.x != 0   )
-    {
-      FT_F26Dot6  control_value_cutin = exc->GS.control_value_cutin;
-      FT_F26Dot6  delta;
-
-
-      if ( !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
-        control_value_cutin = 0;
-
-      delta = SUB_LONG( distance, args[1] );
-      if ( delta < 0 )
-        delta = NEG_LONG( delta );
-
-      if ( delta >= control_value_cutin )
-        distance = args[1];
-    }
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
     exc->func_move( exc,
                     &exc->zp1,
                     point,
@@ -5969,14 +5504,7 @@
     if ( ( exc->opcode & 1 ) != 0 )
     {
       cur_dist = FAST_PROJECT( &exc->zp0.cur[point] );
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-      if ( SUBPIXEL_HINTING_INFINALITY &&
-           exc->ignore_x_mode          &&
-           exc->GS.freeVector.x != 0   )
-        distance = SUB_LONG( Round_None( exc, cur_dist, 3 ), cur_dist );
-      else
-#endif
-        distance = SUB_LONG( exc->func_round( exc, cur_dist, 3 ), cur_dist );
+      distance = SUB_LONG( exc->func_round( exc, cur_dist, 3 ), cur_dist );
     }
     else
       distance = 0;
@@ -6039,27 +5567,12 @@
 
     if ( exc->GS.gep0 == 0 )   /* If in twilight zone */
     {
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-      /* Only adjust if not in sph_compatibility_mode or ignore_x_mode. */
-      /* Determined via experimentation and may be incorrect...         */
-      if ( !( SUBPIXEL_HINTING_INFINALITY           &&
-              ( exc->ignore_x_mode                &&
-                exc->face->sph_compatibility_mode ) ) )
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-        exc->zp0.org[point].x = TT_MulFix14( distance,
+      exc->zp0.org[point].x = TT_MulFix14( distance,
                                              exc->GS.freeVector.x );
       exc->zp0.org[point].y = TT_MulFix14( distance,
                                            exc->GS.freeVector.y );
       exc->zp0.cur[point]   = exc->zp0.org[point];
     }
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    if ( SUBPIXEL_HINTING_INFINALITY                    &&
-         exc->ignore_x_mode                             &&
-         ( exc->sph_tweak_flags & SPH_TWEAK_MIAP_HACK ) &&
-         distance > 0                                   &&
-         exc->GS.freeVector.y != 0                      )
-      distance = 0;
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
 
     org_dist = FAST_PROJECT( &exc->zp0.cur[point] );
 
@@ -6069,15 +5582,6 @@
       FT_F26Dot6  delta;
 
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-      if ( SUBPIXEL_HINTING_INFINALITY                        &&
-           exc->ignore_x_mode                                 &&
-           exc->GS.freeVector.x != 0                          &&
-           exc->GS.freeVector.y == 0                          &&
-           !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
-        control_value_cutin = 0;
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
       delta = SUB_LONG( distance, org_dist );
       if ( delta < 0 )
         delta = NEG_LONG( delta );
@@ -6085,14 +5589,7 @@
       if ( delta > control_value_cutin )
         distance = org_dist;
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-      if ( SUBPIXEL_HINTING_INFINALITY &&
-           exc->ignore_x_mode          &&
-           exc->GS.freeVector.x != 0   )
-        distance = Round_None( exc, distance, 3 );
-      else
-#endif
-        distance = exc->func_round( exc, distance, 3 );
+      distance = exc->func_round( exc, distance, 3 );
     }
 
     exc->func_move( exc, &exc->zp0, point, SUB_LONG( distance, org_dist ) );
@@ -6185,14 +5682,7 @@
 
     if ( ( exc->opcode & 4 ) != 0 )
     {
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-      if ( SUBPIXEL_HINTING_INFINALITY &&
-           exc->ignore_x_mode          &&
-           exc->GS.freeVector.x != 0   )
-        distance = Round_None( exc, org_dist, exc->opcode & 3 );
-      else
-#endif
-        distance = exc->func_round( exc, org_dist, exc->opcode & 3 );
+      distance = exc->func_round( exc, org_dist, exc->opcode & 3 );
     }
     else
       distance = Round_None( exc, org_dist, exc->opcode & 3 );
@@ -6204,14 +5694,6 @@
       FT_F26Dot6  minimum_distance = exc->GS.minimum_distance;
 
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-      if ( SUBPIXEL_HINTING_INFINALITY                        &&
-           exc->ignore_x_mode                                 &&
-           exc->GS.freeVector.x != 0                          &&
-           !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
-        minimum_distance = 0;
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
       if ( org_dist >= 0 )
       {
         if ( distance < minimum_distance )
@@ -6354,41 +5836,7 @@
       distance = exc->func_round( exc, cvt_dist, exc->opcode & 3 );
     }
     else
-    {
-
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-      /* do cvt cut-in always in MIRP for sph */
-      if ( SUBPIXEL_HINTING_INFINALITY  &&
-           exc->ignore_x_mode           &&
-           exc->GS.gep0 == exc->GS.gep1 )
-      {
-        FT_F26Dot6  control_value_cutin = exc->GS.control_value_cutin;
-
-
-        if ( exc->GS.freeVector.x != 0                          &&
-             !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
-          control_value_cutin = 0;
-
-        if ( exc->GS.freeVector.y != 0                                 &&
-             ( exc->sph_tweak_flags & SPH_TWEAK_TIMES_NEW_ROMAN_HACK ) )
-        {
-          if ( cur_dist < -64 )
-            cvt_dist -= 16;
-          else if ( cur_dist > 64 && cur_dist < 84 )
-            cvt_dist += 32;
-        }
-
-        delta = SUB_LONG( cvt_dist, org_dist );
-        if ( delta < 0 )
-          delta = NEG_LONG( delta );
-
-        if ( delta > control_value_cutin )
-          cvt_dist = org_dist;
-      }
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
       distance = Round_None( exc, cvt_dist, exc->opcode & 3 );
-    }
 
     /* minimum distance test */
 
@@ -6397,14 +5845,6 @@
       FT_F26Dot6  minimum_distance    = exc->GS.minimum_distance;
 
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-      if ( SUBPIXEL_HINTING_INFINALITY                        &&
-           exc->ignore_x_mode                                 &&
-           exc->GS.freeVector.x != 0                          &&
-           !( exc->sph_tweak_flags & SPH_TWEAK_NORMAL_ROUND ) )
-        minimum_distance = 0;
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
       if ( org_dist >= 0 )
       {
         if ( distance < minimum_distance )
@@ -6417,51 +5857,10 @@
       }
     }
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    if ( SUBPIXEL_HINTING_INFINALITY &&
-         exc->ignore_x_mode          &&
-         exc->GS.freeVector.y != 0   )
-    {
-      FT_Int   B1, B2;
-
-
-      B1 = exc->zp1.cur[point].y;
-
-      /* Round moves if necessary */
-      if ( exc->sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES )
-        distance = FT_PIX_ROUND( B1 + distance - cur_dist ) - B1 + cur_dist;
-
-      if ( ( exc->opcode & 16 ) == 0                               &&
-           ( exc->opcode & 8 ) == 0                                &&
-           ( exc->sph_tweak_flags & SPH_TWEAK_COURIER_NEW_2_HACK ) )
-        distance += 64;
-
-      exc->func_move( exc,
-                      &exc->zp1,
-                      point,
-                      SUB_LONG( distance, cur_dist ) );
-
-      B2 = exc->zp1.cur[point].y;
-
-      /* Reverse move if necessary */
-      if ( ( exc->face->sph_compatibility_mode &&
-             ( B1 & 63 ) == 0                  &&
-             ( B2 & 63 ) != 0                  )                          ||
-           ( ( exc->sph_tweak_flags & SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES ) &&
-             ( B1 & 63 ) != 0                                           &&
-             ( B2 & 63 ) != 0                                           ) )
-        exc->func_move( exc,
-                        &exc->zp1,
-                        point,
-                        SUB_LONG( cur_dist, distance ) );
-    }
-    else
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
-      exc->func_move( exc,
-                      &exc->zp1,
-                      point,
-                      SUB_LONG( distance, cur_dist ) );
+    exc->func_move( exc,
+                    &exc->zp1,
+                    point,
+                    SUB_LONG( distance, cur_dist ) );
 
   Fail:
     exc->GS.rp1 = exc->GS.rp0;
@@ -6486,17 +5885,6 @@
     FT_F26Dot6  distance;
 
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    if ( SUBPIXEL_HINTING_INFINALITY                               &&
-         exc->ignore_x_mode                                        &&
-         exc->iup_called                                           &&
-         ( exc->sph_tweak_flags & SPH_TWEAK_NO_ALIGNRP_AFTER_IUP ) )
-    {
-      exc->error = FT_THROW( Invalid_Reference );
-      goto Fail;
-    }
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
     if ( exc->top < exc->GS.loop                  ||
          BOUNDS( exc->GS.rp0, exc->zp0.n_points ) )
     {
@@ -7055,16 +6443,6 @@
     contour = 0;
     point   = 0;
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    if ( SUBPIXEL_HINTING_INFINALITY &&
-         exc->ignore_x_mode          )
-    {
-      exc->iup_called = TRUE;
-      if ( exc->sph_tweak_flags & SPH_TWEAK_SKIP_IUP )
-        return;
-    }
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
     do
     {
       end_point   = exc->pts.contours[contour] - exc->pts.first_point;
@@ -7137,14 +6515,6 @@
     FT_Long    B;
 
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    if ( SUBPIXEL_HINTING_INFINALITY                              &&
-         exc->ignore_x_mode                                       &&
-         exc->iup_called                                          &&
-         ( exc->sph_tweak_flags & SPH_TWEAK_NO_DELTAP_AFTER_IUP ) )
-      goto Fail;
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
     P    = (FT_ULong)exc->func_cur_ppem( exc );
     nump = (FT_ULong)args[0];   /* some points theoretically may occur more
                                    than once, thus UShort isn't enough */
@@ -7197,87 +6567,21 @@
             B++;
           B *= 1L << ( 6 - exc->GS.delta_shift );
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-
-          if ( SUBPIXEL_HINTING_INFINALITY )
-          {
-            /*
-             * Allow delta move if
-             *
-             * - not using ignore_x_mode rendering,
-             * - glyph is specifically set to allow it, or
-             * - glyph is composite and freedom vector is not in subpixel
-             *   direction.
-             */
-            if ( !exc->ignore_x_mode                                   ||
-                 ( exc->sph_tweak_flags & SPH_TWEAK_ALWAYS_DO_DELTAP ) ||
-                 ( exc->is_composite && exc->GS.freeVector.y != 0 )    )
-              exc->func_move( exc, &exc->zp0, A, B );
-
-            /* Otherwise, apply subpixel hinting and compatibility mode */
-            /* rules, always skipping deltas in subpixel direction.     */
-            else if ( exc->ignore_x_mode && exc->GS.freeVector.y != 0 )
-            {
-              FT_UShort  B1, B2;
-
-
-              /* save the y value of the point now; compare after move */
-              B1 = (FT_UShort)exc->zp0.cur[A].y;
-
-              /* Standard subpixel hinting: Allow y move for y-touched */
-              /* points.  This messes up DejaVu ...                    */
-              if ( !exc->face->sph_compatibility_mode          &&
-                   ( exc->zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) )
-                exc->func_move( exc, &exc->zp0, A, B );
-
-              /* compatibility mode */
-              else if ( exc->face->sph_compatibility_mode                        &&
-                        !( exc->sph_tweak_flags & SPH_TWEAK_ALWAYS_SKIP_DELTAP ) )
-              {
-                if ( exc->sph_tweak_flags & SPH_TWEAK_ROUND_NONPIXEL_Y_MOVES )
-                  B = FT_PIX_ROUND( B1 + B ) - B1;
-
-                /* Allow delta move if using sph_compatibility_mode,   */
-                /* IUP has not been called, and point is touched on Y. */
-                if ( !exc->iup_called                            &&
-                     ( exc->zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y ) )
-                  exc->func_move( exc, &exc->zp0, A, B );
-              }
-
-              B2 = (FT_UShort)exc->zp0.cur[A].y;
-
-              /* Reverse this move if it results in a disallowed move */
-              if ( exc->GS.freeVector.y != 0                          &&
-                   ( ( exc->face->sph_compatibility_mode          &&
-                       ( B1 & 63 ) == 0                           &&
-                       ( B2 & 63 ) != 0                           ) ||
-                     ( ( exc->sph_tweak_flags                   &
-                         SPH_TWEAK_SKIP_NONPIXEL_Y_MOVES_DELTAP ) &&
-                       ( B1 & 63 ) != 0                           &&
-                       ( B2 & 63 ) != 0                           ) ) )
-                exc->func_move( exc, &exc->zp0, A, NEG_LONG( B ) );
-            }
-          }
-          else
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
-          {
 
 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
-            /* See `ttinterp.h' for details on backward compatibility */
-            /* mode.                                                  */
-            if ( SUBPIXEL_HINTING_MINIMAL    &&
-                 exc->backward_compatibility )
-            {
-              if ( !( exc->iupx_called && exc->iupy_called )              &&
-                   ( ( exc->is_composite && exc->GS.freeVector.y != 0 ) ||
-                     ( exc->zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y )        ) )
-                exc->func_move( exc, &exc->zp0, A, B );
-            }
-            else
-#endif
+          /* See `ttinterp.h' for details on backward compatibility */
+          /* mode.                                                  */
+          if ( SUBPIXEL_HINTING_MINIMAL    &&
+               exc->backward_compatibility )
+          {
+            if ( !( exc->iupx_called && exc->iupy_called )              &&
+                 ( ( exc->is_composite && exc->GS.freeVector.y != 0 ) ||
+                   ( exc->zp0.tags[A] & FT_CURVE_TAG_TOUCH_Y )        ) )
               exc->func_move( exc, &exc->zp0, A, B );
           }
+          else
+#endif
+            exc->func_move( exc, &exc->zp0, A, B );
         }
       }
       else
@@ -7380,14 +6684,6 @@
    * GETINFO[]:    GET INFOrmation
    * Opcode range: 0x88
    * Stack:        uint32 --> uint32
-   *
-   * XXX: UNDOCUMENTED: Selector bits higher than 9 are currently (May
-   *      2015) not documented in the OpenType specification.
-   *
-   *      Selector bit 11 is incorrectly described as bit 8, while the
-   *      real meaning of bit 8 (vertical LCD subpixels) stays
-   *      undocumented.  The same mistake can be found in Greg Hitchcock's
-   *      whitepaper.
    */
   static void
   Ins_GETINFO( TT_ExecContext  exc,
@@ -7399,31 +6695,8 @@
 
     K = 0;
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    /*********************************
-     * RASTERIZER VERSION
-     * Selector Bit:  0
-     * Return Bit(s): 0-7
-     */
-    if ( SUBPIXEL_HINTING_INFINALITY &&
-         ( args[0] & 1 ) != 0        &&
-         exc->subpixel_hinting       )
-    {
-      if ( exc->ignore_x_mode )
-      {
-        /* if in ClearType backward compatibility mode,         */
-        /* we sometimes change the TrueType version dynamically */
-        K = exc->rasterizer_version;
-        FT_TRACE6(( "Setting rasterizer version %d\n",
-                    exc->rasterizer_version ));
-      }
-      else
-        K = TT_INTERPRETER_VERSION_38;
-    }
-    else
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-      if ( ( args[0] & 1 ) != 0 )
-        K = driver->interpreter_version;
+    if ( ( args[0] & 1 ) != 0 )
+      K = driver->interpreter_version;
 
     /*********************************
      * GLYPH ROTATED
@@ -7446,8 +6719,6 @@
      * VARIATION GLYPH
      * Selector Bit:  3
      * Return Bit(s): 10
-     *
-     * XXX: UNDOCUMENTED!
      */
     if ( (args[0] & 8 ) != 0 && exc->face->blend )
       K |= 1 << 10;
@@ -7522,89 +6793,6 @@
     }
 #endif
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-
-    if ( SUBPIXEL_HINTING_INFINALITY                          &&
-         exc->rasterizer_version >= TT_INTERPRETER_VERSION_35 )
-    {
-
-      if ( exc->rasterizer_version >= 37 )
-      {
-        /*********************************
-         * HINTING FOR SUBPIXEL
-         * Selector Bit:  6
-         * Return Bit(s): 13
-         */
-        if ( ( args[0] & 64 ) != 0 && exc->subpixel_hinting )
-          K |= 1 << 13;
-
-        /*********************************
-         * COMPATIBLE WIDTHS ENABLED
-         * Selector Bit:  7
-         * Return Bit(s): 14
-         *
-         * Functionality still needs to be added
-         */
-        if ( ( args[0] & 128 ) != 0 && exc->compatible_widths )
-          K |= 1 << 14;
-
-        /*********************************
-         * VERTICAL LCD SUBPIXELS?
-         * Selector Bit:  8
-         * Return Bit(s): 15
-         *
-         * Functionality still needs to be added
-         */
-        if ( ( args[0] & 256 ) != 0 && exc->vertical_lcd )
-          K |= 1 << 15;
-
-        /*********************************
-         * HINTING FOR BGR?
-         * Selector Bit:  9
-         * Return Bit(s): 16
-         *
-         * Functionality still needs to be added
-         */
-        if ( ( args[0] & 512 ) != 0 && exc->bgr )
-          K |= 1 << 16;
-
-        if ( exc->rasterizer_version >= 38 )
-        {
-          /*********************************
-           * SUBPIXEL POSITIONED?
-           * Selector Bit:  10
-           * Return Bit(s): 17
-           *
-           * Functionality still needs to be added
-           */
-          if ( ( args[0] & 1024 ) != 0 && exc->subpixel_positioned )
-            K |= 1 << 17;
-
-          /*********************************
-           * SYMMETRICAL SMOOTHING
-           * Selector Bit:  11
-           * Return Bit(s): 18
-           *
-           * Functionality still needs to be added
-           */
-          if ( ( args[0] & 2048 ) != 0 && exc->symmetrical_smoothing )
-            K |= 1 << 18;
-
-          /*********************************
-           * GRAY CLEARTYPE
-           * Selector Bit:  12
-           * Return Bit(s): 19
-           *
-           * Functionality still needs to be added
-           */
-          if ( ( args[0] & 4096 ) != 0 && exc->gray_cleartype )
-            K |= 1 << 19;
-        }
-      }
-    }
-
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
     args[0] = K;
   }
 
@@ -7739,25 +6927,14 @@
   /* documentation is in ttinterp.h */
 
   FT_EXPORT_DEF( FT_Error )
-  TT_RunIns( TT_ExecContext  exc )
+  TT_RunIns( void*  exec )
   {
+    TT_ExecContext  exc = (TT_ExecContext)exec;
+
     FT_ULong   ins_counter = 0;  /* executed instructions counter */
     FT_ULong   num_twilight_points;
     FT_UShort  i;
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    FT_Byte    opcode_pattern[1][2] = {
-                  /* #8 TypeMan Talk Align */
-                  {
-                    0x06, /* SPVTL   */
-                    0x7D, /* RDTG    */
-                  },
-                };
-    FT_UShort  opcode_patterns   = 1;
-    FT_UShort  opcode_pointer[1] = { 0 };
-    FT_UShort  opcode_size[1]    = { 1 };
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
 
     /* We restrict the number of twilight points to a reasonable,     */
     /* heuristic value to avoid slow execution of malformed bytecode. */
@@ -7835,9 +7012,6 @@
     Compute_Round( exc, (FT_Byte)exc->GS.round_state );
 
     /* These flags cancel execution of some opcodes after IUP is called */
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    exc->iup_called  = FALSE;
-#endif
 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
     exc->iupx_called = FALSE;
     exc->iupy_called = FALSE;
@@ -7906,7 +7080,7 @@
         /* a variable number of arguments             */
 
         /* it is the job of the application to `activate' GX handling, */
-        /* this is, calling any of the GX API functions on the current */
+        /* that is, calling any of the GX API functions on the current */
         /* font to select a variation instance                         */
         if ( exc->face->blend )
           exc->new_top = exc->args + exc->face->blend->num_axis;
@@ -7927,39 +7101,6 @@
       exc->step_ins = TRUE;
       exc->error    = FT_Err_Ok;
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-
-      if ( SUBPIXEL_HINTING_INFINALITY )
-      {
-        for ( i = 0; i < opcode_patterns; i++ )
-        {
-          if ( opcode_pointer[i] < opcode_size[i]                  &&
-               exc->opcode == opcode_pattern[i][opcode_pointer[i]] )
-          {
-            opcode_pointer[i] += 1;
-
-            if ( opcode_pointer[i] == opcode_size[i] )
-            {
-              FT_TRACE6(( "sph: opcode ptrn: %d, %s %s\n",
-                          i,
-                          exc->face->root.family_name,
-                          exc->face->root.style_name ));
-
-              switch ( i )
-              {
-              case 0:
-                break;
-              }
-              opcode_pointer[i] = 0;
-            }
-          }
-          else
-            opcode_pointer[i] = 0;
-        }
-      }
-
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
       {
         FT_Long*  args   = exc->stack + exc->args;
         FT_Byte   opcode = exc->opcode;
@@ -8466,7 +7607,7 @@
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
         case 0x91:
           /* it is the job of the application to `activate' GX handling, */
-          /* this is, calling any of the GX API functions on the current */
+          /* that is, calling any of the GX API functions on the current */
           /* font to select a variation instance                         */
           if ( exc->face->blend )
             Ins_GETVARIATION( exc, args );
@@ -8604,7 +7745,7 @@
 #else /* !TT_USE_BYTECODE_INTERPRETER */
 
   /* ANSI C doesn't like empty source files */
-  typedef int  _tt_interp_dummy;
+  typedef int  tt_interp_dummy_;
 
 #endif /* !TT_USE_BYTECODE_INTERPRETER */
 
diff --git a/src/java.desktop/share/native/libfreetype/src/truetype/ttinterp.h b/src/java.desktop/share/native/libfreetype/src/truetype/ttinterp.h
index c54c053..e98e258 100644
--- a/src/java.desktop/share/native/libfreetype/src/truetype/ttinterp.h
+++ b/src/java.desktop/share/native/libfreetype/src/truetype/ttinterp.h
@@ -98,48 +98,6 @@
   } TT_CallRec, *TT_CallStack;
 
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-
-  /**************************************************************************
-   *
-   * These structures define rules used to tweak subpixel hinting for
-   * various fonts.  "", 0, "", NULL value indicates to match any value.
-   */
-
-#define SPH_MAX_NAME_SIZE      32
-#define SPH_MAX_CLASS_MEMBERS  100
-
-  typedef struct  SPH_TweakRule_
-  {
-    const char      family[SPH_MAX_NAME_SIZE];
-    const FT_UInt   ppem;
-    const char      style[SPH_MAX_NAME_SIZE];
-    const FT_ULong  glyph;
-
-  } SPH_TweakRule;
-
-
-  typedef struct  SPH_ScaleRule_
-  {
-    const char      family[SPH_MAX_NAME_SIZE];
-    const FT_UInt   ppem;
-    const char      style[SPH_MAX_NAME_SIZE];
-    const FT_ULong  glyph;
-    const FT_ULong  scale;
-
-  } SPH_ScaleRule;
-
-
-  typedef struct  SPH_Font_Class_
-  {
-    const char  name[SPH_MAX_NAME_SIZE];
-    const char  member[SPH_MAX_CLASS_MEMBERS][SPH_MAX_NAME_SIZE];
-
-  } SPH_Font_Class;
-
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
-
   /**************************************************************************
    *
    * The main structure for the interpreter which collects all necessary
@@ -399,38 +357,6 @@
     FT_Bool            grayscale_cleartype;
 #endif /* TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL */
 
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    TT_Round_Func      func_round_sphn;   /* subpixel rounding function */
-
-    FT_Bool            subpixel_hinting;  /* Using subpixel hinting?       */
-    FT_Bool            ignore_x_mode;     /* Standard rendering mode for   */
-                                          /* subpixel hinting.  On if gray */
-                                          /* or subpixel hinting is on.    */
-
-    /* The following 6 aren't fully implemented but here for MS rasterizer */
-    /* compatibility.                                                      */
-    FT_Bool            compatible_widths;     /* compatible widths?        */
-    FT_Bool            symmetrical_smoothing; /* symmetrical_smoothing?    */
-    FT_Bool            bgr;                   /* bgr instead of rgb?       */
-    FT_Bool            vertical_lcd;          /* long side of LCD subpixel */
-                                              /* rectangles is horizontal  */
-    FT_Bool            subpixel_positioned;   /* subpixel positioned       */
-                                              /* (DirectWrite ClearType)?  */
-    FT_Bool            gray_cleartype;        /* ClearType hinting but     */
-                                              /* grayscale rendering       */
-
-    FT_Int             rasterizer_version;    /* MS rasterizer version     */
-
-    FT_Bool            iup_called;            /* IUP called for glyph?     */
-
-    FT_ULong           sph_tweak_flags;       /* flags to control          */
-                                              /* hint tweaks               */
-
-    FT_ULong           sph_in_func_flags;     /* flags to indicate if in   */
-                                              /* special functions         */
-
-#endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
-
     /* We maintain two counters (in addition to the instruction counter) */
     /* that act as loop detectors for LOOPCALL and jump opcodes with     */
     /* negative arguments.                                               */
@@ -460,14 +386,6 @@
   FT_LOCAL( void )
   TT_Clear_CodeRange( TT_ExecContext  exec,
                       FT_Int          range );
-
-
-  FT_LOCAL( FT_Error )
-  Update_Max( FT_Memory  memory,
-              FT_ULong*  size,
-              FT_ULong   multiplier,
-              void*      _pbuff,
-              FT_ULong   new_max );
 #endif /* TT_USE_BYTECODE_INTERPRETER */
 
 
@@ -536,7 +454,7 @@
    *   invoked by the TrueType debugger.
    */
   FT_EXPORT( FT_Error )
-  TT_RunIns( TT_ExecContext  exec );
+  TT_RunIns( void*  exec );
 
 
 FT_END_HEADER
diff --git a/src/java.desktop/share/native/libfreetype/src/truetype/ttobjs.c b/src/java.desktop/share/native/libfreetype/src/truetype/ttobjs.c
index 4a8873f..5b56af7 100644
--- a/src/java.desktop/share/native/libfreetype/src/truetype/ttobjs.c
+++ b/src/java.desktop/share/native/libfreetype/src/truetype/ttobjs.c
@@ -312,7 +312,8 @@
 #define TRICK_SFNT_IDS_NUM_FACES  31
 
     static const tt_sfnt_id_rec sfnt_id[TRICK_SFNT_IDS_NUM_FACES]
-                                       [TRICK_SFNT_IDS_PER_FACE] = {
+                                       [TRICK_SFNT_IDS_PER_FACE] =
+    {
 
 #define TRICK_SFNT_ID_cvt   0
 #define TRICK_SFNT_ID_fpgm  1
@@ -581,7 +582,7 @@
     FT_Bool   result = FALSE;
 
     TT_Face   face = (TT_Face)ttface;
-    FT_UInt   asize;
+    FT_ULong  asize;
     FT_ULong  i;
     FT_ULong  glyph_index = 0;
     FT_UInt   count       = 0;
@@ -589,7 +590,7 @@
 
     for( i = 0; i < face->num_locations; i++ )
     {
-      tt_face_get_location( face, i, &asize );
+      tt_face_get_location( ttface, i, &asize );
       if ( asize > 0 )
       {
         count += 1;
@@ -777,7 +778,6 @@
     }
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
-
     {
       FT_UInt  instance_index = (FT_UInt)face_index >> 16;
 
@@ -785,14 +785,11 @@
       if ( FT_HAS_MULTIPLE_MASTERS( ttface ) &&
            instance_index > 0                )
       {
-        error = TT_Set_Named_Instance( face, instance_index );
+        error = FT_Set_Named_Instance( ttface, instance_index );
         if ( error )
           goto Exit;
-
-        tt_apply_mvar( face );
       }
     }
-
 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
 
     /* initialize standard glyph loading routines */
@@ -858,7 +855,7 @@
     face->cvt_program_size  = 0;
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
-    tt_done_blend( face );
+    tt_done_blend( ttface );
     face->blend = NULL;
 #endif
   }
@@ -1338,39 +1335,29 @@
   /**************************************************************************
    *
    * @Function:
-   *   tt_size_reset
+   *   tt_size_reset_height
    *
    * @Description:
-   *   Reset a TrueType size when resolutions and character dimensions
-   *   have been changed.
+   *   Recompute a TrueType size's ascender, descender, and height
+   *   when resolutions and character dimensions have been changed.
+   *   Used for variation fonts as an iterator function.
    *
    * @Input:
-   *   size ::
-   *     A handle to the target size object.
-   *
-   *   only_height ::
-   *     Only recompute ascender, descender, and height;
-   *     this flag is used for variation fonts where
-   *     `tt_size_reset' is used as an iterator function.
+   *   ft_size ::
+   *     A handle to the target TT_Size object. This function will be called
+   *     through a `FT_Size_Reset_Func` pointer which takes `FT_Size`. This
+   *     function must take `FT_Size` as a result. The passed `FT_Size` is
+   *     expected to point to a `TT_Size`.
    */
   FT_LOCAL_DEF( FT_Error )
-  tt_size_reset( TT_Size  size,
-                 FT_Bool  only_height )
+  tt_size_reset_height( FT_Size  ft_size )
   {
-    TT_Face           face;
-    FT_Size_Metrics*  size_metrics;
-
-
-    face = (TT_Face)size->root.face;
-
-    /* nothing to do for CFF2 */
-    if ( face->is_cff2 )
-      return FT_Err_Ok;
+    TT_Size           size         = (TT_Size)ft_size;
+    TT_Face           face         = (TT_Face)size->root.face;
+    FT_Size_Metrics*  size_metrics = &size->hinted_metrics;
 
     size->ttmetrics.valid = FALSE;
 
-    size_metrics = &size->hinted_metrics;
-
     /* copy the result from base layer */
     *size_metrics = size->root.metrics;
 
@@ -1397,12 +1384,34 @@
 
     size->ttmetrics.valid = TRUE;
 
-    if ( only_height )
-    {
-      /* we must not recompute the scaling values here since       */
-      /* `tt_size_reset' was already called (with only_height = 0) */
-      return FT_Err_Ok;
-    }
+    return FT_Err_Ok;
+  }
+
+
+  /**************************************************************************
+   *
+   * @Function:
+   *   tt_size_reset
+   *
+   * @Description:
+   *   Reset a TrueType size when resolutions and character dimensions
+   *   have been changed.
+   *
+   * @Input:
+   *   size ::
+   *     A handle to the target size object.
+   */
+  FT_LOCAL_DEF( FT_Error )
+  tt_size_reset( TT_Size  size )
+  {
+    FT_Error          error;
+    TT_Face           face         = (TT_Face)size->root.face;
+    FT_Size_Metrics*  size_metrics = &size->hinted_metrics;
+
+
+    error = tt_size_reset_height( (FT_Size)size );
+    if ( error )
+      return error;
 
     if ( face->header.Flags & 8 )
     {
@@ -1472,9 +1481,6 @@
     TT_Driver  driver = (TT_Driver)ttdriver;
 
     driver->interpreter_version = TT_INTERPRETER_VERSION_35;
-#ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-    driver->interpreter_version = TT_INTERPRETER_VERSION_38;
-#endif
 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
     driver->interpreter_version = TT_INTERPRETER_VERSION_40;
 #endif
diff --git a/src/java.desktop/share/native/libfreetype/src/truetype/ttobjs.h b/src/java.desktop/share/native/libfreetype/src/truetype/ttobjs.h
index bc6fbe7..40eb37b 100644
--- a/src/java.desktop/share/native/libfreetype/src/truetype/ttobjs.h
+++ b/src/java.desktop/share/native/libfreetype/src/truetype/ttobjs.h
@@ -162,8 +162,6 @@
     FT_Long   end;            /* where does it end?                     */
     FT_UInt   opc;            /* function #, or instruction code        */
     FT_Bool   active;         /* is it active?                          */
-    FT_Bool   inline_delta;   /* is function that defines inline delta? */
-    FT_ULong  sph_fdef_flags; /* flags to identify special functions    */
 
   } TT_DefRecord, *TT_DefArray;
 
@@ -391,8 +389,10 @@
 #endif /* TT_USE_BYTECODE_INTERPRETER */
 
   FT_LOCAL( FT_Error )
-  tt_size_reset( TT_Size  size,
-                 FT_Bool  only_height );
+  tt_size_reset_height( FT_Size  size );
+
+  FT_LOCAL( FT_Error )
+  tt_size_reset( TT_Size  size );
 
 
   /**************************************************************************
diff --git a/src/java.desktop/share/native/libfreetype/src/truetype/ttpload.c b/src/java.desktop/share/native/libfreetype/src/truetype/ttpload.c
index e08bf30..54a64c7 100644
--- a/src/java.desktop/share/native/libfreetype/src/truetype/ttpload.c
+++ b/src/java.desktop/share/native/libfreetype/src/truetype/ttpload.c
@@ -180,10 +180,11 @@
 
 
   FT_LOCAL_DEF( FT_ULong )
-  tt_face_get_location( TT_Face   face,
-                        FT_UInt   gindex,
-                        FT_UInt  *asize )
+  tt_face_get_location( FT_Face    face,   /* TT_Face */
+                        FT_UInt    gindex,
+                        FT_ULong  *asize )
   {
+    TT_Face   ttface = (TT_Face)face;
     FT_ULong  pos1, pos2;
     FT_Byte*  p;
     FT_Byte*  p_limit;
@@ -191,12 +192,12 @@
 
     pos1 = pos2 = 0;
 
-    if ( gindex < face->num_locations )
+    if ( gindex < ttface->num_locations )
     {
-      if ( face->header.Index_To_Loc_Format != 0 )
+      if ( ttface->header.Index_To_Loc_Format != 0 )
       {
-        p       = face->glyph_locations + gindex * 4;
-        p_limit = face->glyph_locations + face->num_locations * 4;
+        p       = ttface->glyph_locations + gindex * 4;
+        p_limit = ttface->glyph_locations + ttface->num_locations * 4;
 
         pos1 = FT_NEXT_ULONG( p );
         pos2 = pos1;
@@ -206,8 +207,8 @@
       }
       else
       {
-        p       = face->glyph_locations + gindex * 2;
-        p_limit = face->glyph_locations + face->num_locations * 2;
+        p       = ttface->glyph_locations + gindex * 2;
+        p_limit = ttface->glyph_locations + ttface->num_locations * 2;
 
         pos1 = FT_NEXT_USHORT( p );
         pos2 = pos1;
@@ -221,30 +222,30 @@
     }
 
     /* Check broken location data. */
-    if ( pos1 > face->glyf_len )
+    if ( pos1 > ttface->glyf_len )
     {
       FT_TRACE1(( "tt_face_get_location:"
                   " too large offset (0x%08lx) found for glyph index %d,\n",
                   pos1, gindex ));
       FT_TRACE1(( "                     "
                   " exceeding the end of `glyf' table (0x%08lx)\n",
-                  face->glyf_len ));
+                  ttface->glyf_len ));
       *asize = 0;
       return 0;
     }
 
-    if ( pos2 > face->glyf_len )
+    if ( pos2 > ttface->glyf_len )
     {
       /* We try to sanitize the last `loca' entry. */
-      if ( gindex == face->num_locations - 2 )
+      if ( gindex == ttface->num_locations - 2 )
       {
         FT_TRACE1(( "tt_face_get_location:"
                     " too large size (%ld bytes) found for glyph index %d,\n",
                     pos2 - pos1, gindex ));
         FT_TRACE1(( "                     "
                     " truncating at the end of `glyf' table to %ld bytes\n",
-                    face->glyf_len - pos1 ));
-        pos2 = face->glyf_len;
+                    ttface->glyf_len - pos1 ));
+        pos2 = ttface->glyf_len;
       }
       else
       {
@@ -253,7 +254,7 @@
                     pos2, gindex + 1 ));
         FT_TRACE1(( "                     "
                     " exceeding the end of `glyf' table (0x%08lx)\n",
-                    face->glyf_len ));
+                    ttface->glyf_len ));
         *asize = 0;
         return 0;
       }
@@ -268,9 +269,9 @@
     /* We get (intentionally) a wrong, non-zero result in case the  */
     /* `glyf' table is missing.                                     */
     if ( pos2 >= pos1 )
-      *asize = (FT_UInt)( pos2 - pos1 );
+      *asize = (FT_ULong)( pos2 - pos1 );
     else
-      *asize = (FT_UInt)( face->glyf_len - pos1 );
+      *asize = (FT_ULong)( ttface->glyf_len - pos1 );
 
     return pos1;
   }
diff --git a/src/java.desktop/share/native/libfreetype/src/truetype/ttpload.h b/src/java.desktop/share/native/libfreetype/src/truetype/ttpload.h
index 939e02f..ed229fa 100644
--- a/src/java.desktop/share/native/libfreetype/src/truetype/ttpload.h
+++ b/src/java.desktop/share/native/libfreetype/src/truetype/ttpload.h
@@ -31,9 +31,9 @@
                      FT_Stream  stream );
 
   FT_LOCAL( FT_ULong )
-  tt_face_get_location( TT_Face   face,
-                        FT_UInt   gindex,
-                        FT_UInt  *asize );
+  tt_face_get_location( FT_Face    face,
+                        FT_UInt    gindex,
+                        FT_ULong  *asize );
 
   FT_LOCAL( void )
   tt_face_done_loca( TT_Face  face );
diff --git a/src/java.desktop/share/native/libfreetype/src/type1/t1afm.c b/src/java.desktop/share/native/libfreetype/src/type1/t1afm.c
index 608582c..d9b9398 100644
--- a/src/java.desktop/share/native/libfreetype/src/type1/t1afm.c
+++ b/src/java.desktop/share/native/libfreetype/src/type1/t1afm.c
@@ -405,7 +405,7 @@
 #else /* T1_CONFIG_OPTION_NO_AFM */
 
   /* ANSI C doesn't like empty source files */
-  typedef int  _t1_afm_dummy;
+  typedef int  t1_afm_dummy_;
 
 #endif /* T1_CONFIG_OPTION_NO_AFM */
 
diff --git a/src/java.desktop/share/native/libfreetype/src/type1/t1driver.c b/src/java.desktop/share/native/libfreetype/src/type1/t1driver.c
index ded3b26..a4cdf37 100644
--- a/src/java.desktop/share/native/libfreetype/src/type1/t1driver.c
+++ b/src/java.desktop/share/native/libfreetype/src/type1/t1driver.c
@@ -56,28 +56,32 @@
    *
    */
 
-  static FT_Error
-  t1_get_glyph_name( T1_Face     face,
+  FT_CALLBACK_DEF( FT_Error )
+  t1_get_glyph_name( FT_Face     face,        /* T1_Face */
                      FT_UInt     glyph_index,
                      FT_Pointer  buffer,
                      FT_UInt     buffer_max )
   {
-    FT_STRCPYN( buffer, face->type1.glyph_names[glyph_index], buffer_max );
+    T1_Face  t1face = (T1_Face)face;
+
+
+    FT_STRCPYN( buffer, t1face->type1.glyph_names[glyph_index], buffer_max );
 
     return FT_Err_Ok;
   }
 
 
-  static FT_UInt
-  t1_get_name_index( T1_Face           face,
+  FT_CALLBACK_DEF( FT_UInt )
+  t1_get_name_index( FT_Face           face,        /* T1_Face */
                      const FT_String*  glyph_name )
   {
-    FT_Int  i;
+    T1_Face  t1face = (T1_Face)face;
+    FT_Int   i;
 
 
-    for ( i = 0; i < face->type1.num_glyphs; i++ )
+    for ( i = 0; i < t1face->type1.num_glyphs; i++ )
     {
-      FT_String*  gname = face->type1.glyph_names[i];
+      FT_String*  gname = t1face->type1.glyph_names[i];
 
 
       if ( !ft_strcmp( glyph_name, gname ) )
@@ -90,8 +94,8 @@
 
   static const FT_Service_GlyphDictRec  t1_service_glyph_dict =
   {
-    (FT_GlyphDict_GetNameFunc)  t1_get_glyph_name,    /* get_name   */
-    (FT_GlyphDict_NameIndexFunc)t1_get_name_index     /* name_index */
+    t1_get_glyph_name,  /* FT_GlyphDict_GetNameFunc   get_name   */
+    t1_get_name_index   /* FT_GlyphDict_NameIndexFunc name_index */
   };
 
 
@@ -101,9 +105,12 @@
    */
 
   static const char*
-  t1_get_ps_name( T1_Face  face )
+  t1_get_ps_name( FT_Face  face )    /* T1_Face */
   {
-    return (const char*) face->type1.font_name;
+    T1_Face  t1face = (T1_Face)face;
+
+
+    return (const char*) t1face->type1.font_name;
   }
 
 
@@ -121,30 +128,28 @@
 #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
   static const FT_Service_MultiMastersRec  t1_service_multi_masters =
   {
-    (FT_Get_MM_Func)        T1_Get_Multi_Master,    /* get_mm                    */
-    (FT_Set_MM_Design_Func) T1_Set_MM_Design,       /* set_mm_design             */
-    (FT_Set_MM_Blend_Func)  T1_Set_MM_Blend,        /* set_mm_blend              */
-    (FT_Get_MM_Blend_Func)  T1_Get_MM_Blend,        /* get_mm_blend              */
-    (FT_Get_MM_Var_Func)    T1_Get_MM_Var,          /* get_mm_var                */
-    (FT_Set_Var_Design_Func)T1_Set_Var_Design,      /* set_var_design            */
-    (FT_Get_Var_Design_Func)T1_Get_Var_Design,      /* get_var_design            */
-    (FT_Set_Instance_Func)  T1_Reset_MM_Blend,      /* set_instance              */
-    (FT_Set_MM_WeightVector_Func)
-                            T1_Set_MM_WeightVector, /* set_mm_weightvector       */
-    (FT_Get_MM_WeightVector_Func)
-                            T1_Get_MM_WeightVector, /* get_mm_weightvector       */
-    (FT_Var_Load_Delta_Set_Idx_Map_Func)
-                            NULL,                   /* load_delta_set_idx_map    */
-    (FT_Var_Load_Item_Var_Store_Func)
-                            NULL,                   /* load_item_variation_store */
-    (FT_Var_Get_Item_Delta_Func)
-                            NULL,                   /* get_item_delta            */
-    (FT_Var_Done_Item_Var_Store_Func)
-                            NULL,                   /* done_item_variation_store */
-    (FT_Var_Done_Delta_Set_Idx_Map_Func)
-                            NULL,                   /* done_delta_set_index_map  */
-    (FT_Get_Var_Blend_Func) NULL,                   /* get_var_blend             */
-    (FT_Done_Blend_Func)    T1_Done_Blend           /* done_blend                */
+    T1_Get_Multi_Master,    /* FT_Get_MM_Func             get_mm             */
+    T1_Set_MM_Design,       /* FT_Set_MM_Design_Func      set_mm_design      */
+    T1_Set_MM_Blend,        /* FT_Set_MM_Blend_Func       set_mm_blend       */
+    T1_Get_MM_Blend,        /* FT_Get_MM_Blend_Func       get_mm_blend       */
+    T1_Get_MM_Var,          /* FT_Get_MM_Var_Func         get_mm_var         */
+    T1_Set_Var_Design,      /* FT_Set_Var_Design_Func     set_var_design     */
+    T1_Get_Var_Design,      /* FT_Get_Var_Design_Func     get_var_design     */
+    T1_Reset_MM_Blend,      /* FT_Set_Named_Instance_Func set_named_instance */
+    NULL,   /* FT_Get_Default_Named_Instance_Func get_default_named_instance */
+    T1_Set_MM_WeightVector,
+            /* FT_Set_MM_WeightVector_Func        set_mm_weightvector        */
+    T1_Get_MM_WeightVector,
+            /* FT_Get_MM_WeightVector_Func        get_mm_weightvector        */
+
+    NULL,   /* FT_Construct_PS_Name_Func          construct_ps_name          */
+    NULL,   /* FT_Var_Load_Delta_Set_Idx_Map_Func load_delta_set_idx_map     */
+    NULL,   /* FT_Var_Load_Item_Var_Store_Func    load_item_variation_store  */
+    NULL,   /* FT_Var_Get_Item_Delta_Func         get_item_delta             */
+    NULL,   /* FT_Var_Done_Item_Var_Store_Func    done_item_variation_store  */
+    NULL,   /* FT_Var_Done_Delta_Set_Idx_Map_Func done_delta_set_index_map   */
+    NULL,           /* FT_Get_Var_Blend_Func      get_var_blend              */
+    T1_Done_Blend   /* FT_Done_Blend_Func         done_blend                 */
   };
 #endif
 
@@ -632,11 +637,11 @@
 
   static const FT_Service_PsInfoRec  t1_service_ps_info =
   {
-    (PS_GetFontInfoFunc)   t1_ps_get_font_info,    /* ps_get_font_info    */
-    (PS_GetFontExtraFunc)  t1_ps_get_font_extra,   /* ps_get_font_extra   */
-    (PS_HasGlyphNamesFunc) t1_ps_has_glyph_names,  /* ps_has_glyph_names  */
-    (PS_GetFontPrivateFunc)t1_ps_get_font_private, /* ps_get_font_private */
-    (PS_GetFontValueFunc)  t1_ps_get_font_value,   /* ps_get_font_value   */
+    t1_ps_get_font_info,     /* PS_GetFontInfoFunc    ps_get_font_info    */
+    t1_ps_get_font_extra,    /* PS_GetFontExtraFunc   ps_get_font_extra   */
+    t1_ps_has_glyph_names,   /* PS_HasGlyphNamesFunc  ps_has_glyph_names  */
+    t1_ps_get_font_private,  /* PS_GetFontPrivateFunc ps_get_font_private */
+    t1_ps_get_font_value,    /* PS_GetFontValueFunc   ps_get_font_value   */
   };
 
 
@@ -656,9 +661,9 @@
   FT_DEFINE_SERVICE_PROPERTIESREC(
     t1_service_properties,
 
-    (FT_Properties_SetFunc)ps_property_set,      /* set_property */
-    (FT_Properties_GetFunc)ps_property_get )     /* get_property */
-
+    ps_property_set,  /* FT_Properties_SetFunc set_property */
+    ps_property_get   /* FT_Properties_GetFunc get_property */
+  )
 
   /*
    * SERVICE LIST
diff --git a/src/java.desktop/share/native/libfreetype/src/type1/t1load.c b/src/java.desktop/share/native/libfreetype/src/type1/t1load.c
index 5a1afd8..be7cd0f 100644
--- a/src/java.desktop/share/native/libfreetype/src/type1/t1load.c
+++ b/src/java.desktop/share/native/libfreetype/src/type1/t1load.c
@@ -73,7 +73,8 @@
 
 
 #ifdef FT_CONFIG_OPTION_INCREMENTAL
-#define IS_INCREMENTAL  FT_BOOL( face->root.internal->incremental_interface )
+#define IS_INCREMENTAL  \
+          FT_BOOL( FT_FACE( face )->internal->incremental_interface )
 #else
 #define IS_INCREMENTAL  0
 #endif
@@ -174,10 +175,11 @@
 
 
   FT_LOCAL_DEF( FT_Error )
-  T1_Get_Multi_Master( T1_Face           face,
+  T1_Get_Multi_Master( FT_Face           face,    /* T1_Face */
                        FT_Multi_Master*  master )
   {
-    PS_Blend  blend = face->blend;
+    T1_Face   t1face = (T1_Face)face;
+    PS_Blend  blend  = t1face->blend;
     FT_UInt   n;
     FT_Error  error;
 
@@ -225,11 +227,12 @@
     for ( j = 1; j < axismap->num_points; j++ )
     {
       if ( ncv <= axismap->blend_points[j] )
-        return INT_TO_FIXED( axismap->design_points[j - 1] ) +
-               ( axismap->design_points[j] - axismap->design_points[j - 1] ) *
-               FT_DivFix( ncv - axismap->blend_points[j - 1],
-                          axismap->blend_points[j] -
-                            axismap->blend_points[j - 1] );
+        return INT_TO_FIXED( axismap->design_points[j - 1] +
+                               FT_MulDiv( ncv - axismap->blend_points[j - 1],
+                                          axismap->design_points[j] -
+                                            axismap->design_points[j - 1],
+                                          axismap->blend_points[j] -
+                                            axismap->blend_points[j - 1] ) );
     }
 
     return INT_TO_FIXED( axismap->design_points[axismap->num_points - 1] );
@@ -284,16 +287,17 @@
    * arguments needed by the GX var distortable fonts.
    */
   FT_LOCAL_DEF( FT_Error )
-  T1_Get_MM_Var( T1_Face      face,
+  T1_Get_MM_Var( FT_Face      face,    /* T1_Face */
                  FT_MM_Var*  *master )
   {
-    FT_Memory        memory = face->root.memory;
-    FT_MM_Var       *mmvar = NULL;
+    T1_Face          t1face = (T1_Face)face;
+    FT_Memory        memory = FT_FACE_MEMORY( face );
+    FT_MM_Var       *mmvar  = NULL;
     FT_Multi_Master  mmaster;
     FT_Error         error;
     FT_UInt          i;
     FT_Fixed         axiscoords[T1_MAX_MM_AXIS];
-    PS_Blend         blend = face->blend;
+    PS_Blend         blend  = t1face->blend;
     FT_UShort*       axis_flags;
 
     FT_Offset  mmvar_size;
@@ -319,9 +323,9 @@
                                   sizeof ( FT_UShort ) );
     axis_size       = mmaster.num_axis * sizeof ( FT_Var_Axis );
 
-    if ( FT_ALLOC( mmvar, mmvar_size +
-                          axis_flags_size +
-                          axis_size ) )
+    if ( FT_QALLOC( mmvar, mmvar_size +
+                           axis_flags_size +
+                           axis_size ) )
       goto Exit;
 
     mmvar->num_axis        = mmaster.num_axis;
@@ -332,8 +336,7 @@
     /* to make `FT_Get_Var_Axis_Flags' work: the function expects that the */
     /* values directly follow the data of `FT_MM_Var'                      */
     axis_flags = (FT_UShort*)( (char*)mmvar + mmvar_size );
-    for ( i = 0; i < mmaster.num_axis; i++ )
-      axis_flags[i] = 0;
+    FT_ARRAY_ZERO( axis_flags, mmaster.num_axis );
 
     mmvar->axis       = (FT_Var_Axis*)( (char*)axis_flags + axis_flags_size );
     mmvar->namedstyle = NULL;
@@ -438,32 +441,21 @@
 
 
   FT_LOCAL_DEF( FT_Error )
-  T1_Set_MM_Blend( T1_Face    face,
+  T1_Set_MM_Blend( FT_Face    face,       /* T1_Face */
                    FT_UInt    num_coords,
                    FT_Fixed*  coords )
   {
-    FT_Error  error;
-
-
-    error = t1_set_mm_blend( face, num_coords, coords );
-    if ( error )
-      return error;
-
-    if ( num_coords )
-      face->root.face_flags |= FT_FACE_FLAG_VARIATION;
-    else
-      face->root.face_flags &= ~FT_FACE_FLAG_VARIATION;
-
-    return FT_Err_Ok;
+    return t1_set_mm_blend( (T1_Face)face, num_coords, coords );
   }
 
 
   FT_LOCAL_DEF( FT_Error )
-  T1_Get_MM_Blend( T1_Face    face,
+  T1_Get_MM_Blend( FT_Face    face,       /* T1_Face */
                    FT_UInt    num_coords,
                    FT_Fixed*  coords )
   {
-    PS_Blend  blend = face->blend;
+    T1_Face   t1face = (T1_Face)face;
+    PS_Blend  blend  = t1face->blend;
 
     FT_Fixed  axiscoords[4];
     FT_UInt   i, nc;
@@ -494,11 +486,12 @@
 
 
   FT_LOCAL_DEF( FT_Error )
-  T1_Set_MM_WeightVector( T1_Face    face,
+  T1_Set_MM_WeightVector( FT_Face    face,          /* T1_Face */
                           FT_UInt    len,
                           FT_Fixed*  weightvector )
   {
-    PS_Blend  blend = face->blend;
+    T1_Face   t1face = (T1_Face)face;
+    PS_Blend  blend  = t1face->blend;
     FT_UInt   i, n;
 
 
@@ -522,11 +515,6 @@
 
       for ( ; i < blend->num_designs; i++ )
         blend->weight_vector[i] = (FT_Fixed)0;
-
-      if ( len )
-        face->root.face_flags |= FT_FACE_FLAG_VARIATION;
-      else
-        face->root.face_flags &= ~FT_FACE_FLAG_VARIATION;
     }
 
     return FT_Err_Ok;
@@ -534,11 +522,12 @@
 
 
   FT_LOCAL_DEF( FT_Error )
-  T1_Get_MM_WeightVector( T1_Face    face,
+  T1_Get_MM_WeightVector( FT_Face    face,          /* T1_Face */
                           FT_UInt*   len,
                           FT_Fixed*  weightvector )
   {
-    PS_Blend  blend = face->blend;
+    T1_Face   t1face = (T1_Face)face;
+    PS_Blend  blend  = t1face->blend;
     FT_UInt   i;
 
 
@@ -563,12 +552,13 @@
 
 
   FT_LOCAL_DEF( FT_Error )
-  T1_Set_MM_Design( T1_Face   face,
+  T1_Set_MM_Design( FT_Face   face,       /* T1_Face */
                     FT_UInt   num_coords,
                     FT_Long*  coords )
   {
+    T1_Face   t1face = (T1_Face)face;
     FT_Error  error;
-    PS_Blend  blend = face->blend;
+    PS_Blend  blend  = t1face->blend;
     FT_UInt   n;
     FT_Fixed  final_blends[T1_MAX_MM_DESIGNS];
 
@@ -634,15 +624,10 @@
       final_blends[n] = the_blend;
     }
 
-    error = t1_set_mm_blend( face, blend->num_axis, final_blends );
+    error = t1_set_mm_blend( t1face, blend->num_axis, final_blends );
     if ( error )
       return error;
 
-    if ( num_coords )
-      face->root.face_flags |= FT_FACE_FLAG_VARIATION;
-    else
-      face->root.face_flags &= ~FT_FACE_FLAG_VARIATION;
-
     return FT_Err_Ok;
   }
 
@@ -650,7 +635,7 @@
   /* MM fonts don't have named instances, so only the design is reset */
 
   FT_LOCAL_DEF( FT_Error )
-  T1_Reset_MM_Blend( T1_Face  face,
+  T1_Reset_MM_Blend( FT_Face  face,
                      FT_UInt  instance_index )
   {
     FT_UNUSED( instance_index );
@@ -665,7 +650,7 @@
    * arguments needed by the GX var distortable fonts.
    */
   FT_LOCAL_DEF( FT_Error )
-  T1_Set_Var_Design( T1_Face    face,
+  T1_Set_Var_Design( FT_Face    face,       /* T1_Face */
                      FT_UInt    num_coords,
                      FT_Fixed*  coords )
   {
@@ -684,11 +669,12 @@
 
 
   FT_LOCAL_DEF( FT_Error )
-  T1_Get_Var_Design( T1_Face    face,
+  T1_Get_Var_Design( FT_Face    face,       /* T1_Face */
                      FT_UInt    num_coords,
                      FT_Fixed*  coords )
   {
-    PS_Blend  blend = face->blend;
+    T1_Face   t1face = (T1_Face)face;
+    PS_Blend  blend  = t1face->blend;
 
     FT_Fixed  axiscoords[4];
     FT_UInt   i, nc;
@@ -720,10 +706,11 @@
 
 
   FT_LOCAL_DEF( void )
-  T1_Done_Blend( T1_Face  face )
+  T1_Done_Blend( FT_Face  face )    /* T1_Face */
   {
-    FT_Memory  memory = face->root.memory;
-    PS_Blend   blend  = face->blend;
+    T1_Face    t1face = (T1_Face)face;
+    FT_Memory  memory = FT_FACE_MEMORY( face );
+    PS_Blend   blend  = t1face->blend;
 
 
     if ( blend )
@@ -768,20 +755,22 @@
         dmap->num_points = 0;
       }
 
-      FT_FREE( face->blend );
+      FT_FREE( t1face->blend );
     }
   }
 
 
   static void
-  parse_blend_axis_types( T1_Face    face,
-                          T1_Loader  loader )
+  parse_blend_axis_types( FT_Face  face,     /* T1_Face */
+                          void*    loader_ )
   {
+    T1_Face      t1face = (T1_Face)face;
+    T1_Loader    loader = (T1_Loader)loader_;
     T1_TokenRec  axis_tokens[T1_MAX_MM_AXIS];
     FT_Int       n, num_axis;
-    FT_Error     error = FT_Err_Ok;
+    FT_Error     error  = FT_Err_Ok;
     PS_Blend     blend;
-    FT_Memory    memory;
+    FT_Memory    memory = FT_FACE_MEMORY( face );
 
 
     /* take an array of objects */
@@ -801,14 +790,13 @@
     }
 
     /* allocate blend if necessary */
-    error = t1_allocate_blend( face, 0, (FT_UInt)num_axis );
+    error = t1_allocate_blend( t1face, 0, (FT_UInt)num_axis );
     if ( error )
       goto Exit;
 
     FT_TRACE4(( " [" ));
 
-    blend  = face->blend;
-    memory = face->root.memory;
+    blend = t1face->blend;
 
     /* each token is an immediate containing the name of the axis */
     for ( n = 0; n < num_axis; n++ )
@@ -856,14 +844,16 @@
 
 
   static void
-  parse_blend_design_positions( T1_Face    face,
-                                T1_Loader  loader )
+  parse_blend_design_positions( FT_Face  face,     /* T1_Face */
+                                void*    loader_ )
   {
+    T1_Face      t1face   = (T1_Face)face;
+    T1_Loader    loader   = (T1_Loader)loader_;
     T1_TokenRec  design_tokens[T1_MAX_MM_DESIGNS];
     FT_Int       num_designs;
     FT_Int       num_axis = 0; /* make compiler happy */
     T1_Parser    parser   = &loader->parser;
-    FT_Memory    memory   = face->root.memory;
+    FT_Memory    memory   = FT_FACE_MEMORY( face );
     FT_Error     error    = FT_Err_Ok;
     FT_Fixed*    design_pos[T1_MAX_MM_DESIGNS];
 
@@ -921,7 +911,7 @@
           }
 
           num_axis = n_axis;
-          error = t1_allocate_blend( face,
+          error = t1_allocate_blend( t1face,
                                      (FT_UInt)num_designs,
                                      (FT_UInt)num_axis );
           if ( error )
@@ -962,7 +952,7 @@
       loader->parser.root.limit  = old_limit;
 
       /* a valid BlendDesignPosition has been parsed */
-      blend = face->blend;
+      blend = t1face->blend;
       if ( blend->design_pos[0] )
         FT_FREE( blend->design_pos[0] );
 
@@ -980,9 +970,11 @@
 
 
   static void
-  parse_blend_design_map( T1_Face    face,
-                          T1_Loader  loader )
+  parse_blend_design_map( FT_Face  face,     /* T1_Face */
+                          void*    loader_ )
   {
+    T1_Face      t1face = (T1_Face)face;
+    T1_Loader    loader = (T1_Loader)loader_;
     FT_Error     error  = FT_Err_Ok;
     T1_Parser    parser = &loader->parser;
     PS_Blend     blend;
@@ -990,7 +982,7 @@
     FT_Int       n, num_axis;
     FT_Byte*     old_cursor;
     FT_Byte*     old_limit;
-    FT_Memory    memory = face->root.memory;
+    FT_Memory    memory = FT_FACE_MEMORY( face );
 
 
     T1_ToTokenArray( parser, axis_tokens,
@@ -1011,10 +1003,10 @@
     old_cursor = parser->root.cursor;
     old_limit  = parser->root.limit;
 
-    error = t1_allocate_blend( face, 0, (FT_UInt)num_axis );
+    error = t1_allocate_blend( t1face, 0, (FT_UInt)num_axis );
     if ( error )
       goto Exit;
-    blend = face->blend;
+    blend = t1face->blend;
 
     FT_TRACE4(( " [" ));
 
@@ -1089,15 +1081,17 @@
 
 
   static void
-  parse_weight_vector( T1_Face    face,
-                       T1_Loader  loader )
+  parse_weight_vector( FT_Face  face,     /* T1_Face */
+                       void*    loader_ )
   {
+    T1_Face      t1face = (T1_Face)face;
+    T1_Loader    loader = (T1_Loader)loader_;
     T1_TokenRec  design_tokens[T1_MAX_MM_DESIGNS];
     FT_Int       num_designs;
     FT_Error     error  = FT_Err_Ok;
-    FT_Memory    memory = face->root.memory;
+    FT_Memory    memory = FT_FACE_MEMORY( face );
     T1_Parser    parser = &loader->parser;
-    PS_Blend     blend  = face->blend;
+    PS_Blend     blend  = t1face->blend;
     T1_Token     token;
     FT_Int       n;
     FT_Byte*     old_cursor;
@@ -1122,10 +1116,10 @@
 
     if ( !blend || !blend->num_designs )
     {
-      error = t1_allocate_blend( face, (FT_UInt)num_designs, 0 );
+      error = t1_allocate_blend( t1face, (FT_UInt)num_designs, 0 );
       if ( error )
         goto Exit;
-      blend = face->blend;
+      blend = t1face->blend;
     }
     else if ( blend->num_designs != (FT_UInt)num_designs )
     {
@@ -1173,11 +1167,15 @@
   /* e.g., /BuildCharArray [0 0 0 0 0 0 0 0] def           */
   /* we're only interested in the number of array elements */
   static void
-  parse_buildchar( T1_Face    face,
-                   T1_Loader  loader )
+  parse_buildchar( FT_Face  face,     /* T1_Face */
+                   void*    loader_ )
   {
-    face->len_buildchar = (FT_UInt)T1_ToFixedArray( &loader->parser,
-                                                    0, NULL, 0 );
+    T1_Face    t1face = (T1_Face)face;
+    T1_Loader  loader = (T1_Loader)loader_;
+
+
+    t1face->len_buildchar = (FT_UInt)T1_ToFixedArray( &loader->parser,
+                                                      0, NULL, 0 );
 
 #ifdef FT_DEBUG_LEVEL_TRACE
     {
@@ -1185,7 +1183,7 @@
 
 
       FT_TRACE4(( " [" ));
-      for ( i = 0; i < face->len_buildchar; i++ )
+      for ( i = 0; i < t1face->len_buildchar; i++ )
         FT_TRACE4(( " 0" ));
 
       FT_TRACE4(( "]\n" ));
@@ -1335,9 +1333,10 @@
 
 
   static void
-  parse_private( T1_Face    face,
-                 T1_Loader  loader )
+  parse_private( FT_Face  face,
+                 void*    loader_ )
   {
+    T1_Loader  loader = (T1_Loader)loader_;
     FT_UNUSED( face );
 
     loader->keywords_encountered |= T1_PRIVATE;
@@ -1401,13 +1400,14 @@
   /* and `/CharStrings' dictionaries.                                */
 
   static void
-  t1_parse_font_matrix( T1_Face    face,
-                        T1_Loader  loader )
+  t1_parse_font_matrix( FT_Face  face,     /* T1_Face */
+                        void*    loader_ )
   {
+    T1_Face     t1face = (T1_Face)face;
+    T1_Loader   loader = (T1_Loader)loader_;
     T1_Parser   parser = &loader->parser;
-    FT_Matrix*  matrix = &face->type1.font_matrix;
-    FT_Vector*  offset = &face->type1.font_offset;
-    FT_Face     root   = (FT_Face)&face->root;
+    FT_Matrix*  matrix = &t1face->type1.font_matrix;
+    FT_Vector*  offset = &t1face->type1.font_offset;
     FT_Fixed    temp[6];
     FT_Fixed    temp_scale;
     FT_Int      result;
@@ -1443,7 +1443,7 @@
     if ( temp_scale != 0x10000L )
     {
       /* set units per EM based on FontMatrix values */
-      root->units_per_EM = (FT_UShort)FT_DivFix( 1000, temp_scale );
+      face->units_per_EM = (FT_UShort)FT_DivFix( 1000, temp_scale );
 
       temp[0] = FT_DivFix( temp[0], temp_scale );
       temp[1] = FT_DivFix( temp[1], temp_scale );
@@ -1471,14 +1471,16 @@
 
 
   static void
-  parse_encoding( T1_Face    face,
-                  T1_Loader  loader )
+  parse_encoding( FT_Face  face,     /* T1_Face */
+                  void*    loader_ )
   {
+    T1_Face    t1face = (T1_Face)face;
+    T1_Loader  loader = (T1_Loader)loader_;
     T1_Parser  parser = &loader->parser;
     FT_Byte*   cur;
     FT_Byte*   limit  = parser->root.limit;
 
-    PSAux_Service  psaux = (PSAux_Service)face->psaux;
+    PSAux_Service  psaux = (PSAux_Service)t1face->psaux;
 
 
     T1_Skip_Spaces( parser );
@@ -1494,7 +1496,7 @@
     /* and we must load it now                               */
     if ( ft_isdigit( *cur ) || *cur == '[' )
     {
-      T1_Encoding  encode          = &face->type1.encoding;
+      T1_Encoding  encode          = &t1face->type1.encoding;
       FT_Int       count, array_size, n;
       PS_Table     char_table      = &loader->encoding_table;
       FT_Memory    memory          = parser->root.memory;
@@ -1676,7 +1678,7 @@
       FT_TRACE4(( "]\n" ));
 #endif
 
-      face->type1.encoding_type = T1_ENCODING_TYPE_ARRAY;
+      t1face->type1.encoding_type = T1_ENCODING_TYPE_ARRAY;
       parser->root.cursor       = cur;
     }
 
@@ -1687,21 +1689,21 @@
       if ( cur + 17 < limit                                            &&
            ft_strncmp( (const char*)cur, "StandardEncoding", 16 ) == 0 )
       {
-        face->type1.encoding_type = T1_ENCODING_TYPE_STANDARD;
+        t1face->type1.encoding_type = T1_ENCODING_TYPE_STANDARD;
         FT_TRACE4(( " StandardEncoding\n" ));
       }
 
       else if ( cur + 15 < limit                                          &&
                 ft_strncmp( (const char*)cur, "ExpertEncoding", 14 ) == 0 )
       {
-        face->type1.encoding_type = T1_ENCODING_TYPE_EXPERT;
+        t1face->type1.encoding_type = T1_ENCODING_TYPE_EXPERT;
         FT_TRACE4(( " ExpertEncoding\n" ));
       }
 
       else if ( cur + 18 < limit                                             &&
                 ft_strncmp( (const char*)cur, "ISOLatin1Encoding", 17 ) == 0 )
       {
-        face->type1.encoding_type = T1_ENCODING_TYPE_ISOLATIN1;
+        t1face->type1.encoding_type = T1_ENCODING_TYPE_ISOLATIN1;
         FT_TRACE4(( " ISOLatin1Encoding\n" ));
       }
 
@@ -1715,9 +1717,11 @@
 
 
   static void
-  parse_subrs( T1_Face    face,
-               T1_Loader  loader )
+  parse_subrs( FT_Face  face,     /* T1_Face */
+               void*    loader_ )
   {
+    T1_Face    t1face = (T1_Face)face;
+    T1_Loader  loader = (T1_Loader)loader_;
     T1_Parser  parser = &loader->parser;
     PS_Table   table  = &loader->subrs;
     FT_Memory  memory = parser->root.memory;
@@ -1725,7 +1729,7 @@
     FT_Int     num_subrs;
     FT_UInt    count;
 
-    PSAux_Service  psaux = (PSAux_Service)face->psaux;
+    PSAux_Service  psaux = (PSAux_Service)t1face->psaux;
 
 
     T1_Skip_Spaces( parser );
@@ -1769,7 +1773,7 @@
        */
 
       FT_TRACE0(( "parse_subrs: adjusting number of subroutines"
-                  " (from %d to %ld)\n",
+                  " (from %d to %zu)\n",
                   num_subrs,
                   ( parser->root.limit - parser->root.cursor ) >> 3 ));
       num_subrs = ( parser->root.limit - parser->root.cursor ) >> 3;
@@ -1857,7 +1861,7 @@
       /*                                                         */
       /* thanks to Tom Kacvinsky for pointing this out           */
       /*                                                         */
-      if ( face->type1.private_dict.lenIV >= 0 )
+      if ( t1face->type1.private_dict.lenIV >= 0 )
       {
         FT_Byte*  temp = NULL;
 
@@ -1865,7 +1869,7 @@
         /* some fonts define empty subr records -- this is not totally */
         /* compliant to the specification (which says they should at   */
         /* least contain a `return'), but we support them anyway       */
-        if ( size < (FT_ULong)face->type1.private_dict.lenIV )
+        if ( size < (FT_ULong)t1face->type1.private_dict.lenIV )
         {
           error = FT_THROW( Invalid_File_Format );
           goto Fail;
@@ -1876,9 +1880,11 @@
           goto Fail;
         FT_MEM_COPY( temp, base, size );
         psaux->t1_decrypt( temp, size, 4330 );
-        size -= (FT_ULong)face->type1.private_dict.lenIV;
-        error = T1_Add_Table( table, (FT_Int)idx,
-                              temp + face->type1.private_dict.lenIV, size );
+        size -= (FT_ULong)t1face->type1.private_dict.lenIV;
+        error = T1_Add_Table( table,
+                              (FT_Int)idx,
+                              temp + t1face->type1.private_dict.lenIV,
+                              size );
         FT_FREE( temp );
       }
       else
@@ -1910,9 +1916,11 @@
 
 
   static void
-  parse_charstrings( T1_Face    face,
-                     T1_Loader  loader )
+  parse_charstrings( FT_Face  face,     /* T1_Face */
+                     void*    loader_ )
   {
+    T1_Face        t1face       = (T1_Face)face;
+    T1_Loader      loader       = (T1_Loader)loader_;
     T1_Parser      parser       = &loader->parser;
     PS_Table       code_table   = &loader->charstrings;
     PS_Table       name_table   = &loader->glyph_names;
@@ -1920,7 +1928,7 @@
     FT_Memory      memory       = parser->root.memory;
     FT_Error       error;
 
-    PSAux_Service  psaux        = (PSAux_Service)face->psaux;
+    PSAux_Service  psaux        = (PSAux_Service)t1face->psaux;
 
     FT_Byte*       cur          = parser->root.cursor;
     FT_Byte*       limit        = parser->root.limit;
@@ -1940,7 +1948,7 @@
     if ( num_glyphs > ( limit - cur ) >> 3 )
     {
       FT_TRACE0(( "parse_charstrings: adjusting number of glyphs"
-                  " (from %d to %ld)\n",
+                  " (from %d to %zu)\n",
                   num_glyphs, ( limit - cur ) >> 3 ));
       num_glyphs = ( limit - cur ) >> 3;
     }
@@ -2069,13 +2077,13 @@
           notdef_found = 1;
         }
 
-        if ( face->type1.private_dict.lenIV >= 0 &&
+        if ( t1face->type1.private_dict.lenIV >= 0 &&
              n < num_glyphs + TABLE_EXTEND       )
         {
           FT_Byte*  temp = NULL;
 
 
-          if ( size <= (FT_ULong)face->type1.private_dict.lenIV )
+          if ( size <= (FT_ULong)t1face->type1.private_dict.lenIV )
           {
             error = FT_THROW( Invalid_File_Format );
             goto Fail;
@@ -2086,9 +2094,11 @@
             goto Fail;
           FT_MEM_COPY( temp, base, size );
           psaux->t1_decrypt( temp, size, 4330 );
-          size -= (FT_ULong)face->type1.private_dict.lenIV;
-          error = T1_Add_Table( code_table, n,
-                                temp + face->type1.private_dict.lenIV, size );
+          size -= (FT_ULong)t1face->type1.private_dict.lenIV;
+          error = T1_Add_Table( code_table,
+                                n,
+                                temp + t1face->type1.private_dict.lenIV,
+                                size );
           FT_FREE( temp );
         }
         else
@@ -2570,7 +2580,7 @@
     {
       FT_ERROR(( "T1_Open_Face:"
                  " number-of-designs != 2 ^^ number-of-axes\n" ));
-      T1_Done_Blend( face );
+      T1_Done_Blend( FT_FACE( face ) );
     }
 
     if ( face->blend                                                     &&
@@ -2590,15 +2600,15 @@
     /* font as a normal PS font                                     */
     if ( face->blend                                             &&
          ( !face->blend->num_designs || !face->blend->num_axis ) )
-      T1_Done_Blend( face );
+      T1_Done_Blend( FT_FACE( face ) );
 
     /* the font may have no valid WeightVector */
     if ( face->blend && !face->blend->weight_vector )
-      T1_Done_Blend( face );
+      T1_Done_Blend( FT_FACE( face ) );
 
     /* the font may have no valid BlendDesignPositions */
     if ( face->blend && !face->blend->design_pos[0] )
-      T1_Done_Blend( face );
+      T1_Done_Blend( FT_FACE( face ) );
 
     /* the font may have no valid BlendDesignMap */
     if ( face->blend )
@@ -2609,7 +2619,7 @@
       for ( i = 0; i < face->blend->num_axis; i++ )
         if ( !face->blend->design_map[i].num_points )
         {
-          T1_Done_Blend( face );
+          T1_Done_Blend( FT_FACE( face ) );
           break;
         }
     }
diff --git a/src/java.desktop/share/native/libfreetype/src/type1/t1load.h b/src/java.desktop/share/native/libfreetype/src/type1/t1load.h
index f8511cc..d8c9d2d 100644
--- a/src/java.desktop/share/native/libfreetype/src/type1/t1load.h
+++ b/src/java.desktop/share/native/libfreetype/src/type1/t1load.h
@@ -66,52 +66,52 @@
 #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
 
   FT_LOCAL( FT_Error )
-  T1_Get_Multi_Master( T1_Face           face,
+  T1_Get_Multi_Master( FT_Face           face,
                        FT_Multi_Master*  master );
 
   FT_LOCAL( FT_Error )
-  T1_Get_MM_Var( T1_Face      face,
+  T1_Get_MM_Var( FT_Face      face,
                  FT_MM_Var*  *master );
 
   FT_LOCAL( FT_Error )
-  T1_Set_MM_Blend( T1_Face    face,
+  T1_Set_MM_Blend( FT_Face    face,
                    FT_UInt    num_coords,
                    FT_Fixed*  coords );
 
   FT_LOCAL( FT_Error )
-  T1_Get_MM_Blend( T1_Face    face,
+  T1_Get_MM_Blend( FT_Face    face,
                    FT_UInt    num_coords,
                    FT_Fixed*  coords );
 
   FT_LOCAL( FT_Error )
-  T1_Set_MM_Design( T1_Face   face,
+  T1_Set_MM_Design( FT_Face   face,
                     FT_UInt   num_coords,
                     FT_Long*  coords );
 
   FT_LOCAL( FT_Error )
-  T1_Reset_MM_Blend( T1_Face  face,
+  T1_Reset_MM_Blend( FT_Face  face,
                      FT_UInt  instance_index );
 
   FT_LOCAL( FT_Error )
-  T1_Get_Var_Design( T1_Face    face,
+  T1_Get_Var_Design( FT_Face    face,
                      FT_UInt    num_coords,
                      FT_Fixed*  coords );
 
   FT_LOCAL( FT_Error )
-  T1_Set_Var_Design( T1_Face    face,
+  T1_Set_Var_Design( FT_Face    face,
                      FT_UInt    num_coords,
                      FT_Fixed*  coords );
 
   FT_LOCAL( void )
-  T1_Done_Blend( T1_Face  face );
+  T1_Done_Blend( FT_Face  face );
 
   FT_LOCAL( FT_Error )
-  T1_Set_MM_WeightVector( T1_Face    face,
+  T1_Set_MM_WeightVector( FT_Face    face,
                           FT_UInt    len,
                           FT_Fixed*  weightvector );
 
   FT_LOCAL( FT_Error )
-  T1_Get_MM_WeightVector( T1_Face    face,
+  T1_Get_MM_WeightVector( FT_Face    face,
                           FT_UInt*   len,
                           FT_Fixed*  weightvector );
 
diff --git a/src/java.desktop/share/native/libfreetype/src/type1/t1objs.c b/src/java.desktop/share/native/libfreetype/src/type1/t1objs.c
index 1bb2f15..69e4fd5 100644
--- a/src/java.desktop/share/native/libfreetype/src/type1/t1objs.c
+++ b/src/java.desktop/share/native/libfreetype/src/type1/t1objs.c
@@ -167,8 +167,7 @@
       FT_Module  module;
 
 
-      module = FT_Get_Module( slot->face->driver->root.library,
-                              "pshinter" );
+      module = FT_Get_Module( slot->library, "pshinter" );
       if ( module )
       {
         T1_Hints_Funcs  funcs;
@@ -227,7 +226,7 @@
       face->len_buildchar = 0;
     }
 
-    T1_Done_Blend( face );
+    T1_Done_Blend( t1face );
     face->blend = NULL;
 #endif
 
@@ -290,7 +289,8 @@
    *
    * @Input:
    *   stream ::
-   *     input stream where to load font data.
+   *     Dummy argument for compatibility with the `FT_Face_InitFunc` API.
+   *     Ignored.  The stream should be passed through `face->root.stream`.
    *
    *   face_index ::
    *     The index of the font face in the resource.
diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Color/CBDT/CBDT.hh b/src/java.desktop/share/native/libharfbuzz/OT/Color/CBDT/CBDT.hh
index 11aeda5..d7b2b13 100644
--- a/src/java.desktop/share/native/libharfbuzz/OT/Color/CBDT/CBDT.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/Color/CBDT/CBDT.hh
@@ -397,7 +397,6 @@
     TRACE_SERIALIZE (this);
 
     auto *subtable = c->serializer->start_embed<IndexSubtable> ();
-    if (unlikely (!subtable)) return_trace (false);
     if (unlikely (!c->serializer->extend_min (subtable))) return_trace (false);
 
     auto *old_subtable = get_subtable (base);
@@ -545,7 +544,8 @@
                 const IndexSubtableRecord*>> *lookup /* OUT */) const
   {
     bool start_glyph_is_set = false;
-    for (hb_codepoint_t new_gid = 0; new_gid < c->plan->num_output_glyphs (); new_gid++)
+    unsigned num_glyphs = c->plan->num_output_glyphs ();
+    for (hb_codepoint_t new_gid = 0; new_gid < num_glyphs; new_gid++)
     {
       hb_codepoint_t old_gid;
       if (unlikely (!c->plan->old_gid_for_new_gid (new_gid, &old_gid))) continue;
@@ -576,9 +576,6 @@
   {
     TRACE_SUBSET (this);
 
-    auto *dst = c->serializer->start_embed<IndexSubtableArray> ();
-    if (unlikely (!dst)) return_trace (false);
-
     hb_vector_t<hb_pair_t<hb_codepoint_t, const IndexSubtableRecord*>> lookup;
     build_lookup (c, bitmap_size_context, &lookup);
     if (unlikely (!c->serializer->propagate_error (lookup)))
@@ -993,12 +990,10 @@
 {
   TRACE_SUBSET (this);
 
-  auto *cblc_prime = c->serializer->start_embed<CBLC> ();
-
   // Use a vector as a secondary buffer as the tables need to be built in parallel.
   hb_vector_t<char> cbdt_prime;
 
-  if (unlikely (!cblc_prime)) return_trace (false);
+  auto *cblc_prime = c->serializer->start_embed<CBLC> ();
   if (unlikely (!c->serializer->extend_min (cblc_prime))) return_trace (false);
   cblc_prime->version = version;
 
diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Color/COLR/COLR.hh b/src/java.desktop/share/native/libharfbuzz/OT/Color/COLR/COLR.hh
index e7c34a8..fb2c42a 100644
--- a/src/java.desktop/share/native/libharfbuzz/OT/Color/COLR/COLR.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/Color/COLR/COLR.hh
@@ -53,6 +53,7 @@
 struct hb_paint_context_t :
        hb_dispatch_context_t<hb_paint_context_t>
 {
+  const char *get_name () { return "PAINT"; }
   template <typename T>
   return_t dispatch (const T &obj) { obj.paint_glyph (this); return hb_empty_t (); }
   static return_t default_return_value () { return hb_empty_t (); }
@@ -68,6 +69,8 @@
   unsigned int palette_index;
   hb_color_t foreground;
   VarStoreInstancer &instancer;
+  hb_map_t current_glyphs;
+  hb_map_t current_layers;
   int depth_left = HB_MAX_NESTING_LEVEL;
   int edge_count = HB_COLRV1_MAX_EDGE_COUNT;
 
@@ -261,6 +264,7 @@
 
   void paint_glyph (hb_paint_context_t *c) const
   {
+    TRACE_PAINT (this);
     value.paint_glyph (c, varIdxBase);
   }
 
@@ -281,7 +285,7 @@
   public:
   VarIdx varIdxBase;
   public:
-  DEFINE_SIZE_STATIC (4 + T::static_size);
+  DEFINE_SIZE_MIN (VarIdx::static_size + T::min_size);
 };
 
 template <typename T>
@@ -315,6 +319,7 @@
 
   void paint_glyph (hb_paint_context_t *c) const
   {
+    TRACE_PAINT (this);
     value.paint_glyph (c, varIdxBase);
   }
 
@@ -332,7 +337,7 @@
 
   T      value;
   public:
-  DEFINE_SIZE_STATIC (T::static_size);
+  DEFINE_SIZE_MIN (T::min_size);
 };
 
 // Color structures
@@ -409,7 +414,6 @@
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->start_embed (this);
-    if (unlikely (!out)) return_trace (false);
     if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
 
     if (!c->serializer->check_assign (out->extend, extend, HB_SERIALIZE_ERROR_INT_OVERFLOW)) return_trace (false);
@@ -559,6 +563,7 @@
 
   void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
   {
+    TRACE_PAINT (this);
     c->funcs->push_transform (c->data,
                               xx.to_float (c->instancer (varIdxBase, 0)),
                               yx.to_float (c->instancer (varIdxBase, 1)),
@@ -640,6 +645,7 @@
 
   void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
   {
+    TRACE_PAINT (this);
     hb_bool_t is_foreground;
     hb_color_t color;
 
@@ -694,6 +700,7 @@
 
   void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
   {
+    TRACE_PAINT (this);
     hb_color_line_t cl = {
       (void *) &(this+colorLine),
       (this+colorLine).static_get_color_stops, c,
@@ -760,6 +767,7 @@
 
   void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
   {
+    TRACE_PAINT (this);
     hb_color_line_t cl = {
       (void *) &(this+colorLine),
       (this+colorLine).static_get_color_stops, c,
@@ -824,6 +832,7 @@
 
   void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
   {
+    TRACE_PAINT (this);
     hb_color_line_t cl = {
       (void *) &(this+colorLine),
       (this+colorLine).static_get_color_stops, c,
@@ -875,6 +884,7 @@
 
   void paint_glyph (hb_paint_context_t *c) const
   {
+    TRACE_PAINT (this);
     c->funcs->push_inverse_root_transform (c->data, c->font);
     c->funcs->push_clip_glyph (c->data, gid, c->font);
     c->funcs->push_root_transform (c->data, c->font);
@@ -947,6 +957,7 @@
 
   void paint_glyph (hb_paint_context_t *c) const
   {
+    TRACE_PAINT (this);
     (this+transform).paint_glyph (c);
     c->recurse (this+src);
     c->funcs->pop_transform (c->data);
@@ -991,6 +1002,7 @@
 
   void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
   {
+    TRACE_PAINT (this);
     float ddx = dx + c->instancer (varIdxBase, 0);
     float ddy = dy + c->instancer (varIdxBase, 1);
 
@@ -1039,6 +1051,7 @@
 
   void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
   {
+    TRACE_PAINT (this);
     float sx = scaleX.to_float (c->instancer (varIdxBase, 0));
     float sy = scaleY.to_float (c->instancer (varIdxBase, 1));
 
@@ -1089,6 +1102,7 @@
 
   void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
   {
+    TRACE_PAINT (this);
     float sx = scaleX.to_float (c->instancer (varIdxBase, 0));
     float sy = scaleY.to_float (c->instancer (varIdxBase, 1));
     float tCenterX = centerX + c->instancer (varIdxBase, 2);
@@ -1142,6 +1156,7 @@
 
   void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
   {
+    TRACE_PAINT (this);
     float s = scale.to_float (c->instancer (varIdxBase, 0));
 
     bool p1 = c->funcs->push_scale (c->data, s, s);
@@ -1189,6 +1204,7 @@
 
   void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
   {
+    TRACE_PAINT (this);
     float s = scale.to_float (c->instancer (varIdxBase, 0));
     float tCenterX = centerX + c->instancer (varIdxBase, 1);
     float tCenterY = centerY + c->instancer (varIdxBase, 2);
@@ -1240,6 +1256,7 @@
 
   void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
   {
+    TRACE_PAINT (this);
     float a = angle.to_float (c->instancer (varIdxBase, 0));
 
     bool p1 = c->funcs->push_rotate (c->data, a);
@@ -1287,6 +1304,7 @@
 
   void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
   {
+    TRACE_PAINT (this);
     float a = angle.to_float (c->instancer (varIdxBase, 0));
     float tCenterX = centerX + c->instancer (varIdxBase, 1);
     float tCenterY = centerY + c->instancer (varIdxBase, 2);
@@ -1341,6 +1359,7 @@
 
   void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
   {
+    TRACE_PAINT (this);
     float sx = xSkewAngle.to_float(c->instancer (varIdxBase, 0));
     float sy = ySkewAngle.to_float(c->instancer (varIdxBase, 1));
 
@@ -1391,6 +1410,7 @@
 
   void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
   {
+    TRACE_PAINT (this);
     float sx = xSkewAngle.to_float(c->instancer (varIdxBase, 0));
     float sy = ySkewAngle.to_float(c->instancer (varIdxBase, 1));
     float tCenterX = centerX + c->instancer (varIdxBase, 2);
@@ -1426,20 +1446,24 @@
     auto *out = c->serializer->embed (this);
     if (unlikely (!out)) return_trace (false);
 
-    if (!out->src.serialize_subset (c, src, this, instancer)) return_trace (false);
-    return_trace (out->backdrop.serialize_subset (c, backdrop, this, instancer));
+    bool ret = false;
+    ret |= out->src.serialize_subset (c, src, this, instancer);
+    ret |= out->backdrop.serialize_subset (c, backdrop, this, instancer);
+    return_trace (ret);
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
     return_trace (c->check_struct (this) &&
+                  c->check_ops (this->min_size) && // PainComposite can get exponential
                   src.sanitize (c, this) &&
                   backdrop.sanitize (c, this));
   }
 
   void paint_glyph (hb_paint_context_t *c) const
   {
+    TRACE_PAINT (this);
     c->recurse (this+backdrop);
     c->funcs->push_group (c->data);
     c->recurse (this+src);
@@ -1514,10 +1538,10 @@
     value.get_clip_box(clip_box, instancer);
     if (instancer)
     {
-      clip_box.xMin += _hb_roundf (instancer (varIdxBase, 0));
-      clip_box.yMin += _hb_roundf (instancer (varIdxBase, 1));
-      clip_box.xMax += _hb_roundf (instancer (varIdxBase, 2));
-      clip_box.yMax += _hb_roundf (instancer (varIdxBase, 3));
+      clip_box.xMin += roundf (instancer (varIdxBase, 0));
+      clip_box.yMin += roundf (instancer (varIdxBase, 1));
+      clip_box.xMax += roundf (instancer (varIdxBase, 2));
+      clip_box.yMax += roundf (instancer (varIdxBase, 3));
     }
   }
 };
@@ -1898,15 +1922,16 @@
     auto *out = c->serializer->start_embed (this);
     if (unlikely (!c->serializer->extend_min (out)))  return_trace (false);
 
+    bool ret = false;
     for (const auto& _ : + hb_enumerate (*this)
                          | hb_filter (c->plan->colrv1_layers, hb_first))
 
     {
       auto *o = out->serialize_append (c->serializer);
-      if (unlikely (!o) || !o->serialize_subset (c, _.second, this, instancer))
-        return_trace (false);
+      if (unlikely (!o)) return_trace (false);
+      ret |= o->serialize_subset (c, _.second, this, instancer);
     }
-    return_trace (true);
+    return_trace (ret);
   }
 
   bool sanitize (hb_sanitize_context_t *c) const
@@ -2167,7 +2192,7 @@
     if (version == 0 && (!base_it || !layer_it))
       return_trace (false);
 
-    COLR *colr_prime = c->serializer->start_embed<COLR> ();
+    auto *colr_prime = c->serializer->start_embed<COLR> ();
     if (unlikely (!c->serializer->extend_min (colr_prime)))  return_trace (false);
 
     if (version == 0)
@@ -2284,6 +2309,7 @@
                                  &(this+varIdxMap),
                                  hb_array (font->coords, font->num_coords));
     hb_paint_context_t c (this, funcs, data, font, palette_index, foreground, instancer);
+    c.current_glyphs.add (glyph);
 
     if (version == 1)
     {
@@ -2399,18 +2425,42 @@
 
 void PaintColrLayers::paint_glyph (hb_paint_context_t *c) const
 {
+  TRACE_PAINT (this);
   const LayerList &paint_offset_lists = c->get_colr_table ()->get_layerList ();
   for (unsigned i = firstLayerIndex; i < firstLayerIndex + numLayers; i++)
   {
+    if (unlikely (c->current_layers.has (i)))
+      continue;
+
+    c->current_layers.add (i);
+
     const Paint &paint = paint_offset_lists.get_paint (i);
     c->funcs->push_group (c->data);
     c->recurse (paint);
     c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER);
+
+    c->current_layers.del (i);
   }
 }
 
 void PaintColrGlyph::paint_glyph (hb_paint_context_t *c) const
 {
+  TRACE_PAINT (this);
+
+  if (unlikely (c->current_glyphs.has (gid)))
+    return;
+
+  c->current_glyphs.add (gid);
+
+  c->funcs->push_inverse_root_transform (c->data, c->font);
+  if (c->funcs->color_glyph (c->data, gid, c->font))
+  {
+    c->funcs->pop_transform (c->data);
+    c->current_glyphs.del (gid);
+    return;
+  }
+  c->funcs->pop_transform (c->data);
+
   const COLR *colr_table = c->get_colr_table ();
   const Paint *paint = colr_table->get_base_glyph_paint (gid);
 
@@ -2429,6 +2479,8 @@
 
   if (has_clip_box)
     c->funcs->pop_clip (c->data);
+
+  c->current_glyphs.del (gid);
 }
 
 } /* namespace OT */
diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Color/sbix/sbix.hh b/src/java.desktop/share/native/libharfbuzz/OT/Color/sbix/sbix.hh
index 55d770e..20b06ab 100644
--- a/src/java.desktop/share/native/libharfbuzz/OT/Color/sbix/sbix.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/Color/sbix/sbix.hh
@@ -48,7 +48,6 @@
   {
     TRACE_SERIALIZE (this);
     SBIXGlyph* new_glyph = c->start_embed<SBIXGlyph> ();
-    if (unlikely (!new_glyph)) return_trace (nullptr);
     if (unlikely (!c->extend_min (new_glyph))) return_trace (nullptr);
 
     new_glyph->xOffset = xOffset;
@@ -143,7 +142,6 @@
     unsigned int num_output_glyphs = c->plan->num_output_glyphs ();
 
     auto* out = c->serializer->start_embed<SBIXStrike> ();
-    if (unlikely (!out)) return_trace (false);
     auto snap = c->serializer->snapshot ();
     if (unlikely (!c->serializer->extend (out, num_output_glyphs + 1))) return_trace (false);
     out->ppem = ppem;
@@ -388,7 +386,6 @@
     TRACE_SERIALIZE (this);
 
     auto *out = c->serializer->start_embed<Array32OfOffset32To<SBIXStrike>> ();
-    if (unlikely (!out)) return_trace (false);
     if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
 
     hb_vector_t<Offset32To<SBIXStrike>*> new_strikes;
@@ -423,8 +420,6 @@
   {
     TRACE_SUBSET (this);
 
-    sbix *sbix_prime = c->serializer->start_embed<sbix> ();
-    if (unlikely (!sbix_prime)) return_trace (false);
     if (unlikely (!c->serializer->embed (this->version))) return_trace (false);
     if (unlikely (!c->serializer->embed (this->flags))) return_trace (false);
 
diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/Coverage.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/Coverage.hh
index 016a940..257b2a3 100644
--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/Coverage.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/Coverage.hh
@@ -57,6 +57,9 @@
   public:
   DEFINE_SIZE_UNION (2, format);
 
+#ifndef HB_OPTIMIZE_SIZE
+  HB_ALWAYS_INLINE
+#endif
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
@@ -113,22 +116,33 @@
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (this))) return_trace (false);
 
-    unsigned count = 0;
+    unsigned count = hb_len (glyphs);
     unsigned num_ranges = 0;
     hb_codepoint_t last = (hb_codepoint_t) -2;
+    hb_codepoint_t max = 0;
+    bool unsorted = false;
     for (auto g: glyphs)
     {
+      if (last != (hb_codepoint_t) -2 && g < last)
+        unsorted = true;
       if (last + 1 != g)
         num_ranges++;
       last = g;
-      count++;
+      if (g > max) max = g;
     }
-    u.format = count <= num_ranges * 3 ? 1 : 2;
+    u.format = !unsorted && count <= num_ranges * 3 ? 1 : 2;
 
 #ifndef HB_NO_BEYOND_64K
-    if (count && last > 0xFFFFu)
+    if (max > 0xFFFFu)
       u.format += 2;
+    if (unlikely (max > 0xFFFFFFu))
+#else
+    if (unlikely (max > 0xFFFFu))
 #endif
+    {
+      c->check_success (false, HB_SERIALIZE_ERROR_INT_OVERFLOW);
+      return_trace (false);
+    }
 
     switch (u.format)
     {
@@ -148,8 +162,8 @@
     auto it =
     + iter ()
     | hb_take (c->plan->source->get_num_glyphs ())
-    | hb_filter (c->plan->glyph_map_gsub)
     | hb_map_retains_sorting (c->plan->glyph_map_gsub)
+    | hb_filter ([] (hb_codepoint_t glyph) { return glyph != HB_MAP_VALUE_INVALID; })
     ;
 
     // Cache the iterator result as it will be iterated multiple times
diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat1.hh
index 1fa92df..995f1eb 100644
--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat1.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat1.hh
@@ -79,7 +79,7 @@
   {
     if (glyphArray.len > glyphs->get_population () * hb_bit_storage ((unsigned) glyphArray.len) / 2)
     {
-      for (hb_codepoint_t g = HB_SET_VALUE_INVALID; glyphs->next (&g);)
+      for (auto g : *glyphs)
         if (get_coverage (g) != NOT_COVERED)
           return true;
       return false;
diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat2.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat2.hh
index 2650d19..d47c7ee 100644
--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat2.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/CoverageFormat2.hh
@@ -95,19 +95,26 @@
     unsigned count = 0;
     unsigned range = (unsigned) -1;
     last = (hb_codepoint_t) -2;
+    unsigned unsorted = false;
     for (auto g: glyphs)
     {
       if (last + 1 != g)
       {
+        if (unlikely (last != (hb_codepoint_t) -2 && last + 1 > g))
+          unsorted = true;
+
         range++;
-        rangeRecord[range].first = g;
-        rangeRecord[range].value = count;
+        rangeRecord.arrayZ[range].first = g;
+        rangeRecord.arrayZ[range].value = count;
       }
-      rangeRecord[range].last = g;
+      rangeRecord.arrayZ[range].last = g;
       last = g;
       count++;
     }
 
+    if (unlikely (unsorted))
+      rangeRecord.as_array ().qsort (RangeRecord<Types>::cmp_range);
+
     return_trace (true);
   }
 
@@ -115,7 +122,7 @@
   {
     if (rangeRecord.len > glyphs->get_population () * hb_bit_storage ((unsigned) rangeRecord.len) / 2)
     {
-      for (hb_codepoint_t g = HB_SET_VALUE_INVALID; glyphs->next (&g);)
+      for (auto g : *glyphs)
         if (get_coverage (g) != NOT_COVERED)
           return true;
       return false;
@@ -185,8 +192,8 @@
         if (__more__ ())
         {
           unsigned int old = coverage;
-          j = c->rangeRecord[i].first;
-          coverage = c->rangeRecord[i].value;
+          j = c->rangeRecord.arrayZ[i].first;
+          coverage = c->rangeRecord.arrayZ[i].value;
           if (unlikely (coverage != old + 1))
           {
             /* Broken table. Skip. Important to avoid DoS.
diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/RangeRecord.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/RangeRecord.hh
index a62629f..85aacac 100644
--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/RangeRecord.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/Common/RangeRecord.hh
@@ -51,6 +51,18 @@
   int cmp (hb_codepoint_t g) const
   { return g < first ? -1 : g <= last ? 0 : +1; }
 
+  HB_INTERNAL static int cmp_range (const void *pa, const void *pb) {
+    const RangeRecord *a = (const RangeRecord *) pa;
+    const RangeRecord *b = (const RangeRecord *) pb;
+    if (a->first < b->first) return -1;
+    if (a->first > b->first) return +1;
+    if (a->last < b->last) return -1;
+    if (a->last > b->last) return +1;
+    if (a->value < b->value) return -1;
+    if (a->value > b->value) return +1;
+    return 0;
+  }
+
   unsigned get_population () const
   {
     if (unlikely (last < first)) return 0;
diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GDEF/GDEF.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GDEF/GDEF.hh
index 0cf5753..98543f5 100644
--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GDEF/GDEF.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GDEF/GDEF.hh
@@ -29,9 +29,10 @@
 #ifndef OT_LAYOUT_GDEF_GDEF_HH
 #define OT_LAYOUT_GDEF_GDEF_HH
 
-#include "../../../hb-ot-layout-common.hh"
+#include "../../../hb-ot-var-common.hh"
 
 #include "../../../hb-font.hh"
+#include "../../../hb-cache.hh"
 
 
 namespace OT {
@@ -48,8 +49,6 @@
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->start_embed (*this);
-    if (unlikely (!out)) return_trace (false);
-
     return_trace (out->serialize (c->serializer, + iter ()));
   }
 };
@@ -201,22 +200,23 @@
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->start_embed (*this);
-    if (unlikely (!out)) return_trace (false);
     if (!c->serializer->embed (caretValueFormat)) return_trace (false);
     if (!c->serializer->embed (coordinate)) return_trace (false);
 
     unsigned varidx = (this+deviceTable).get_variation_index ();
-    if (c->plan->layout_variation_idx_delta_map.has (varidx))
+    hb_pair_t<unsigned, int> *new_varidx_delta;
+    if (!c->plan->layout_variation_idx_delta_map.has (varidx, &new_varidx_delta))
+      return_trace (false);
+
+    uint32_t new_varidx = hb_first (*new_varidx_delta);
+    int delta = hb_second (*new_varidx_delta);
+    if (delta != 0)
     {
-      int delta = hb_second (c->plan->layout_variation_idx_delta_map.get (varidx));
-      if (delta != 0)
-      {
-        if (!c->serializer->check_assign (out->coordinate, coordinate + delta, HB_SERIALIZE_ERROR_INT_OVERFLOW))
-          return_trace (false);
-      }
+      if (!c->serializer->check_assign (out->coordinate, coordinate + delta, HB_SERIALIZE_ERROR_INT_OVERFLOW))
+        return_trace (false);
     }
 
-    if (c->plan->all_axes_pinned)
+    if (new_varidx == HB_OT_LAYOUT_NO_VARIATIONS_INDEX)
       return_trace (c->serializer->check_assign (out->caretValueFormat, 1, HB_SERIALIZE_ERROR_INT_OVERFLOW));
 
     if (!c->serializer->embed (deviceTable))
@@ -441,6 +441,16 @@
   bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const
   { return (this+coverage[set_index]).get_coverage (glyph_id) != NOT_COVERED; }
 
+  template <typename set_t>
+  void collect_coverage (hb_vector_t<set_t> &sets) const
+  {
+     for (const auto &offset : coverage)
+     {
+       const auto &cov = this+offset;
+       cov.collect_coverage (sets.push ());
+     }
+  }
+
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
@@ -494,6 +504,15 @@
     }
   }
 
+  template <typename set_t>
+  void collect_coverage (hb_vector_t<set_t> &sets) const
+  {
+    switch (u.format) {
+    case 1: u.format1.collect_coverage (sets); return;
+    default:return;
+    }
+  }
+
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
@@ -585,6 +604,26 @@
                   (version.to_int () < 0x00010003u || varStore.sanitize (c, this)));
   }
 
+  static void remap_varidx_after_instantiation (const hb_map_t& varidx_map,
+                                                hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>>& layout_variation_idx_delta_map /* IN/OUT */)
+  {
+    /* varidx_map is empty which means varstore is empty after instantiation,
+     * no variations, map all varidx to HB_OT_LAYOUT_NO_VARIATIONS_INDEX.
+     * varidx_map doesn't have original varidx, indicating delta row is all
+     * zeros, map varidx to HB_OT_LAYOUT_NO_VARIATIONS_INDEX */
+    for (auto _ : layout_variation_idx_delta_map.iter_ref ())
+    {
+      /* old_varidx->(varidx, delta) mapping generated for subsetting, then this
+       * varidx is used as key of varidx_map during instantiation */
+      uint32_t varidx = _.second.first;
+      uint32_t *new_varidx;
+      if (varidx_map.has (varidx, &new_varidx))
+        _.second.first = *new_varidx;
+      else
+        _.second.first = HB_OT_LAYOUT_NO_VARIATIONS_INDEX;
+    }
+  }
+
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
@@ -607,6 +646,22 @@
     {
       if (c->plan->all_axes_pinned)
         out->varStore = 0;
+      else if (c->plan->normalized_coords)
+      {
+        if (varStore)
+        {
+          item_variations_t item_vars;
+          if (item_vars.instantiate (this+varStore, c->plan, true, true,
+                                     c->plan->gdef_varstore_inner_maps.as_array ()))
+            subset_varstore = out->varStore.serialize_serialize (c->serializer,
+                                                                 item_vars.has_long_word (),
+                                                                 c->plan->axis_tags,
+                                                                 item_vars.get_region_list (),
+                                                                 item_vars.get_vardata_encodings ());
+          remap_varidx_after_instantiation (item_vars.get_varidx_map (),
+                                            c->plan->layout_variation_idx_delta_map);
+        }
+      }
       else
         subset_varstore = out->varStore.serialize_subset (c, varStore, this, c->plan->gdef_varstore_inner_maps.as_array ());
     }
@@ -858,27 +913,79 @@
         hb_blob_destroy (table.get_blob ());
         table = hb_blob_get_empty ();
       }
+
+#ifndef HB_NO_GDEF_CACHE
+      table->get_mark_glyph_sets ().collect_coverage (mark_glyph_set_digests);
+#endif
     }
     ~accelerator_t () { table.destroy (); }
 
+    unsigned int get_glyph_props (hb_codepoint_t glyph) const
+    {
+      unsigned v;
+
+#ifndef HB_NO_GDEF_CACHE
+      if (glyph_props_cache.get (glyph, &v))
+        return v;
+#endif
+
+      v = table->get_glyph_props (glyph);
+
+#ifndef HB_NO_GDEF_CACHE
+      if (likely (table.get_blob ())) // Don't try setting if we are the null instance!
+        glyph_props_cache.set (glyph, v);
+#endif
+
+      return v;
+
+    }
+
+    bool mark_set_covers (unsigned int set_index, hb_codepoint_t glyph_id) const
+    {
+      return
+#ifndef HB_NO_GDEF_CACHE
+             mark_glyph_set_digests[set_index].may_have (glyph_id) &&
+#endif
+             table->mark_set_covers (set_index, glyph_id);
+    }
+
     hb_blob_ptr_t<GDEF> table;
+#ifndef HB_NO_GDEF_CACHE
+    hb_vector_t<hb_set_digest_t> mark_glyph_set_digests;
+    mutable hb_cache_t<21, 3, 8> glyph_props_cache;
+#endif
   };
 
   void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
   { get_lig_caret_list ().collect_variation_indices (c); }
 
   void remap_layout_variation_indices (const hb_set_t *layout_variation_indices,
+                                       const hb_vector_t<int>& normalized_coords,
+                                       bool calculate_delta, /* not pinned at default */
+                                       bool no_variations, /* all axes pinned */
                                        hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map /* OUT */) const
   {
     if (!has_var_store ()) return;
-    if (layout_variation_indices->is_empty ()) return;
+    const VariationStore &var_store = get_var_store ();
+    float *store_cache = var_store.create_cache ();
 
     unsigned new_major = 0, new_minor = 0;
     unsigned last_major = (layout_variation_indices->get_min ()) >> 16;
     for (unsigned idx : layout_variation_indices->iter ())
     {
+      int delta = 0;
+      if (calculate_delta)
+        delta = roundf (var_store.get_delta (idx, normalized_coords.arrayZ,
+                                             normalized_coords.length, store_cache));
+
+      if (no_variations)
+      {
+        layout_variation_idx_delta_map->set (idx, hb_pair_t<unsigned, int> (HB_OT_LAYOUT_NO_VARIATIONS_INDEX, delta));
+        continue;
+      }
+
       uint16_t major = idx >> 16;
-      if (major >= get_var_store ().get_sub_table_count ()) break;
+      if (major >= var_store.get_sub_table_count ()) break;
       if (major != last_major)
       {
         new_minor = 0;
@@ -886,14 +993,11 @@
       }
 
       unsigned new_idx = (new_major << 16) + new_minor;
-      if (!layout_variation_idx_delta_map->has (idx))
-        continue;
-      int delta = hb_second (layout_variation_idx_delta_map->get (idx));
-
       layout_variation_idx_delta_map->set (idx, hb_pair_t<unsigned, int> (new_idx, delta));
       ++new_minor;
       last_major = major;
     }
+    var_store.destroy_cache (store_cache);
   }
 
   protected:
diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorFormat3.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorFormat3.hh
index e7e3c5c..23821a4 100644
--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorFormat3.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorFormat3.hh
@@ -25,7 +25,9 @@
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) && xDeviceTable.sanitize (c, this) && yDeviceTable.sanitize (c, this));
+    if (unlikely (!c->check_struct (this))) return_trace (false);
+
+    return_trace (xDeviceTable.sanitize (c, this) && yDeviceTable.sanitize (c, this));
   }
 
   void get_anchor (hb_ot_apply_context_t *c, hb_codepoint_t glyph_id HB_UNUSED,
@@ -35,9 +37,9 @@
     *x = font->em_fscale_x (xCoordinate);
     *y = font->em_fscale_y (yCoordinate);
 
-    if (font->x_ppem || font->num_coords)
+    if ((font->x_ppem || font->num_coords) && xDeviceTable.sanitize (&c->sanitizer, this))
       *x += (this+xDeviceTable).get_x_delta (font, c->var_store, c->var_store_cache);
-    if (font->y_ppem || font->num_coords)
+    if ((font->y_ppem || font->num_coords) && yDeviceTable.sanitize (&c->sanitizer, this))
       *y += (this+yDeviceTable).get_y_delta (font, c->var_store, c->var_store_cache);
   }
 
@@ -45,15 +47,19 @@
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->start_embed (*this);
-    if (unlikely (!out)) return_trace (false);
     if (unlikely (!c->serializer->embed (format))) return_trace (false);
     if (unlikely (!c->serializer->embed (xCoordinate))) return_trace (false);
     if (unlikely (!c->serializer->embed (yCoordinate))) return_trace (false);
 
     unsigned x_varidx = xDeviceTable ? (this+xDeviceTable).get_variation_index () : HB_OT_LAYOUT_NO_VARIATIONS_INDEX;
-    if (c->plan->layout_variation_idx_delta_map.has (x_varidx))
+    if (x_varidx != HB_OT_LAYOUT_NO_VARIATIONS_INDEX)
     {
-      int delta = hb_second (c->plan->layout_variation_idx_delta_map.get (x_varidx));
+      hb_pair_t<unsigned, int> *new_varidx_delta;
+      if (!c->plan->layout_variation_idx_delta_map.has (x_varidx, &new_varidx_delta))
+        return_trace (false);
+
+      x_varidx = hb_first (*new_varidx_delta);
+      int delta = hb_second (*new_varidx_delta);
       if (delta != 0)
       {
         if (!c->serializer->check_assign (out->xCoordinate, xCoordinate + delta,
@@ -63,9 +69,14 @@
     }
 
     unsigned y_varidx = yDeviceTable ? (this+yDeviceTable).get_variation_index () : HB_OT_LAYOUT_NO_VARIATIONS_INDEX;
-    if (c->plan->layout_variation_idx_delta_map.has (y_varidx))
+    if (y_varidx != HB_OT_LAYOUT_NO_VARIATIONS_INDEX)
     {
-      int delta = hb_second (c->plan->layout_variation_idx_delta_map.get (y_varidx));
+      hb_pair_t<unsigned, int> *new_varidx_delta;
+      if (!c->plan->layout_variation_idx_delta_map.has (y_varidx, &new_varidx_delta))
+        return_trace (false);
+
+      y_varidx = hb_first (*new_varidx_delta);
+      int delta = hb_second (*new_varidx_delta);
       if (delta != 0)
       {
         if (!c->serializer->check_assign (out->yCoordinate, yCoordinate + delta,
@@ -74,7 +85,10 @@
       }
     }
 
-    if (c->plan->all_axes_pinned)
+    /* in case that all axes are pinned or no variations after instantiation,
+     * both var_idxes will be mapped to HB_OT_LAYOUT_NO_VARIATIONS_INDEX */
+    if (x_varidx == HB_OT_LAYOUT_NO_VARIATIONS_INDEX &&
+        y_varidx == HB_OT_LAYOUT_NO_VARIATIONS_INDEX)
       return_trace (c->serializer->check_assign (out->format, 1, HB_SERIALIZE_ERROR_INT_OVERFLOW));
 
     if (!c->serializer->embed (xDeviceTable)) return_trace (false);
diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorMatrix.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorMatrix.hh
index c442efa..b61f141 100644
--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorMatrix.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/AnchorMatrix.hh
@@ -21,18 +21,25 @@
     if (unlikely (hb_unsigned_mul_overflows (rows, cols))) return_trace (false);
     unsigned int count = rows * cols;
     if (!c->check_array (matrixZ.arrayZ, count)) return_trace (false);
+
+    if (c->lazy_some_gpos)
+      return_trace (true);
+
     for (unsigned int i = 0; i < count; i++)
       if (!matrixZ[i].sanitize (c, this)) return_trace (false);
     return_trace (true);
   }
 
-  const Anchor& get_anchor (unsigned int row, unsigned int col,
+  const Anchor& get_anchor (hb_ot_apply_context_t *c,
+                            unsigned int row, unsigned int col,
                             unsigned int cols, bool *found) const
   {
     *found = false;
     if (unlikely (row >= rows || col >= cols)) return Null (Anchor);
-    *found = !matrixZ[row * cols + col].is_null ();
-    return this+matrixZ[row * cols + col];
+    auto &offset = matrixZ[row * cols + col];
+    if (unlikely (!offset.sanitize (&c->sanitizer, this))) return Null (Anchor);
+    *found = !offset.is_null ();
+    return this+offset;
   }
 
   template <typename Iterator,
@@ -58,14 +65,15 @@
     if (unlikely (!c->serializer->extend_min (out)))  return_trace (false);
 
     out->rows = num_rows;
+    bool ret = false;
     for (const unsigned i : index_iter)
     {
       auto *offset = c->serializer->embed (matrixZ[i]);
       if (!offset) return_trace (false);
-      offset->serialize_subset (c, matrixZ[i], this);
+      ret |= offset->serialize_subset (c, matrixZ[i], this);
     }
 
-    return_trace (true);
+    return_trace (ret);
   }
 };
 
diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/CursivePosFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/CursivePosFormat1.hh
index 13a435d..3a2957a 100644
--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/CursivePosFormat1.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/CursivePosFormat1.hh
@@ -24,16 +24,17 @@
     (src_base+exitAnchor).collect_variation_indices (c);
   }
 
-  EntryExitRecord* subset (hb_subset_context_t *c,
-                           const void *src_base) const
+  bool subset (hb_subset_context_t *c,
+               const void *src_base) const
   {
     TRACE_SERIALIZE (this);
     auto *out = c->serializer->embed (this);
-    if (unlikely (!out)) return_trace (nullptr);
+    if (unlikely (!out)) return_trace (false);
 
-    out->entryAnchor.serialize_subset (c, entryAnchor, src_base);
-    out->exitAnchor.serialize_subset (c, exitAnchor, src_base);
-    return_trace (out);
+    bool ret = false;
+    ret |= out->entryAnchor.serialize_subset (c, entryAnchor, src_base);
+    ret |= out->exitAnchor.serialize_subset (c, exitAnchor, src_base);
+    return_trace (ret);
   }
 
   protected:
@@ -91,7 +92,13 @@
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (coverage.sanitize (c, this) && entryExitRecord.sanitize (c, this));
+    if (unlikely (!coverage.sanitize (c, this)))
+      return_trace (false);
+
+    if (c->lazy_some_gpos)
+      return_trace (entryExitRecord.sanitize_shallow (c));
+    else
+      return_trace (entryExitRecord.sanitize (c, this));
   }
 
   bool intersects (const hb_set_t *glyphs) const
@@ -119,19 +126,21 @@
     hb_buffer_t *buffer = c->buffer;
 
     const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_coverage  (buffer->cur().codepoint)];
-    if (!this_record.entryAnchor) return_trace (false);
+    if (!this_record.entryAnchor ||
+        unlikely (!this_record.entryAnchor.sanitize (&c->sanitizer, this))) return_trace (false);
 
     hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
-    skippy_iter.reset (buffer->idx, 1);
+    skippy_iter.reset_fast (buffer->idx);
     unsigned unsafe_from;
-    if (!skippy_iter.prev (&unsafe_from))
+    if (unlikely (!skippy_iter.prev (&unsafe_from)))
     {
       buffer->unsafe_to_concat_from_outbuffer (unsafe_from, buffer->idx + 1);
       return_trace (false);
     }
 
     const EntryExitRecord &prev_record = entryExitRecord[(this+coverage).get_coverage  (buffer->info[skippy_iter.idx].codepoint)];
-    if (!prev_record.exitAnchor)
+    if (!prev_record.exitAnchor ||
+        unlikely (!prev_record.exitAnchor.sanitize (&c->sanitizer, this)))
     {
       buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
       return_trace (false);
@@ -200,8 +209,8 @@
      * Arabic. */
     unsigned int child  = i;
     unsigned int parent = j;
-    hb_position_t x_offset = entry_x - exit_x;
-    hb_position_t y_offset = entry_y - exit_y;
+    hb_position_t x_offset = roundf (entry_x - exit_x);
+    hb_position_t y_offset = roundf (entry_y - exit_y);
     if  (!(c->lookup_props & LookupFlag::RightToLeft))
     {
       unsigned int k = child;
@@ -278,7 +287,6 @@
     const hb_map_t &glyph_map = *c->plan->glyph_map;
 
     auto *out = c->serializer->start_embed (*this);
-    if (unlikely (!out)) return_trace (false);
 
     auto it =
     + hb_zip (this+coverage, entryExitRecord)
diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/GPOS.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/GPOS.hh
index 9493ec9..f4af98b 100644
--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/GPOS.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/GPOS.hh
@@ -156,7 +156,7 @@
   {
     for (unsigned i = 0; i < len; i++)
       if (unlikely (pos[i].y_offset))
-        pos[i].x_offset += _hb_roundf (font->slant_xy * pos[i].y_offset);
+        pos[i].x_offset += roundf (font->slant_xy * pos[i].y_offset);
   }
 }
 
diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/LigatureArray.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/LigatureArray.hh
index a2d807c..eecdb95 100644
--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/LigatureArray.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/LigatureArray.hh
@@ -27,6 +27,7 @@
     auto *out = c->serializer->start_embed (this);
     if (unlikely (!c->serializer->extend_min (out)))  return_trace (false);
 
+    bool ret = false;
     for (const auto _ : + hb_zip (coverage, *this)
                   | hb_filter (glyphset, hb_first))
     {
@@ -38,13 +39,13 @@
           + hb_range (src.rows * class_count)
           | hb_filter ([=] (unsigned index) { return klass_mapping->has (index % class_count); })
           ;
-      matrix->serialize_subset (c,
-                                _.second,
-                                this,
-                                src.rows,
-                                indexes);
+      ret |= matrix->serialize_subset (c,
+                                       _.second,
+                                       this,
+                                       src.rows,
+                                       indexes);
     }
-    return_trace (this->len);
+    return_trace (ret);
   }
 };
 
diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkArray.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkArray.hh
index e80c05c..abae8f1 100644
--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkArray.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkArray.hh
@@ -28,7 +28,7 @@
 
     const Anchor& mark_anchor = this + record.markAnchor;
     bool found;
-    const Anchor& glyph_anchor = anchors.get_anchor (glyph_index, mark_class, class_count, &found);
+    const Anchor& glyph_anchor = anchors.get_anchor (c, glyph_index, mark_class, class_count, &found);
     /* If this subtable doesn't have an anchor for this base and this class,
      * return false such that the subsequent subtables have a chance at it. */
     if (unlikely (!found)) return_trace (false);
@@ -82,10 +82,10 @@
     | hb_map (hb_second)
     ;
 
+    bool ret = false;
     unsigned new_length = 0;
     for (const auto& mark_record : mark_iter) {
-      if (unlikely (!mark_record.subset (c, this, klass_mapping)))
-        return_trace (false);
+      ret |= mark_record.subset (c, this, klass_mapping);
       new_length++;
     }
 
@@ -93,7 +93,7 @@
                                                 HB_SERIALIZE_ERROR_ARRAY_OVERFLOW)))
       return_trace (false);
 
-    return_trace (true);
+    return_trace (ret);
   }
 };
 
diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkBasePosFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkBasePosFormat1.hh
index bf129a4..e633f7a 100644
--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkBasePosFormat1.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkBasePosFormat1.hh
@@ -197,9 +197,10 @@
     if (!out->markCoverage.serialize_serialize (c->serializer, new_coverage.iter ()))
       return_trace (false);
 
-    out->markArray.serialize_subset (c, markArray, this,
-                                     (this+markCoverage).iter (),
-                                     &klass_mapping);
+    if (unlikely (!out->markArray.serialize_subset (c, markArray, this,
+                                                    (this+markCoverage).iter (),
+                                                    &klass_mapping)))
+      return_trace (false);
 
     unsigned basecount = (this+baseArray).rows;
     auto base_iter =
@@ -228,11 +229,9 @@
       ;
     }
 
-    out->baseArray.serialize_subset (c, baseArray, this,
-                                     base_iter.len (),
-                                     base_indexes.iter ());
-
-    return_trace (true);
+    return_trace (out->baseArray.serialize_subset (c, baseArray, this,
+                                                   base_iter.len (),
+                                                   base_indexes.iter ()));
   }
 };
 
diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkLigPosFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkLigPosFormat1.hh
index 30bba4b..cf4cbae 100644
--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkLigPosFormat1.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkLigPosFormat1.hh
@@ -169,7 +169,7 @@
   {
     TRACE_SUBSET (this);
     const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
-    const hb_map_t &glyph_map = *c->plan->glyph_map;
+    const hb_map_t &glyph_map = c->plan->glyph_map_gsub;
 
     auto *out = c->serializer->start_embed (*this);
     if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
@@ -195,23 +195,24 @@
     if (!out->markCoverage.serialize_serialize (c->serializer, new_mark_coverage))
       return_trace (false);
 
-    out->markArray.serialize_subset (c, markArray, this,
-                                     (this+markCoverage).iter (),
-                                     &klass_mapping);
+    if (unlikely (!out->markArray.serialize_subset (c, markArray, this,
+                                                    (this+markCoverage).iter (),
+                                                    &klass_mapping)))
+      return_trace (false);
 
     auto new_ligature_coverage =
     + hb_iter (this + ligatureCoverage)
-    | hb_filter (glyphset)
+    | hb_take ((this + ligatureArray).len)
     | hb_map_retains_sorting (glyph_map)
+    | hb_filter ([] (hb_codepoint_t glyph) { return glyph != HB_MAP_VALUE_INVALID; })
     ;
 
     if (!out->ligatureCoverage.serialize_serialize (c->serializer, new_ligature_coverage))
       return_trace (false);
 
-    out->ligatureArray.serialize_subset (c, ligatureArray, this,
-                                         hb_iter (this+ligatureCoverage), classCount, &klass_mapping);
-
-    return_trace (true);
+    return_trace (out->ligatureArray.serialize_subset (c, ligatureArray, this,
+                                                       hb_iter (this+ligatureCoverage),
+                                                       classCount, &klass_mapping));
   }
 
 };
diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkMarkPosFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkMarkPosFormat1.hh
index fbcebb8..ea19658 100644
--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkMarkPosFormat1.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkMarkPosFormat1.hh
@@ -100,16 +100,16 @@
 
     /* now we search backwards for a suitable mark glyph until a non-mark glyph */
     hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
-    skippy_iter.reset (buffer->idx, 1);
+    skippy_iter.reset_fast (buffer->idx);
     skippy_iter.set_lookup_props (c->lookup_props & ~(uint32_t)LookupFlag::IgnoreFlags);
     unsigned unsafe_from;
-    if (!skippy_iter.prev (&unsafe_from))
+    if (unlikely (!skippy_iter.prev (&unsafe_from)))
     {
       buffer->unsafe_to_concat_from_outbuffer (unsafe_from, buffer->idx + 1);
       return_trace (false);
     }
 
-    if (!_hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx]))
+    if (likely (!_hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx])))
     {
       buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
       return_trace (false);
@@ -183,9 +183,10 @@
     if (!out->mark1Coverage.serialize_serialize (c->serializer, new_coverage.iter ()))
       return_trace (false);
 
-    out->mark1Array.serialize_subset (c, mark1Array, this,
-                                      (this+mark1Coverage).iter (),
-                                      &klass_mapping);
+    if (unlikely (!out->mark1Array.serialize_subset (c, mark1Array, this,
+                                                     (this+mark1Coverage).iter (),
+                                                     &klass_mapping)))
+      return_trace (false);
 
     unsigned mark2count = (this+mark2Array).rows;
     auto mark2_iter =
@@ -214,9 +215,10 @@
       ;
     }
 
-    out->mark2Array.serialize_subset (c, mark2Array, this, mark2_iter.len (), mark2_indexes.iter ());
+    return_trace (out->mark2Array.serialize_subset (c, mark2Array, this,
+                                                    mark2_iter.len (),
+                                                    mark2_indexes.iter ()));
 
-    return_trace (true);
   }
 };
 
diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkRecord.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkRecord.hh
index a7d489d..1230025 100644
--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkRecord.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/MarkRecord.hh
@@ -24,17 +24,16 @@
     return_trace (c->check_struct (this) && markAnchor.sanitize (c, base));
   }
 
-  MarkRecord *subset (hb_subset_context_t    *c,
-                      const void             *src_base,
-                      const hb_map_t         *klass_mapping) const
+  bool subset (hb_subset_context_t    *c,
+               const void             *src_base,
+               const hb_map_t         *klass_mapping) const
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->embed (this);
-    if (unlikely (!out)) return_trace (nullptr);
+    if (unlikely (!out)) return_trace (false);
 
     out->klass = klass_mapping->get (klass);
-    out->markAnchor.serialize_subset (c, markAnchor, src_base);
-    return_trace (out);
+    return_trace (out->markAnchor.serialize_subset (c, markAnchor, src_base));
   }
 
   void collect_variation_indices (hb_collect_variation_indices_context_t *c,
diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat1.hh
index 468eccf..478c72d 100644
--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat1.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat1.hh
@@ -110,9 +110,9 @@
     if (likely (index == NOT_COVERED)) return_trace (false);
 
     hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
-    skippy_iter.reset (buffer->idx, 1);
+    skippy_iter.reset_fast (buffer->idx);
     unsigned unsafe_to;
-    if (!skippy_iter.next (&unsafe_to))
+    if (unlikely (!skippy_iter.next (&unsafe_to)))
     {
       buffer->unsafe_to_concat (buffer->idx, unsafe_to);
       return_trace (false);
diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat2.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat2.hh
index 17486dd..ce6eec4 100644
--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat2.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairPosFormat2.hh
@@ -50,13 +50,13 @@
     unsigned int len1 = valueFormat1.get_len ();
     unsigned int len2 = valueFormat2.get_len ();
     unsigned int stride = HBUINT16::static_size * (len1 + len2);
-    unsigned int record_size = valueFormat1.get_size () + valueFormat2.get_size ();
     unsigned int count = (unsigned int) class1Count * (unsigned int) class2Count;
     return_trace (c->check_range ((const void *) values,
                                   count,
-                                  record_size) &&
-                  valueFormat1.sanitize_values_stride_unsafe (c, this, &values[0], count, stride) &&
-                  valueFormat2.sanitize_values_stride_unsafe (c, this, &values[len1], count, stride));
+                                  stride) &&
+                  (c->lazy_some_gpos ||
+                   (valueFormat1.sanitize_values_stride_unsafe (c, this, &values[0], count, stride) &&
+                    valueFormat2.sanitize_values_stride_unsafe (c, this, &values[len1], count, stride))));
   }
 
   bool intersects (const hb_set_t *glyphs) const
@@ -131,40 +131,46 @@
     if (likely (index == NOT_COVERED)) return_trace (false);
 
     hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
-    skippy_iter.reset (buffer->idx, 1);
+    skippy_iter.reset_fast (buffer->idx);
     unsigned unsafe_to;
-    if (!skippy_iter.next (&unsafe_to))
+    if (unlikely (!skippy_iter.next (&unsafe_to)))
     {
       buffer->unsafe_to_concat (buffer->idx, unsafe_to);
       return_trace (false);
     }
 
+    unsigned int klass2 = (this+classDef2).get_class (buffer->info[skippy_iter.idx].codepoint);
+    if (!klass2)
+    {
+      buffer->unsafe_to_concat (buffer->idx, skippy_iter.idx + 1);
+      return_trace (false);
+    }
+
+    unsigned int klass1 = (this+classDef1).get_class (buffer->cur().codepoint);
+    if (unlikely (klass1 >= class1Count || klass2 >= class2Count))
+    {
+      buffer->unsafe_to_concat (buffer->idx, skippy_iter.idx + 1);
+      return_trace (false);
+    }
+
     unsigned int len1 = valueFormat1.get_len ();
     unsigned int len2 = valueFormat2.get_len ();
     unsigned int record_len = len1 + len2;
 
-    unsigned int klass1 = (this+classDef1).get_class (buffer->cur().codepoint);
-    unsigned int klass2 = (this+classDef2).get_class (buffer->info[skippy_iter.idx].codepoint);
-    if (unlikely (klass1 >= class1Count || klass2 >= class2Count))
-    {
-      buffer->unsafe_to_concat (buffer->idx, skippy_iter.idx + 1);
-      return_trace (false);
-    }
-
     const Value *v = &values[record_len * (klass1 * class2Count + klass2)];
 
     bool applied_first = false, applied_second = false;
 
 
     /* Isolate simple kerning and apply it half to each side.
-     * Results in better cursor positinoing / underline drawing.
+     * Results in better cursor positioning / underline drawing.
      *
      * Disabled, because causes issues... :-(
      * https://github.com/harfbuzz/harfbuzz/issues/3408
      * https://github.com/harfbuzz/harfbuzz/pull/3235#issuecomment-1029814978
      */
 #ifndef HB_SPLIT_KERN
-    if (0)
+    if (false)
 #endif
     {
       if (!len2)
@@ -224,8 +230,8 @@
                           c->buffer->idx, skippy_iter.idx);
     }
 
-    applied_first = valueFormat1.apply_value (c, this, v, buffer->cur_pos());
-    applied_second = valueFormat2.apply_value (c, this, v + len1, buffer->pos[skippy_iter.idx]);
+    applied_first = len1 && valueFormat1.apply_value (c, this, v, buffer->cur_pos());
+    applied_second = len2 && valueFormat2.apply_value (c, this, v + len1, buffer->pos[skippy_iter.idx]);
 
     if (applied_first || applied_second)
       if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
@@ -293,11 +299,13 @@
       out->valueFormat2 = out->valueFormat2.drop_device_table_flags ();
     }
 
+    unsigned total_len = len1 + len2;
+    hb_vector_t<unsigned> class2_idxs (+ hb_range ((unsigned) class2Count) | hb_filter (klass2_map));
     for (unsigned class1_idx : + hb_range ((unsigned) class1Count) | hb_filter (klass1_map))
     {
-      for (unsigned class2_idx : + hb_range ((unsigned) class2Count) | hb_filter (klass2_map))
+      for (unsigned class2_idx : class2_idxs)
       {
-        unsigned idx = (class1_idx * (unsigned) class2Count + class2_idx) * (len1 + len2);
+        unsigned idx = (class1_idx * (unsigned) class2Count + class2_idx) * total_len;
         valueFormat1.copy_values (c->serializer, out->valueFormat1, this, &values[idx], &c->plan->layout_variation_idx_delta_map);
         valueFormat2.copy_values (c->serializer, out->valueFormat2, this, &values[idx + len1], &c->plan->layout_variation_idx_delta_map);
       }
diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairSet.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairSet.hh
index adeb08e..7ccec1d 100644
--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairSet.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairSet.hh
@@ -52,8 +52,9 @@
 
     unsigned int count = len;
     const PairValueRecord *record = &firstPairValueRecord;
-    return_trace (closure->valueFormats[0].sanitize_values_stride_unsafe (c, this, &record->values[0], count, closure->stride) &&
-                  closure->valueFormats[1].sanitize_values_stride_unsafe (c, this, &record->values[closure->len1], count, closure->stride));
+    return_trace (c->lazy_some_gpos ||
+                  (closure->valueFormats[0].sanitize_values_stride_unsafe (c, this, &record->values[0], count, closure->stride) &&
+                   closure->valueFormats[1].sanitize_values_stride_unsafe (c, this, &record->values[closure->len1], count, closure->stride)));
   }
 
   bool intersects (const hb_set_t *glyphs,
@@ -120,8 +121,8 @@
                             c->buffer->idx, pos);
       }
 
-      bool applied_first = valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_pos());
-      bool applied_second = valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos[pos]);
+      bool applied_first = len1 && valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_pos());
+      bool applied_second = len2 && valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos[pos]);
 
       if (applied_first || applied_second)
         if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairValueRecord.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairValueRecord.hh
index d4f549a..b32abe4 100644
--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairValueRecord.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/PairValueRecord.hh
@@ -22,7 +22,7 @@
   ValueRecord   values;                 /* Positioning data for the first glyph
                                          * followed by for second glyph */
   public:
-  DEFINE_SIZE_ARRAY (Types::size, values);
+  DEFINE_SIZE_ARRAY (Types::HBGlyphID::static_size, values);
 
   int cmp (hb_codepoint_t k) const
   { return secondGlyph.cmp (k); }
diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePosFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePosFormat1.hh
index 47391c7..8e21c5f 100644
--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePosFormat1.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePosFormat1.hh
@@ -90,6 +90,7 @@
 
   bool
   position_single (hb_font_t           *font,
+                   hb_blob_t           *table_blob,
                    hb_direction_t       direction,
                    hb_codepoint_t       gid,
                    hb_glyph_position_t &pos) const
@@ -100,7 +101,7 @@
     /* This is ugly... */
     hb_buffer_t buffer;
     buffer.props.direction = direction;
-    OT::hb_ot_apply_context_t c (1, font, &buffer);
+    OT::hb_ot_apply_context_t c (1, font, &buffer, table_blob);
 
     valueFormat.apply_value (&c, this, values, pos);
     return true;
diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePosFormat2.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePosFormat2.hh
index 6546eb1..ddc4c18 100644
--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePosFormat2.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/SinglePosFormat2.hh
@@ -94,6 +94,7 @@
 
   bool
   position_single (hb_font_t           *font,
+                   hb_blob_t           *table_blob,
                    hb_direction_t       direction,
                    hb_codepoint_t       gid,
                    hb_glyph_position_t &pos) const
@@ -105,7 +106,7 @@
     /* This is ugly... */
     hb_buffer_t buffer;
     buffer.props.direction = direction;
-    OT::hb_ot_apply_context_t c (1, font, &buffer);
+    OT::hb_ot_apply_context_t c (1, font, &buffer, table_blob);
 
     valueFormat.apply_value (&c, this,
                              &values[index * valueFormat.get_len ()],
diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/ValueFormat.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/ValueFormat.hh
index 1aa451a..8618cdd 100644
--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/ValueFormat.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GPOS/ValueFormat.hh
@@ -118,21 +118,25 @@
     auto *cache = c->var_store_cache;
 
     /* pixel -> fractional pixel */
-    if (format & xPlaDevice) {
-      if (use_x_device) glyph_pos.x_offset  += (base + get_device (values, &ret)).get_x_delta (font, store, cache);
+    if (format & xPlaDevice)
+    {
+      if (use_x_device) glyph_pos.x_offset  += get_device (values, &ret, base, c->sanitizer).get_x_delta (font, store, cache);
       values++;
     }
-    if (format & yPlaDevice) {
-      if (use_y_device) glyph_pos.y_offset  += (base + get_device (values, &ret)).get_y_delta (font, store, cache);
+    if (format & yPlaDevice)
+    {
+      if (use_y_device) glyph_pos.y_offset  += get_device (values, &ret, base, c->sanitizer).get_y_delta (font, store, cache);
       values++;
     }
-    if (format & xAdvDevice) {
-      if (horizontal && use_x_device) glyph_pos.x_advance += (base + get_device (values, &ret)).get_x_delta (font, store, cache);
+    if (format & xAdvDevice)
+    {
+      if (horizontal && use_x_device) glyph_pos.x_advance += get_device (values, &ret, base, c->sanitizer).get_x_delta (font, store, cache);
       values++;
     }
-    if (format & yAdvDevice) {
+    if (format & yAdvDevice)
+    {
       /* y_advance values grow downward but font-space grows upward, hence negation */
-      if (!horizontal && use_y_device) glyph_pos.y_advance -= (base + get_device (values, &ret)).get_y_delta (font, store, cache);
+      if (!horizontal && use_y_device) glyph_pos.y_advance -= get_device (values, &ret, base, c->sanitizer).get_y_delta (font, store, cache);
       values++;
     }
     return ret;
@@ -174,6 +178,9 @@
     if (format & xAdvance)   x_adv = copy_value (c, new_format, xAdvance, *values++);
     if (format & yAdvance)   y_adv = copy_value (c, new_format, yAdvance, *values++);
 
+    if (!has_device ())
+      return;
+
     if (format & xPlaDevice)
     {
       add_delta_to_value (x_placement, base, values, layout_variation_idx_delta_map);
@@ -233,14 +240,12 @@
 
     if (format & ValueFormat::xAdvDevice)
     {
-
       (base + get_device (&(values[i]))).collect_variation_indices (c);
       i++;
     }
 
     if (format & ValueFormat::yAdvDevice)
     {
-
       (base + get_device (&(values[i]))).collect_variation_indices (c);
       i++;
     }
@@ -277,10 +282,22 @@
   {
     return *static_cast<Offset16To<Device> *> (value);
   }
-  static inline const Offset16To<Device>& get_device (const Value* value, bool *worked=nullptr)
+  static inline const Offset16To<Device>& get_device (const Value* value)
+  {
+    return *static_cast<const Offset16To<Device> *> (value);
+  }
+  static inline const Device& get_device (const Value* value,
+                                          bool *worked,
+                                          const void *base,
+                                          hb_sanitize_context_t &c)
   {
     if (worked) *worked |= bool (*value);
-    return *static_cast<const Offset16To<Device> *> (value);
+    auto &offset = *static_cast<const Offset16To<Device> *> (value);
+
+    if (unlikely (!offset.sanitize (&c, base)))
+      return Null(Device);
+
+    return base + offset;
   }
 
   void add_delta_to_value (HBINT16 *value,
@@ -340,25 +357,26 @@
   bool sanitize_value (hb_sanitize_context_t *c, const void *base, const Value *values) const
   {
     TRACE_SANITIZE (this);
-    return_trace (c->check_range (values, get_size ()) && (!has_device () || sanitize_value_devices (c, base, values)));
+
+    if (unlikely (!c->check_range (values, get_size ()))) return_trace (false);
+
+    if (c->lazy_some_gpos)
+      return_trace (true);
+
+    return_trace (!has_device () || sanitize_value_devices (c, base, values));
   }
 
   bool sanitize_values (hb_sanitize_context_t *c, const void *base, const Value *values, unsigned int count) const
   {
     TRACE_SANITIZE (this);
-    unsigned int len = get_len ();
+    unsigned size = get_size ();
 
-    if (!c->check_range (values, count, get_size ())) return_trace (false);
+    if (!c->check_range (values, count, size)) return_trace (false);
 
-    if (!has_device ()) return_trace (true);
+    if (c->lazy_some_gpos)
+      return_trace (true);
 
-    for (unsigned int i = 0; i < count; i++) {
-      if (!sanitize_value_devices (c, base, values))
-        return_trace (false);
-      values += len;
-    }
-
-    return_trace (true);
+    return_trace (sanitize_values_stride_unsafe (c, base, values, count, size));
   }
 
   /* Just sanitize referenced Device tables.  Doesn't check the values themselves. */
diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Common.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Common.hh
index 968bba0..b849494 100644
--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Common.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Common.hh
@@ -8,8 +8,6 @@
 namespace Layout {
 namespace GSUB_impl {
 
-typedef hb_pair_t<hb_codepoint_t, hb_codepoint_t> hb_codepoint_pair_t;
-
 template<typename Iterator>
 static void SingleSubst_serialize (hb_serialize_context_t *c,
                                    Iterator it);
diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Ligature.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Ligature.hh
index 308da58..de4a111 100644
--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Ligature.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Ligature.hh
@@ -10,10 +10,10 @@
 template <typename Types>
 struct Ligature
 {
-  protected:
+  public:
   typename Types::HBGlyphID
                 ligGlyph;               /* GlyphID of ligature to substitute */
-  HeadlessArrayOf<typename Types::HBGlyphID>
+  HeadlessArray16Of<typename Types::HBGlyphID>
                 component;              /* Array of component GlyphIDs--start
                                          * with the second  component--ordered
                                          * in writing direction */
diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSet.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSet.hh
index 2b23262..ff0ffce 100644
--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSet.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/LigatureSet.hh
@@ -75,12 +75,69 @@
   bool apply (hb_ot_apply_context_t *c) const
   {
     TRACE_APPLY (this);
+
     unsigned int num_ligs = ligature.len;
+
+#ifndef HB_NO_OT_RULESETS_FAST_PATH
+    if (HB_OPTIMIZE_SIZE_VAL || num_ligs <= 4)
+#endif
+    {
+    slow:
+      for (unsigned int i = 0; i < num_ligs; i++)
+      {
+        const auto &lig = this+ligature.arrayZ[i];
+        if (lig.apply (c)) return_trace (true);
+      }
+      return_trace (false);
+    }
+
+    /* This version is optimized for speed by matching the first component
+     * of the ligature here, instead of calling into the ligation code.
+     *
+     * This is replicated in ChainRuleSet and RuleSet. */
+
+    hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
+    skippy_iter.reset (c->buffer->idx);
+    skippy_iter.set_match_func (match_always, nullptr);
+    skippy_iter.set_glyph_data ((HBUINT16 *) nullptr);
+    unsigned unsafe_to;
+    hb_codepoint_t first = (unsigned) -1;
+    bool matched = skippy_iter.next (&unsafe_to);
+    if (likely (matched))
+    {
+      first = c->buffer->info[skippy_iter.idx].codepoint;
+      unsafe_to = skippy_iter.idx + 1;
+
+      if (skippy_iter.may_skip (c->buffer->info[skippy_iter.idx]))
+      {
+        /* Can't use the fast path if eg. the next char is a default-ignorable
+         * or other skippable. */
+        goto slow;
+      }
+    }
+    else
+      goto slow;
+
+    bool unsafe_to_concat = false;
+
     for (unsigned int i = 0; i < num_ligs; i++)
     {
-      const auto &lig = this+ligature[i];
-      if (lig.apply (c)) return_trace (true);
+      const auto &lig = this+ligature.arrayZ[i];
+      if (unlikely (lig.component.lenP1 <= 1) ||
+          lig.component.arrayZ[0] == first)
+      {
+        if (lig.apply (c))
+        {
+          if (unsafe_to_concat)
+            c->buffer->unsafe_to_concat (c->buffer->idx, unsafe_to);
+          return_trace (true);
+        }
+      }
+      else if (likely (lig.component.lenP1 > 1))
+        unsafe_to_concat = true;
     }
+    if (likely (unsafe_to_concat))
+      c->buffer->unsafe_to_concat (c->buffer->idx, unsafe_to);
 
     return_trace (false);
   }
diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh
index 73f2227..ec6dfa4 100644
--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh
@@ -191,7 +191,6 @@
     TRACE_SERIALIZE (this);
 
     auto *out = c->serializer->start_embed (this);
-    if (unlikely (!c->serializer->check_success (out))) return_trace (false);
     if (unlikely (!c->serializer->embed (this->format))) return_trace (false);
     if (unlikely (!c->serializer->embed (this->coverage))) return_trace (false);
 
diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Sequence.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Sequence.hh
index 62d6816..a5e93a9 100644
--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Sequence.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/Sequence.hh
@@ -53,7 +53,7 @@
       if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
       {
         c->buffer->message (c->font,
-                            "replaced glyph at %u (multiple subtitution)",
+                            "replaced glyph at %u (multiple substitution)",
                             c->buffer->idx - 1u);
       }
 
diff --git a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubst.hh b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubst.hh
index 304d192..b84259e 100644
--- a/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubst.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/Layout/GSUB/SingleSubst.hh
@@ -57,7 +57,7 @@
 
 #ifndef HB_NO_BEYOND_64K
        if (+ glyphs
-           | hb_map_retains_sorting (hb_first)
+           | hb_map_retains_sorting (hb_second)
            | hb_filter ([] (hb_codepoint_t gid) { return gid > 0xFFFFu; }))
        {
          format += 2;
diff --git a/src/java.desktop/share/native/libharfbuzz/OT/glyf/CompositeGlyph.hh b/src/java.desktop/share/native/libharfbuzz/OT/glyf/CompositeGlyph.hh
index 94cb61a..151c1ac 100644
--- a/src/java.desktop/share/native/libharfbuzz/OT/glyf/CompositeGlyph.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/glyf/CompositeGlyph.hh
@@ -87,19 +87,54 @@
     }
   }
 
-  void transform_points (contour_point_vector_t &points,
+  static void transform (const float (&matrix)[4],
+                         hb_array_t<contour_point_t> points)
+  {
+    if (matrix[0] != 1.f || matrix[1] != 0.f ||
+        matrix[2] != 0.f || matrix[3] != 1.f)
+      for (auto &point : points)
+        point.transform (matrix);
+  }
+
+  static void translate (const contour_point_t &trans,
+                         hb_array_t<contour_point_t> points)
+  {
+    if (HB_OPTIMIZE_SIZE_VAL)
+    {
+      if (trans.x != 0.f || trans.y != 0.f)
+        for (auto &point : points)
+          point.translate (trans);
+    }
+    else
+    {
+      if (trans.x != 0.f && trans.y != 0.f)
+        for (auto &point : points)
+          point.translate (trans);
+      else
+      {
+        if (trans.x != 0.f)
+          for (auto &point : points)
+            point.x += trans.x;
+        else if (trans.y != 0.f)
+          for (auto &point : points)
+            point.y += trans.y;
+      }
+    }
+  }
+
+  void transform_points (hb_array_t<contour_point_t> points,
                          const float (&matrix)[4],
                          const contour_point_t &trans) const
   {
     if (scaled_offsets ())
     {
-      points.translate (trans);
-      points.transform (matrix);
+      translate (trans, points);
+      transform (matrix, points);
     }
     else
     {
-      points.transform (matrix);
-      points.translate (trans);
+      transform (matrix, points);
+      translate (trans, points);
     }
   }
 
@@ -108,8 +143,8 @@
     float matrix[4];
     contour_point_t trans;
     get_transformation (matrix, trans);
-    if (unlikely (!points.resize (points.length + 1))) return false;
-    points[points.length - 1] = trans;
+    if (unlikely (!points.alloc (points.length + 4))) return false; // For phantom points
+    points.push (trans);
     return true;
   }
 
@@ -358,7 +393,7 @@
     {
       /* last 4 points in points_with_deltas are phantom points and should not be included */
       if (i >= points_with_deltas.length - 4) {
-        free (o);
+        hb_free (o);
         return false;
       }
 
diff --git a/src/java.desktop/share/native/libharfbuzz/OT/glyf/Glyph.hh b/src/java.desktop/share/native/libharfbuzz/OT/glyf/Glyph.hh
index 1ebaaa3..b295e41 100644
--- a/src/java.desktop/share/native/libharfbuzz/OT/glyf/Glyph.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/glyf/Glyph.hh
@@ -103,6 +103,63 @@
     }
   }
 
+  bool get_all_points_without_var (const hb_face_t *face,
+                                   contour_point_vector_t &points /* OUT */) const
+  {
+    switch (type) {
+    case SIMPLE:
+      if (unlikely (!SimpleGlyph (*header, bytes).get_contour_points (points)))
+        return false;
+      break;
+    case COMPOSITE:
+    {
+      for (auto &item : get_composite_iterator ())
+        if (unlikely (!item.get_points (points))) return false;
+      break;
+    }
+#ifndef HB_NO_VAR_COMPOSITES
+    case VAR_COMPOSITE:
+    {
+      for (auto &item : get_var_composite_iterator ())
+        if (unlikely (!item.get_points (points))) return false;
+      break;
+    }
+#endif
+    case EMPTY:
+      break;
+    }
+
+    /* Init phantom points */
+    if (unlikely (!points.resize (points.length + PHANTOM_COUNT))) return false;
+    hb_array_t<contour_point_t> phantoms = points.as_array ().sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT);
+    {
+      int lsb = 0;
+      int h_delta = face->table.hmtx->get_leading_bearing_without_var_unscaled (gid, &lsb) ?
+                    (int) header->xMin - lsb : 0;
+      HB_UNUSED int tsb = 0;
+      int v_orig  = (int) header->yMax +
+#ifndef HB_NO_VERTICAL
+                    ((void) face->table.vmtx->get_leading_bearing_without_var_unscaled (gid, &tsb), tsb)
+#else
+                    0
+#endif
+                    ;
+      unsigned h_adv = face->table.hmtx->get_advance_without_var_unscaled (gid);
+      unsigned v_adv =
+#ifndef HB_NO_VERTICAL
+                       face->table.vmtx->get_advance_without_var_unscaled (gid)
+#else
+                       - face->get_upem ()
+#endif
+                       ;
+      phantoms[PHANTOM_LEFT].x = h_delta;
+      phantoms[PHANTOM_RIGHT].x = (int) h_adv + h_delta;
+      phantoms[PHANTOM_TOP].y = v_orig;
+      phantoms[PHANTOM_BOTTOM].y = v_orig - (int) v_adv;
+    }
+    return true;
+  }
+
   void update_mtx (const hb_subset_plan_t *plan,
                    int xMin, int xMax,
                    int yMin, int yMax,
@@ -114,8 +171,8 @@
 
     if (type != EMPTY)
     {
-      plan->bounds_width_map.set (new_gid, xMax - xMin);
-      plan->bounds_height_map.set (new_gid, yMax - yMin);
+      plan->bounds_width_vec[new_gid] = xMax - xMin;
+      plan->bounds_height_vec[new_gid] = yMax - yMin;
     }
 
     unsigned len = all_points.length;
@@ -124,10 +181,12 @@
     float topSideY = all_points[len - 2].y;
     float bottomSideY = all_points[len - 1].y;
 
+    uint32_t hash = hb_hash (new_gid);
+
     signed hori_aw = roundf (rightSideX - leftSideX);
     if (hori_aw < 0) hori_aw = 0;
     int lsb = roundf (xMin - leftSideX);
-    plan->hmtx_map.set (new_gid, hb_pair ((unsigned) hori_aw, lsb));
+    plan->hmtx_map.set_with_hash (new_gid, hash, hb_pair ((unsigned) hori_aw, lsb));
     //flag value should be computed using non-empty glyphs
     if (type != EMPTY && lsb != xMin)
       plan->head_maxp_info.allXMinIsLsb = false;
@@ -135,7 +194,7 @@
     signed vert_aw = roundf (topSideY - bottomSideY);
     if (vert_aw < 0) vert_aw = 0;
     int tsb = roundf (topSideY - yMax);
-    plan->vmtx_map.set (new_gid, hb_pair ((unsigned) vert_aw, tsb));
+    plan->vmtx_map.set_with_hash (new_gid, hash, hb_pair ((unsigned) vert_aw, tsb));
   }
 
   bool compile_header_bytes (const hb_subset_plan_t *plan,
@@ -155,24 +214,28 @@
     {
       xMin = xMax = all_points[0].x;
       yMin = yMax = all_points[0].y;
+
+      unsigned count = all_points.length - 4;
+      for (unsigned i = 1; i < count; i++)
+      {
+        float x = all_points[i].x;
+        float y = all_points[i].y;
+        xMin = hb_min (xMin, x);
+        xMax = hb_max (xMax, x);
+        yMin = hb_min (yMin, y);
+        yMax = hb_max (yMax, y);
+      }
     }
 
-    for (unsigned i = 1; i < all_points.length - 4; i++)
-    {
-      float x = all_points[i].x;
-      float y = all_points[i].y;
-      xMin = hb_min (xMin, x);
-      xMax = hb_max (xMax, x);
-      yMin = hb_min (yMin, y);
-      yMax = hb_max (yMax, y);
-    }
 
-    update_mtx (plan, roundf (xMin), roundf (xMax), roundf (yMin), roundf (yMax), all_points);
+    // These are destined for storage in a 16 bit field to clamp the values to
+    // fit into a 16 bit signed integer.
+    int rounded_xMin = hb_clamp (roundf (xMin), -32768.0f, 32767.0f);
+    int rounded_xMax = hb_clamp (roundf (xMax), -32768.0f, 32767.0f);
+    int rounded_yMin = hb_clamp (roundf (yMin), -32768.0f, 32767.0f);
+    int rounded_yMax = hb_clamp (roundf (yMax), -32768.0f, 32767.0f);
 
-    int rounded_xMin = roundf (xMin);
-    int rounded_xMax = roundf (xMax);
-    int rounded_yMin = roundf (yMin);
-    int rounded_yMax = roundf (yMax);
+    update_mtx (plan, rounded_xMin, rounded_xMax, rounded_yMin, rounded_yMax, all_points);
 
     if (type != EMPTY)
     {
@@ -287,6 +350,7 @@
                    bool use_my_metrics = true,
                    bool phantom_only = false,
                    hb_array_t<int> coords = hb_array_t<int> (),
+                   hb_map_t *current_glyphs = nullptr,
                    unsigned int depth = 0,
                    unsigned *edge_count = nullptr) const
   {
@@ -296,6 +360,10 @@
     if (unlikely (*edge_count > HB_GLYF_MAX_EDGE_COUNT)) return false;
     (*edge_count)++;
 
+    hb_map_t current_glyphs_stack;
+    if (current_glyphs == nullptr)
+      current_glyphs = &current_glyphs_stack;
+
     if (head_maxp_info)
     {
       head_maxp_info->maxComponentDepth = hb_max (head_maxp_info->maxComponentDepth, depth);
@@ -305,9 +373,8 @@
       coords = hb_array (font->coords, font->num_coords);
 
     contour_point_vector_t stack_points;
-    bool inplace = type == SIMPLE && all_points.length == 0;
-    /* Load into all_points if it's empty, as an optimization. */
-    contour_point_vector_t &points = inplace ? all_points : stack_points;
+    contour_point_vector_t &points = type == SIMPLE ? all_points : stack_points;
+    unsigned old_length = points.length;
 
     switch (type) {
     case SIMPLE:
@@ -315,7 +382,7 @@
         head_maxp_info->maxContours = hb_max (head_maxp_info->maxContours, (unsigned) header->numberOfContours);
       if (depth > 0 && composite_contours)
         *composite_contours += (unsigned) header->numberOfContours;
-      if (unlikely (!SimpleGlyph (*header, bytes).get_contour_points (points, phantom_only)))
+      if (unlikely (!SimpleGlyph (*header, bytes).get_contour_points (all_points, phantom_only)))
         return false;
       break;
     case COMPOSITE:
@@ -329,6 +396,7 @@
     {
       for (auto &item : get_var_composite_iterator ())
         if (unlikely (!item.get_points (points))) return false;
+      break;
     }
 #endif
     case EMPTY:
@@ -365,9 +433,11 @@
     }
 
 #ifndef HB_NO_VAR
-    glyf_accelerator.gvar->apply_deltas_to_points (gid,
-                                                   coords,
-                                                   points.as_array ());
+    if (coords)
+      glyf_accelerator.gvar->apply_deltas_to_points (gid,
+                                                     coords,
+                                                     points.as_array ().sub_array (old_length),
+                                                     phantom_only && type == SIMPLE);
 #endif
 
     // mainly used by CompositeGlyph calculating new X/Y offset value so no need to extend it
@@ -375,27 +445,33 @@
     if (points_with_deltas != nullptr && depth == 0 && type == COMPOSITE)
     {
       if (unlikely (!points_with_deltas->resize (points.length))) return false;
-      points_with_deltas->copy_vector (points);
+      *points_with_deltas = points;
     }
 
     switch (type) {
     case SIMPLE:
       if (depth == 0 && head_maxp_info)
-        head_maxp_info->maxPoints = hb_max (head_maxp_info->maxPoints, points.length - 4);
-      if (!inplace)
-        all_points.extend (points.as_array ());
+        head_maxp_info->maxPoints = hb_max (head_maxp_info->maxPoints, all_points.length - old_length - 4);
       break;
     case COMPOSITE:
     {
-      contour_point_vector_t comp_points;
       unsigned int comp_index = 0;
       for (auto &item : get_composite_iterator ())
       {
-        comp_points.reset ();
-        if (unlikely (!glyf_accelerator.glyph_for_gid (item.get_gid ())
+        hb_codepoint_t item_gid = item.get_gid ();
+
+        if (unlikely (current_glyphs->has (item_gid)))
+          continue;
+
+        current_glyphs->add (item_gid);
+
+        unsigned old_count = all_points.length;
+
+        if (unlikely ((!phantom_only || (use_my_metrics && item.is_use_my_metrics ())) &&
+                      !glyf_accelerator.glyph_for_gid (item_gid)
                                        .get_points (font,
                                                     glyf_accelerator,
-                                                    comp_points,
+                                                    all_points,
                                                     points_with_deltas,
                                                     head_maxp_info,
                                                     composite_contours,
@@ -403,23 +479,32 @@
                                                     use_my_metrics,
                                                     phantom_only,
                                                     coords,
+                                                    current_glyphs,
                                                     depth + 1,
                                                     edge_count)))
+        {
+          current_glyphs->del (item_gid);
           return false;
+        }
+
+        auto comp_points = all_points.as_array ().sub_array (old_count);
 
         /* Copy phantom points from component if USE_MY_METRICS flag set */
         if (use_my_metrics && item.is_use_my_metrics ())
           for (unsigned int i = 0; i < PHANTOM_COUNT; i++)
             phantoms[i] = comp_points[comp_points.length - PHANTOM_COUNT + i];
 
-        float matrix[4];
-        contour_point_t default_trans;
-        item.get_transformation (matrix, default_trans);
+        if (comp_points) // Empty in case of phantom_only
+        {
+          float matrix[4];
+          contour_point_t default_trans;
+          item.get_transformation (matrix, default_trans);
 
-        /* Apply component transformation & translation (with deltas applied) */
-        item.transform_points (comp_points, matrix, points[comp_index]);
+          /* Apply component transformation & translation (with deltas applied) */
+          item.transform_points (comp_points, matrix, points[comp_index]);
+        }
 
-        if (item.is_anchored ())
+        if (item.is_anchored () && !phantom_only)
         {
           unsigned int p1, p2;
           item.get_anchor_points (p1, p2);
@@ -429,16 +514,20 @@
             delta.init (all_points[p1].x - comp_points[p2].x,
                         all_points[p1].y - comp_points[p2].y);
 
-            comp_points.translate (delta);
+            item.translate (delta, comp_points);
           }
         }
 
-        all_points.extend (comp_points.as_array ().sub_array (0, comp_points.length - PHANTOM_COUNT));
+        all_points.resize (all_points.length - PHANTOM_COUNT);
 
         if (all_points.length > HB_GLYF_MAX_POINTS)
+        {
+          current_glyphs->del (item_gid);
           return false;
+        }
 
         comp_index++;
+        current_glyphs->del (item_gid);
       }
 
       if (head_maxp_info && depth == 0)
@@ -453,26 +542,37 @@
 #ifndef HB_NO_VAR_COMPOSITES
     case VAR_COMPOSITE:
     {
-      contour_point_vector_t comp_points;
       hb_array_t<contour_point_t> points_left = points.as_array ();
       for (auto &item : get_var_composite_iterator ())
       {
+        hb_codepoint_t item_gid = item.get_gid ();
+
+        if (unlikely (current_glyphs->has (item_gid)))
+          continue;
+
+        current_glyphs->add (item_gid);
+
         unsigned item_num_points = item.get_num_points ();
         hb_array_t<contour_point_t> record_points = points_left.sub_array (0, item_num_points);
-
-        comp_points.reset ();
+        assert (record_points.length == item_num_points);
 
         auto component_coords = coords;
-        if (item.is_reset_unspecified_axes ())
+        /* Copying coords is expensive; so we have put an arbitrary
+         * limit on the max number of coords for now. */
+        if (item.is_reset_unspecified_axes () ||
+            coords.length > HB_GLYF_VAR_COMPOSITE_MAX_AXES)
           component_coords = hb_array<int> ();
 
         coord_setter_t coord_setter (component_coords);
         item.set_variations (coord_setter, record_points);
 
-        if (unlikely (!glyf_accelerator.glyph_for_gid (item.get_gid ())
+        unsigned old_count = all_points.length;
+
+        if (unlikely ((!phantom_only || (use_my_metrics && item.is_use_my_metrics ())) &&
+                      !glyf_accelerator.glyph_for_gid (item_gid)
                                        .get_points (font,
                                                     glyf_accelerator,
-                                                    comp_points,
+                                                    all_points,
                                                     points_with_deltas,
                                                     head_maxp_info,
                                                     nullptr,
@@ -480,24 +580,36 @@
                                                     use_my_metrics,
                                                     phantom_only,
                                                     coord_setter.get_coords (),
+                                                    current_glyphs,
                                                     depth + 1,
                                                     edge_count)))
+        {
+          current_glyphs->del (item_gid);
           return false;
+        }
+
+        auto comp_points = all_points.as_array ().sub_array (old_count);
 
         /* Apply component transformation */
-        item.transform_points (record_points, comp_points);
+        if (comp_points) // Empty in case of phantom_only
+          item.transform_points (record_points, comp_points);
 
         /* Copy phantom points from component if USE_MY_METRICS flag set */
         if (use_my_metrics && item.is_use_my_metrics ())
           for (unsigned int i = 0; i < PHANTOM_COUNT; i++)
             phantoms[i] = comp_points[comp_points.length - PHANTOM_COUNT + i];
 
-        all_points.extend (comp_points.as_array ().sub_array (0, comp_points.length - PHANTOM_COUNT));
+        all_points.resize (all_points.length - PHANTOM_COUNT);
 
         if (all_points.length > HB_GLYF_MAX_POINTS)
+        {
+          current_glyphs->del (item_gid);
           return false;
+        }
 
         points_left += item_num_points;
+
+        current_glyphs->del (item_gid);
       }
       all_points.extend (phantoms);
     } break;
@@ -512,9 +624,10 @@
       /* Undocumented rasterizer behavior:
        * Shift points horizontally by the updated left side bearing
        */
-      contour_point_t delta;
-      delta.init (-phantoms[PHANTOM_LEFT].x, 0.f);
-      if (delta.x) all_points.translate (delta);
+      int v = -phantoms[PHANTOM_LEFT].x;
+      if (v)
+        for (auto &point : all_points)
+          point.x += v;
     }
 
     return !all_points.in_error ();
@@ -545,10 +658,11 @@
     int num_contours = header->numberOfContours;
     if (unlikely (num_contours == 0)) type = EMPTY;
     else if (num_contours > 0) type = SIMPLE;
+    else if (num_contours == -1) type = COMPOSITE;
 #ifndef HB_NO_VAR_COMPOSITES
     else if (num_contours == -2) type = VAR_COMPOSITE;
 #endif
-    else type = COMPOSITE; /* negative numbers */
+    else type = EMPTY; // Spec deviation; Spec says COMPOSITE, but not seen in the wild.
   }
 
   protected:
diff --git a/src/java.desktop/share/native/libharfbuzz/OT/glyf/SimpleGlyph.hh b/src/java.desktop/share/native/libharfbuzz/OT/glyf/SimpleGlyph.hh
index bed9fc8..5088397 100644
--- a/src/java.desktop/share/native/libharfbuzz/OT/glyf/SimpleGlyph.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/glyf/SimpleGlyph.hh
@@ -124,7 +124,7 @@
   }
 
   static bool read_flags (const HBUINT8 *&p /* IN/OUT */,
-                          contour_point_vector_t &points_ /* IN/OUT */,
+                          hb_array_t<contour_point_t> points_ /* IN/OUT */,
                           const HBUINT8 *end)
   {
     unsigned count = points_.length;
@@ -146,7 +146,7 @@
   }
 
   static bool read_points (const HBUINT8 *&p /* IN/OUT */,
-                           contour_point_vector_t &points_ /* IN/OUT */,
+                           hb_array_t<contour_point_t> points_ /* IN/OUT */,
                            const HBUINT8 *end,
                            float contour_point_t::*m,
                            const simple_glyph_flag_t short_flag,
@@ -154,10 +154,9 @@
   {
     int v = 0;
 
-    unsigned count = points_.length;
-    for (unsigned i = 0; i < count; i++)
+    for (auto &point : points_)
     {
-      unsigned flag = points_[i].flag;
+      unsigned flag = point.flag;
       if (flag & short_flag)
       {
         if (unlikely (p + 1 > end)) return false;
@@ -175,23 +174,27 @@
           p += HBINT16::static_size;
         }
       }
-      points_.arrayZ[i].*m = v;
+      point.*m = v;
     }
     return true;
   }
 
-  bool get_contour_points (contour_point_vector_t &points_ /* OUT */,
+  bool get_contour_points (contour_point_vector_t &points /* OUT */,
                            bool phantom_only = false) const
   {
     const HBUINT16 *endPtsOfContours = &StructAfter<HBUINT16> (header);
     int num_contours = header.numberOfContours;
-    assert (num_contours);
+    assert (num_contours > 0);
     /* One extra item at the end, for the instruction-count below. */
     if (unlikely (!bytes.check_range (&endPtsOfContours[num_contours]))) return false;
     unsigned int num_points = endPtsOfContours[num_contours - 1] + 1;
 
-    points_.alloc (num_points + 4, true); // Allocate for phantom points, to avoid a possible copy
-    if (!points_.resize (num_points)) return false;
+    unsigned old_length = points.length;
+    points.alloc (points.length + num_points + 4, true); // Allocate for phantom points, to avoid a possible copy
+    if (unlikely (!points.resize (points.length + num_points, false))) return false;
+    auto points_ = points.as_array ().sub_array (old_length);
+    if (!phantom_only)
+      hb_memset (points_.arrayZ, 0, sizeof (contour_point_t) * num_points);
     if (phantom_only) return true;
 
     for (int i = 0; i < num_contours; i++)
@@ -214,7 +217,7 @@
   }
 
   static void encode_coord (int value,
-                            uint8_t &flag,
+                            unsigned &flag,
                             const simple_glyph_flag_t short_flag,
                             const simple_glyph_flag_t same_flag,
                             hb_vector_t<uint8_t> &coords /* OUT */)
@@ -239,9 +242,9 @@
     }
   }
 
-  static void encode_flag (uint8_t &flag,
-                           uint8_t &repeat,
-                           uint8_t lastflag,
+  static void encode_flag (unsigned flag,
+                           unsigned &repeat,
+                           unsigned lastflag,
                            hb_vector_t<uint8_t> &flags /* OUT */)
   {
     if (flag == lastflag && repeat != 255)
@@ -262,7 +265,7 @@
     else
     {
       repeat = 0;
-      flags.push (flag);
+      flags.arrayZ[flags.length++] = flag;
     }
   }
 
@@ -282,13 +285,13 @@
     if (unlikely (!x_coords.alloc (2*num_points, true))) return false;
     if (unlikely (!y_coords.alloc (2*num_points, true))) return false;
 
-    uint8_t lastflag = 255, repeat = 0;
+    unsigned lastflag = 255, repeat = 0;
     int prev_x = 0, prev_y = 0;
 
     for (unsigned i = 0; i < num_points; i++)
     {
-      uint8_t flag = all_points.arrayZ[i].flag;
-      flag &= FLAG_ON_CURVE + FLAG_OVERLAP_SIMPLE;
+      unsigned flag = all_points.arrayZ[i].flag;
+      flag &= FLAG_ON_CURVE | FLAG_OVERLAP_SIMPLE | FLAG_CUBIC;
 
       int cur_x = roundf (all_points.arrayZ[i].x);
       int cur_y = roundf (all_points.arrayZ[i].y);
diff --git a/src/java.desktop/share/native/libharfbuzz/OT/glyf/SubsetGlyph.hh b/src/java.desktop/share/native/libharfbuzz/OT/glyf/SubsetGlyph.hh
index d6ce5be..9c04d89 100644
--- a/src/java.desktop/share/native/libharfbuzz/OT/glyf/SubsetGlyph.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/glyf/SubsetGlyph.hh
@@ -22,7 +22,7 @@
 
   bool serialize (hb_serialize_context_t *c,
                   bool use_short_loca,
-                  const hb_subset_plan_t *plan)
+                  const hb_subset_plan_t *plan) const
   {
     TRACE_SERIALIZE (this);
 
@@ -40,7 +40,7 @@
     pad = 0;
     while (pad_length > 0)
     {
-      c->embed (pad);
+      (void) c->embed (pad);
       pad_length--;
     }
 
diff --git a/src/java.desktop/share/native/libharfbuzz/OT/glyf/VarCompositeGlyph.hh b/src/java.desktop/share/native/libharfbuzz/OT/glyf/VarCompositeGlyph.hh
index f2dcb06..4f29f0a 100644
--- a/src/java.desktop/share/native/libharfbuzz/OT/glyf/VarCompositeGlyph.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/glyf/VarCompositeGlyph.hh
@@ -36,24 +36,21 @@
 
   unsigned int get_size () const
   {
+    unsigned fl = flags;
     unsigned int size = min_size;
 
-    unsigned axis_width = (flags & AXIS_INDICES_ARE_SHORT) ? 4 : 3;
+    unsigned axis_width = (fl & AXIS_INDICES_ARE_SHORT) ? 4 : 3;
     size += numAxes * axis_width;
 
-    // gid
-    size += 2;
-    if (flags & GID_IS_24BIT)           size += 1;
+    if (fl & GID_IS_24BIT)      size += 1;
 
-    if (flags & HAVE_TRANSLATE_X)       size += 2;
-    if (flags & HAVE_TRANSLATE_Y)       size += 2;
-    if (flags & HAVE_ROTATION)          size += 2;
-    if (flags & HAVE_SCALE_X)           size += 2;
-    if (flags & HAVE_SCALE_Y)           size += 2;
-    if (flags & HAVE_SKEW_X)            size += 2;
-    if (flags & HAVE_SKEW_Y)            size += 2;
-    if (flags & HAVE_TCENTER_X)         size += 2;
-    if (flags & HAVE_TCENTER_Y)         size += 2;
+    // 2 bytes each for the following flags
+    fl = fl & (HAVE_TRANSLATE_X | HAVE_TRANSLATE_Y |
+               HAVE_ROTATION |
+               HAVE_SCALE_X | HAVE_SCALE_Y |
+               HAVE_SKEW_X | HAVE_SKEW_Y |
+               HAVE_TCENTER_X | HAVE_TCENTER_Y);
+    size += hb_popcount (fl) * 2;
 
     return size;
   }
@@ -66,17 +63,17 @@
   hb_codepoint_t get_gid () const
   {
     if (flags & GID_IS_24BIT)
-      return StructAfter<const HBGlyphID24> (numAxes);
+      return * (const HBGlyphID24 *) &pad;
     else
-      return StructAfter<const HBGlyphID16> (numAxes);
+      return * (const HBGlyphID16 *) &pad;
   }
 
   void set_gid (hb_codepoint_t gid)
   {
     if (flags & GID_IS_24BIT)
-      StructAfter<HBGlyphID24> (numAxes) = gid;
+      * (HBGlyphID24 *) &pad = gid;
     else
-      StructAfter<HBGlyphID16> (numAxes) = gid;
+      * (HBGlyphID16 *) &pad = gid;
   }
 
   unsigned get_numAxes () const
@@ -86,26 +83,44 @@
 
   unsigned get_num_points () const
   {
+    unsigned fl = flags;
     unsigned num = 0;
-    if (flags & AXES_HAVE_VARIATION)                    num += numAxes;
-    if (flags & (HAVE_TRANSLATE_X | HAVE_TRANSLATE_Y))  num++;
-    if (flags & HAVE_ROTATION)                          num++;
-    if (flags & (HAVE_SCALE_X | HAVE_SCALE_Y))          num++;
-    if (flags & (HAVE_SKEW_X | HAVE_SKEW_Y))            num++;
-    if (flags & (HAVE_TCENTER_X | HAVE_TCENTER_Y))      num++;
+    if (fl & AXES_HAVE_VARIATION)                       num += numAxes;
+
+    /* Hopefully faster code, relying on the value of the flags. */
+    fl = (((fl & (HAVE_TRANSLATE_Y | HAVE_SCALE_Y | HAVE_SKEW_Y | HAVE_TCENTER_Y)) >> 1) | fl) &
+         (HAVE_TRANSLATE_X | HAVE_ROTATION | HAVE_SCALE_X | HAVE_SKEW_X | HAVE_TCENTER_X);
+    num += hb_popcount (fl);
+    return num;
+
+    /* Slower but more readable code. */
+    if (fl & (HAVE_TRANSLATE_X | HAVE_TRANSLATE_Y))     num++;
+    if (fl & HAVE_ROTATION)                             num++;
+    if (fl & (HAVE_SCALE_X | HAVE_SCALE_Y))             num++;
+    if (fl & (HAVE_SKEW_X | HAVE_SKEW_Y))               num++;
+    if (fl & (HAVE_TCENTER_X | HAVE_TCENTER_Y))         num++;
     return num;
   }
 
-  void transform_points (hb_array_t<contour_point_t> record_points,
-                         contour_point_vector_t &points) const
+  void transform_points (hb_array_t<const contour_point_t> record_points,
+                         hb_array_t<contour_point_t> points) const
   {
     float matrix[4];
     contour_point_t trans;
 
-    get_transformation_from_points (record_points, matrix, trans);
+    get_transformation_from_points (record_points.arrayZ, matrix, trans);
 
-    points.transform (matrix);
-    points.translate (trans);
+    auto arrayZ = points.arrayZ;
+    unsigned count = points.length;
+
+    if (matrix[0] != 1.f || matrix[1] != 0.f ||
+        matrix[2] != 0.f || matrix[3] != 1.f)
+      for (unsigned i = 0; i < count; i++)
+        arrayZ[i].transform (matrix);
+
+    if (trans.x != 0.f || trans.y != 0.f)
+      for (unsigned i = 0; i < count; i++)
+        arrayZ[i].translate (trans);
   }
 
   static inline void transform (float (&matrix)[4], contour_point_t &trans,
@@ -136,26 +151,41 @@
   static void translate (float (&matrix)[4], contour_point_t &trans,
                          float translateX, float translateY)
   {
-    // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L213
-    float other[6] = {1.f, 0.f, 0.f, 1.f, translateX, translateY};
-    transform (matrix, trans, other);
+    if (!translateX && !translateY)
+      return;
+
+    trans.x += matrix[0] * translateX + matrix[2] * translateY;
+    trans.y += matrix[1] * translateX + matrix[3] * translateY;
   }
 
   static void scale (float (&matrix)[4], contour_point_t &trans,
                      float scaleX, float scaleY)
   {
-    // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L224
-    float other[6] = {scaleX, 0.f, 0.f, scaleY, 0.f, 0.f};
-    transform (matrix, trans, other);
+    if (scaleX == 1.f && scaleY == 1.f)
+      return;
+
+    matrix[0] *= scaleX;
+    matrix[1] *= scaleX;
+    matrix[2] *= scaleY;
+    matrix[3] *= scaleY;
   }
 
   static void rotate (float (&matrix)[4], contour_point_t &trans,
                       float rotation)
   {
+    if (!rotation)
+      return;
+
     // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L240
     rotation = rotation * HB_PI;
-    float c = cosf (rotation);
-    float s = sinf (rotation);
+    float c;
+    float s;
+#ifdef HAVE_SINCOSF
+    sincosf (rotation, &s, &c);
+#else
+    c = cosf (rotation);
+    s = sinf (rotation);
+#endif
     float other[6] = {c, s, -s, c, 0.f, 0.f};
     transform (matrix, trans, other);
   }
@@ -163,101 +193,100 @@
   static void skew (float (&matrix)[4], contour_point_t &trans,
                     float skewX, float skewY)
   {
+    if (!skewX && !skewY)
+      return;
+
     // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L255
     skewX = skewX * HB_PI;
     skewY = skewY * HB_PI;
-    float other[6] = {1.f, tanf (skewY), tanf (skewX), 1.f, 0.f, 0.f};
+    float other[6] = {1.f,
+                      skewY ? tanf (skewY) : 0.f,
+                      skewX ? tanf (skewX) : 0.f,
+                      1.f,
+                      0.f, 0.f};
     transform (matrix, trans, other);
   }
 
   bool get_points (contour_point_vector_t &points) const
   {
-    float translateX = 0.f;
-    float translateY = 0.f;
-    float rotation = 0.f;
-    float scaleX = 1.f * (1 << 10);
-    float scaleY = 1.f * (1 << 10);
-    float skewX = 0.f;
-    float skewY = 0.f;
-    float tCenterX = 0.f;
-    float tCenterY = 0.f;
-
     unsigned num_points = get_num_points ();
 
-    if (unlikely (!points.resize (points.length + num_points))) return false;
+    points.alloc (points.length + num_points + 4); // For phantom points
+    if (unlikely (!points.resize (points.length + num_points, false))) return false;
+    contour_point_t *rec_points = points.arrayZ + (points.length - num_points);
+    hb_memset (rec_points, 0, num_points * sizeof (rec_points[0]));
 
-    unsigned axis_width = (flags & AXIS_INDICES_ARE_SHORT) ? 2 : 1;
-    unsigned axes_size = numAxes * axis_width;
+    unsigned fl = flags;
+
+    unsigned num_axes = numAxes;
+    unsigned axis_width = (fl & AXIS_INDICES_ARE_SHORT) ? 2 : 1;
+    unsigned axes_size = num_axes * axis_width;
 
     const F2DOT14 *q = (const F2DOT14 *) (axes_size +
-                                          (flags & GID_IS_24BIT ? 3 : 2) +
-                                          &StructAfter<const HBUINT8> (numAxes));
+                                          (fl & GID_IS_24BIT ? 3 : 2) +
+                                          (const HBUINT8 *) &pad);
 
-    hb_array_t<contour_point_t> rec_points = points.as_array ().sub_array (points.length - num_points);
-
-    unsigned count = numAxes;
-    if (flags & AXES_HAVE_VARIATION)
+    unsigned count = num_axes;
+    if (fl & AXES_HAVE_VARIATION)
     {
       for (unsigned i = 0; i < count; i++)
-        rec_points[i].x = q++->to_int ();
-      rec_points += count;
+        rec_points++->x = q++->to_int ();
     }
     else
       q += count;
 
     const HBUINT16 *p = (const HBUINT16 *) q;
 
-    if (flags & HAVE_TRANSLATE_X)       translateX = * (const FWORD *) p++;
-    if (flags & HAVE_TRANSLATE_Y)       translateY = * (const FWORD *) p++;
-    if (flags & HAVE_ROTATION)          rotation = ((const F4DOT12 *) p++)->to_int ();
-    if (flags & HAVE_SCALE_X)           scaleX = ((const F6DOT10 *) p++)->to_int ();
-    if (flags & HAVE_SCALE_Y)           scaleY = ((const F6DOT10 *) p++)->to_int ();
-    if (flags & HAVE_SKEW_X)            skewX = ((const F4DOT12 *) p++)->to_int ();
-    if (flags & HAVE_SKEW_Y)            skewY = ((const F4DOT12 *) p++)->to_int ();
-    if (flags & HAVE_TCENTER_X)         tCenterX = * (const FWORD *) p++;
-    if (flags & HAVE_TCENTER_Y)         tCenterY = * (const FWORD *) p++;
-
-    if ((flags & UNIFORM_SCALE) && !(flags & HAVE_SCALE_Y))
-      scaleY = scaleX;
-
-    if (flags & (HAVE_TRANSLATE_X | HAVE_TRANSLATE_Y))
+    if (fl & (HAVE_TRANSLATE_X | HAVE_TRANSLATE_Y))
     {
-      rec_points[0].x = translateX;
-      rec_points[0].y = translateY;
+      int translateX = (fl & HAVE_TRANSLATE_X) ? * (const FWORD *) p++ : 0;
+      int translateY = (fl & HAVE_TRANSLATE_Y) ? * (const FWORD *) p++ : 0;
+      rec_points->x = translateX;
+      rec_points->y = translateY;
       rec_points++;
     }
-    if (flags & HAVE_ROTATION)
+    if (fl & HAVE_ROTATION)
     {
-      rec_points[0].x = rotation;
+      int rotation = (fl & HAVE_ROTATION) ? ((const F4DOT12 *) p++)->to_int () : 0;
+      rec_points->x = rotation;
       rec_points++;
     }
-    if (flags & (HAVE_SCALE_X | HAVE_SCALE_Y))
+    if (fl & (HAVE_SCALE_X | HAVE_SCALE_Y))
     {
-      rec_points[0].x = scaleX;
-      rec_points[0].y = scaleY;
+      int scaleX = (fl & HAVE_SCALE_X) ? ((const F6DOT10 *) p++)->to_int () : 1 << 10;
+      int scaleY = (fl & HAVE_SCALE_Y) ? ((const F6DOT10 *) p++)->to_int () : 1 << 10;
+      if ((fl & UNIFORM_SCALE) && !(fl & HAVE_SCALE_Y))
+        scaleY = scaleX;
+      rec_points->x = scaleX;
+      rec_points->y = scaleY;
       rec_points++;
     }
-    if (flags & (HAVE_SKEW_X | HAVE_SKEW_Y))
+    if (fl & (HAVE_SKEW_X | HAVE_SKEW_Y))
     {
-      rec_points[0].x = skewX;
-      rec_points[0].y = skewY;
+      int skewX = (fl & HAVE_SKEW_X) ? ((const F4DOT12 *) p++)->to_int () : 0;
+      int skewY = (fl & HAVE_SKEW_Y) ? ((const F4DOT12 *) p++)->to_int () : 0;
+      rec_points->x = skewX;
+      rec_points->y = skewY;
       rec_points++;
     }
-    if (flags & (HAVE_TCENTER_X | HAVE_TCENTER_Y))
+    if (fl & (HAVE_TCENTER_X | HAVE_TCENTER_Y))
     {
-      rec_points[0].x = tCenterX;
-      rec_points[0].y = tCenterY;
+      int tCenterX = (fl & HAVE_TCENTER_X) ? * (const FWORD *) p++ : 0;
+      int tCenterY = (fl & HAVE_TCENTER_Y) ? * (const FWORD *) p++ : 0;
+      rec_points->x = tCenterX;
+      rec_points->y = tCenterY;
       rec_points++;
     }
-    assert (!rec_points);
 
     return true;
   }
 
-  void get_transformation_from_points (hb_array_t<contour_point_t> rec_points,
+  void get_transformation_from_points (const contour_point_t *rec_points,
                                        float (&matrix)[4], contour_point_t &trans) const
   {
-    if (flags & AXES_HAVE_VARIATION)
+    unsigned fl = flags;
+
+    if (fl & AXES_HAVE_VARIATION)
       rec_points += numAxes;
 
     matrix[0] = matrix[3] = 1.f;
@@ -274,36 +303,35 @@
     float tCenterX = 0.f;
     float tCenterY = 0.f;
 
-    if (flags & (HAVE_TRANSLATE_X | HAVE_TRANSLATE_Y))
+    if (fl & (HAVE_TRANSLATE_X | HAVE_TRANSLATE_Y))
     {
-      translateX = rec_points[0].x;
-      translateY = rec_points[0].y;
+      translateX = rec_points->x;
+      translateY = rec_points->y;
       rec_points++;
     }
-    if (flags & HAVE_ROTATION)
+    if (fl & HAVE_ROTATION)
     {
-      rotation = rec_points[0].x / (1 << 12);
+      rotation = rec_points->x / (1 << 12);
       rec_points++;
     }
-    if (flags & (HAVE_SCALE_X | HAVE_SCALE_Y))
+    if (fl & (HAVE_SCALE_X | HAVE_SCALE_Y))
     {
-      scaleX = rec_points[0].x / (1 << 10);
-      scaleY = rec_points[0].y / (1 << 10);
+      scaleX = rec_points->x / (1 << 10);
+      scaleY = rec_points->y / (1 << 10);
       rec_points++;
     }
-    if (flags & (HAVE_SKEW_X | HAVE_SKEW_Y))
+    if (fl & (HAVE_SKEW_X | HAVE_SKEW_Y))
     {
-      skewX = rec_points[0].x / (1 << 12);
-      skewY = rec_points[0].y / (1 << 12);
+      skewX = rec_points->x / (1 << 12);
+      skewY = rec_points->y / (1 << 12);
       rec_points++;
     }
-    if (flags & (HAVE_TCENTER_X | HAVE_TCENTER_Y))
+    if (fl & (HAVE_TCENTER_X | HAVE_TCENTER_Y))
     {
-      tCenterX = rec_points[0].x;
-      tCenterY = rec_points[0].y;
+      tCenterX = rec_points->x;
+      tCenterY = rec_points->y;
       rec_points++;
     }
-    assert (!rec_points);
 
     translate (matrix, trans, translateX + tCenterX, translateY + tCenterY);
     rotate (matrix, trans, rotation);
@@ -317,18 +345,19 @@
   {
     bool have_variations = flags & AXES_HAVE_VARIATION;
     unsigned axis_width = (flags & AXIS_INDICES_ARE_SHORT) ? 2 : 1;
+    unsigned num_axes = numAxes;
 
     const HBUINT8  *p = (const HBUINT8 *)  (((HBUINT8 *) &numAxes) + numAxes.static_size + (flags & GID_IS_24BIT ? 3 : 2));
     const HBUINT16 *q = (const HBUINT16 *) (((HBUINT8 *) &numAxes) + numAxes.static_size + (flags & GID_IS_24BIT ? 3 : 2));
 
-    const F2DOT14 *a = (const F2DOT14 *) ((HBUINT8 *) (axis_width == 1 ? (p + numAxes) : (HBUINT8 *) (q + numAxes)));
+    const F2DOT14 *a = (const F2DOT14 *) ((HBUINT8 *) (axis_width == 1 ? (p + num_axes) : (HBUINT8 *) (q + num_axes)));
 
-    unsigned count = numAxes;
+    unsigned count = num_axes;
     for (unsigned i = 0; i < count; i++)
     {
       unsigned axis_index = axis_width == 1 ? (unsigned) *p++ : (unsigned) *q++;
 
-      signed v = have_variations ? rec_points[i].x : a++->to_int ();
+      signed v = have_variations ? rec_points.arrayZ[i].x : a++->to_int ();
 
       v = hb_clamp (v, -(1<<14), (1<<14));
       setter[axis_index] = v;
@@ -338,8 +367,9 @@
   protected:
   HBUINT16      flags;
   HBUINT8       numAxes;
+  HBUINT16      pad;
   public:
-  DEFINE_SIZE_MIN (3);
+  DEFINE_SIZE_MIN (5);
 };
 
 using var_composite_iter_t = composite_iter_tmpl<VarCompositeGlyphRecord>;
diff --git a/src/java.desktop/share/native/libharfbuzz/OT/glyf/coord-setter.hh b/src/java.desktop/share/native/libharfbuzz/OT/glyf/coord-setter.hh
index df64ed5..cf05929 100644
--- a/src/java.desktop/share/native/libharfbuzz/OT/glyf/coord-setter.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/glyf/coord-setter.hh
@@ -16,6 +16,8 @@
 
   int& operator [] (unsigned idx)
   {
+    if (unlikely (idx >= HB_GLYF_VAR_COMPOSITE_MAX_AXES))
+      return Crap(int);
     if (coords.length < idx + 1)
       coords.resize (idx + 1);
     return coords[idx];
diff --git a/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf-helpers.hh b/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf-helpers.hh
index 18e2d92..3462e4d 100644
--- a/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf-helpers.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf-helpers.hh
@@ -12,24 +12,44 @@
 namespace glyf_impl {
 
 
-template<typename IteratorIn, typename IteratorOut,
-         hb_requires (hb_is_source_of (IteratorIn, unsigned int)),
-         hb_requires (hb_is_sink_of (IteratorOut, unsigned))>
+template<typename IteratorIn, typename TypeOut,
+         hb_requires (hb_is_source_of (IteratorIn, unsigned int))>
 static void
-_write_loca (IteratorIn&& it, bool short_offsets, IteratorOut&& dest)
+_write_loca (IteratorIn&& it,
+             const hb_sorted_vector_t<hb_codepoint_pair_t> new_to_old_gid_list,
+             bool short_offsets,
+             TypeOut *dest,
+             unsigned num_offsets)
 {
   unsigned right_shift = short_offsets ? 1 : 0;
-  unsigned int offset = 0;
-  dest << 0;
-  + it
-  | hb_map ([=, &offset] (unsigned int padded_size)
-            {
-              offset += padded_size;
-              DEBUG_MSG (SUBSET, nullptr, "loca entry offset %u", offset);
-              return offset >> right_shift;
-            })
-  | hb_sink (dest)
-  ;
+  unsigned offset = 0;
+  TypeOut value;
+  value = 0;
+  *dest++ = value;
+  hb_codepoint_t last = 0;
+  for (auto _ : new_to_old_gid_list)
+  {
+    hb_codepoint_t gid = _.first;
+    for (; last < gid; last++)
+    {
+      DEBUG_MSG (SUBSET, nullptr, "loca entry empty offset %u", offset);
+      *dest++ = value;
+    }
+
+    unsigned padded_size = *it++;
+    offset += padded_size;
+    DEBUG_MSG (SUBSET, nullptr, "loca entry gid %u offset %u padded-size %u", gid, offset, padded_size);
+    value = offset >> right_shift;
+    *dest++ = value;
+
+    last++; // Skip over gid
+  }
+  unsigned num_glyphs = num_offsets - 1;
+  for (; last < num_glyphs; last++)
+  {
+    DEBUG_MSG (SUBSET, nullptr, "loca entry empty offset %u", offset);
+    *dest++ = value;
+  }
 }
 
 static bool
@@ -67,11 +87,14 @@
 template<typename Iterator,
          hb_requires (hb_is_source_of (Iterator, unsigned int))>
 static bool
-_add_loca_and_head (hb_subset_plan_t * plan, Iterator padded_offsets, bool use_short_loca)
+_add_loca_and_head (hb_subset_context_t *c,
+                    Iterator padded_offsets,
+                    bool use_short_loca)
 {
-  unsigned num_offsets = padded_offsets.len () + 1;
+  unsigned num_offsets = c->plan->num_output_glyphs () + 1;
   unsigned entry_size = use_short_loca ? 2 : 4;
-  char *loca_prime_data = (char *) hb_calloc (entry_size, num_offsets);
+
+  char *loca_prime_data = (char *) hb_malloc (entry_size * num_offsets);
 
   if (unlikely (!loca_prime_data)) return false;
 
@@ -79,9 +102,9 @@
              entry_size, num_offsets, entry_size * num_offsets);
 
   if (use_short_loca)
-    _write_loca (padded_offsets, true, hb_array ((HBUINT16 *) loca_prime_data, num_offsets));
+    _write_loca (padded_offsets, c->plan->new_to_old_gid_list, true, (HBUINT16 *) loca_prime_data, num_offsets);
   else
-    _write_loca (padded_offsets, false, hb_array ((HBUINT32 *) loca_prime_data, num_offsets));
+    _write_loca (padded_offsets, c->plan->new_to_old_gid_list, false, (HBUINT32 *) loca_prime_data, num_offsets);
 
   hb_blob_t *loca_blob = hb_blob_create (loca_prime_data,
                                          entry_size * num_offsets,
@@ -89,8 +112,8 @@
                                          loca_prime_data,
                                          hb_free);
 
-  bool result = plan->add_table (HB_OT_TAG_loca, loca_blob)
-             && _add_head_and_set_loca_version (plan, use_short_loca);
+  bool result = c->plan->add_table (HB_OT_TAG_loca, loca_blob)
+             && _add_head_and_set_loca_version (c->plan, use_short_loca);
 
   hb_blob_destroy (loca_blob);
   return result;
diff --git a/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf.hh b/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf.hh
index d2a93a5..175e1de 100644
--- a/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/glyf/glyf.hh
@@ -85,75 +85,72 @@
       return_trace (false);
     }
 
-    glyf *glyf_prime = c->serializer->start_embed <glyf> ();
-    if (unlikely (!c->serializer->check_success (glyf_prime))) return_trace (false);
-
     hb_font_t *font = nullptr;
     if (c->plan->normalized_coords)
     {
       font = _create_font_for_instancing (c->plan);
-      if (unlikely (!font)) return false;
+      if (unlikely (!font))
+        return_trace (false);
     }
 
     hb_vector_t<unsigned> padded_offsets;
-    unsigned num_glyphs = c->plan->num_output_glyphs ();
-    if (unlikely (!padded_offsets.resize (num_glyphs)))
-    {
-      hb_font_destroy (font);
-      return false;
-    }
+    if (unlikely (!padded_offsets.alloc (c->plan->new_to_old_gid_list.length, true)))
+      return_trace (false);
 
     hb_vector_t<glyf_impl::SubsetGlyph> glyphs;
     if (!_populate_subset_glyphs (c->plan, font, glyphs))
     {
       hb_font_destroy (font);
-      return false;
+      return_trace (false);
     }
 
     if (font)
       hb_font_destroy (font);
 
     unsigned max_offset = 0;
-    for (unsigned i = 0; i < num_glyphs; i++)
+    for (auto &g : glyphs)
     {
-      padded_offsets[i] = glyphs[i].padded_size ();
-      max_offset += padded_offsets[i];
+      unsigned size = g.padded_size ();
+      padded_offsets.push (size);
+      max_offset += size;
     }
 
     bool use_short_loca = false;
     if (likely (!c->plan->force_long_loca))
       use_short_loca = max_offset < 0x1FFFF;
 
-    if (!use_short_loca) {
-      for (unsigned i = 0; i < num_glyphs; i++)
-        padded_offsets[i] = glyphs[i].length ();
+    if (!use_short_loca)
+    {
+      padded_offsets.resize (0);
+      for (auto &g : glyphs)
+        padded_offsets.push (g.length ());
     }
 
-    bool result = glyf_prime->serialize (c->serializer, glyphs.writer (), use_short_loca, c->plan);
+    auto *glyf_prime = c->serializer->start_embed <glyf> ();
+    bool result = glyf_prime->serialize (c->serializer, hb_iter (glyphs), use_short_loca, c->plan);
     if (c->plan->normalized_coords && !c->plan->pinned_at_default)
       _free_compiled_subset_glyphs (glyphs);
 
-    if (!result) return false;
+    if (unlikely (!c->serializer->check_success (glyf_impl::_add_loca_and_head (c,
+                                                 padded_offsets.iter (),
+                                                 use_short_loca))))
+      return_trace (false);
 
-    if (unlikely (c->serializer->in_error ())) return_trace (false);
-
-    return_trace (c->serializer->check_success (glyf_impl::_add_loca_and_head (c->plan,
-                                                                               padded_offsets.iter (),
-                                                                               use_short_loca)));
+    return result;
   }
 
   bool
   _populate_subset_glyphs (const hb_subset_plan_t   *plan,
                            hb_font_t                *font,
-                           hb_vector_t<glyf_impl::SubsetGlyph> &glyphs /* OUT */) const;
+                           hb_vector_t<glyf_impl::SubsetGlyph>& glyphs /* OUT */) const;
 
   hb_font_t *
   _create_font_for_instancing (const hb_subset_plan_t *plan) const;
 
   void _free_compiled_subset_glyphs (hb_vector_t<glyf_impl::SubsetGlyph> &glyphs) const
   {
-    for (unsigned i = 0; i < glyphs.length; i++)
-      glyphs[i].free_compiled_bytes ();
+    for (auto &g : glyphs)
+      g.free_compiled_bytes ();
   }
 
   protected:
@@ -222,13 +219,14 @@
     if (unlikely (!glyph_for_gid (gid).get_points (font, *this, all_points, nullptr, nullptr, nullptr, true, true, phantom_only)))
       return false;
 
+    unsigned count = all_points.length;
+    assert (count >= glyf_impl::PHANTOM_COUNT);
+    count -= glyf_impl::PHANTOM_COUNT;
+
     if (consumer.is_consuming_contour_points ())
     {
-      unsigned count = all_points.length;
-      assert (count >= glyf_impl::PHANTOM_COUNT);
-      count -= glyf_impl::PHANTOM_COUNT;
-      for (unsigned point_index = 0; point_index < count; point_index++)
-        consumer.consume_point (all_points[point_index]);
+      for (auto &point : all_points.as_array ().sub_array (0, count))
+        consumer.consume_point (point);
       consumer.points_end ();
     }
 
@@ -236,7 +234,7 @@
     contour_point_t *phantoms = consumer.get_phantoms_sink ();
     if (phantoms)
       for (unsigned i = 0; i < glyf_impl::PHANTOM_COUNT; ++i)
-        phantoms[i] = all_points[all_points.length - glyf_impl::PHANTOM_COUNT + i];
+        phantoms[i] = all_points.arrayZ[count + i];
 
     return true;
   }
@@ -299,6 +297,7 @@
       if (extents) bounds = contour_bounds_t ();
     }
 
+    HB_ALWAYS_INLINE
     void consume_point (const contour_point_t &point) { bounds.add (point); }
     void points_end () { bounds.get_extents (font, extents, scaled); }
 
@@ -431,16 +430,17 @@
                                hb_vector_t<glyf_impl::SubsetGlyph>& glyphs /* OUT */) const
 {
   OT::glyf_accelerator_t glyf (plan->source);
-  unsigned num_glyphs = plan->num_output_glyphs ();
-  if (!glyphs.resize (num_glyphs)) return false;
+  if (!glyphs.alloc (plan->new_to_old_gid_list.length, true)) return false;
 
-  for (auto p : plan->glyph_map->iter ())
+  for (const auto &pair : plan->new_to_old_gid_list)
   {
-    unsigned new_gid = p.second;
-    glyf_impl::SubsetGlyph& subset_glyph = glyphs.arrayZ[new_gid];
-    subset_glyph.old_gid = p.first;
+    hb_codepoint_t new_gid = pair.first;
+    hb_codepoint_t old_gid = pair.second;
+    glyf_impl::SubsetGlyph *p = glyphs.push ();
+    glyf_impl::SubsetGlyph& subset_glyph = *p;
+    subset_glyph.old_gid = old_gid;
 
-    if (unlikely (new_gid == 0 &&
+    if (unlikely (old_gid == 0 && new_gid == 0 &&
                   !(plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE)) &&
                   !plan->normalized_coords)
       subset_glyph.source_glyph = glyf_impl::Glyph ();
@@ -487,7 +487,7 @@
   {
     hb_variation_t var;
     var.tag = _.first;
-    var.value = _.second;
+    var.value = _.second.middle;
     vars.push (var);
   }
 
diff --git a/src/java.desktop/share/native/libharfbuzz/OT/glyf/path-builder.hh b/src/java.desktop/share/native/libharfbuzz/OT/glyf/path-builder.hh
index 6a47620..d56ea3e 100644
--- a/src/java.desktop/share/native/libharfbuzz/OT/glyf/path-builder.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/glyf/path-builder.hh
@@ -21,19 +21,15 @@
     operator bool () const { return has_data; }
 
     bool has_data = false;
-    float x = 0.;
-    float y = 0.;
+    float x;
+    float y;
 
-    optional_point_t lerp (optional_point_t p, float t)
-    { return optional_point_t (x + t * (p.x - x), y + t * (p.y - y)); }
+    optional_point_t mid (optional_point_t p)
+    { return optional_point_t ((x + p.x) * 0.5f, (y + p.y) * 0.5f); }
   } first_oncurve, first_offcurve, first_offcurve2, last_offcurve, last_offcurve2;
 
-  path_builder_t (hb_font_t *font_, hb_draw_session_t &draw_session_)
-  {
-    font = font_;
-    draw_session = &draw_session_;
-    first_oncurve = first_offcurve = first_offcurve2 = last_offcurve = last_offcurve2 = optional_point_t ();
-  }
+  path_builder_t (hb_font_t *font_, hb_draw_session_t &draw_session_) :
+    font (font_), draw_session (&draw_session_) {}
 
   /* based on https://github.com/RazrFalcon/ttf-parser/blob/4f32821/src/glyf.rs#L287
      See also:
@@ -41,6 +37,7 @@
      * https://stackoverflow.com/a/20772557
      *
      * Cubic support added. */
+  HB_ALWAYS_INLINE
   void consume_point (const contour_point_t &point)
   {
     bool is_on_curve = point.flag & glyf_impl::SimpleGlyph::FLAG_ON_CURVE;
@@ -50,7 +47,7 @@
     bool is_cubic = !is_on_curve && (point.flag & glyf_impl::SimpleGlyph::FLAG_CUBIC);
 #endif
     optional_point_t p (font->em_fscalef_x (point.x), font->em_fscalef_y (point.y));
-    if (!first_oncurve)
+    if (unlikely (!first_oncurve))
     {
       if (is_on_curve)
       {
@@ -66,7 +63,7 @@
         }
         else if (first_offcurve)
         {
-          optional_point_t mid = first_offcurve.lerp (p, .5f);
+          optional_point_t mid = first_offcurve.mid (p);
           first_oncurve = mid;
           last_offcurve = p;
           draw_session->move_to (mid.x, mid.y);
@@ -102,7 +99,7 @@
           }
           else
           {
-            optional_point_t mid = last_offcurve.lerp (p, .5f);
+            optional_point_t mid = last_offcurve.mid (p);
 
             if (is_cubic)
             {
@@ -127,13 +124,13 @@
       }
     }
 
-    if (point.is_end_point)
+    if (unlikely (point.is_end_point))
     {
       if (first_offcurve && last_offcurve)
       {
-        optional_point_t mid = last_offcurve.lerp (first_offcurve2 ?
-                                                   first_offcurve2 :
-                                                   first_offcurve, .5f);
+        optional_point_t mid = last_offcurve.mid (first_offcurve2 ?
+                                                  first_offcurve2 :
+                                                  first_offcurve);
         if (last_offcurve2)
           draw_session->cubic_to (last_offcurve2.x, last_offcurve2.y,
                                   last_offcurve.x, last_offcurve.y,
diff --git a/src/java.desktop/share/native/libharfbuzz/OT/name/name.hh b/src/java.desktop/share/native/libharfbuzz/OT/name/name.hh
index 15ff7a8..f14c2da 100644
--- a/src/java.desktop/share/native/libharfbuzz/OT/name/name.hh
+++ b/src/java.desktop/share/native/libharfbuzz/OT/name/name.hh
@@ -359,7 +359,7 @@
       record.nameID = ids.name_id;
       record.length = 0; // handled in NameRecord copy()
       record.offset = 0;
-      memcpy (name_records, &record, NameRecord::static_size);
+      hb_memcpy (name_records, &record, NameRecord::static_size);
       name_records++;
     }
 #endif
@@ -384,10 +384,7 @@
 
   bool subset (hb_subset_context_t *c) const
   {
-    TRACE_SUBSET (this);
-
-    name *name_prime = c->serializer->start_embed<name> ();
-    if (unlikely (!name_prime)) return_trace (false);
+    auto *name_prime = c->serializer->start_embed<name> ();
 
 #ifdef HB_EXPERIMENTAL_API
     const hb_hashmap_t<hb_ot_name_record_ids_t, hb_bytes_t> *name_table_overrides =
@@ -436,7 +433,7 @@
     if (!name_table_overrides->is_empty ())
     {
       if (unlikely (!insert_name_records.alloc (name_table_overrides->get_population (), true)))
-        return_trace (false);
+        return false;
       for (const auto& record_ids : name_table_overrides->keys ())
       {
         if (name_table_overrides->get (record_ids).length == 0)
@@ -448,13 +445,13 @@
     }
 #endif
 
-    return (name_prime->serialize (c->serializer, it,
-                                   std::addressof (this + stringOffset)
+    return name_prime->serialize (c->serializer, it,
+                                  std::addressof (this + stringOffset)
 #ifdef HB_EXPERIMENTAL_API
-                                   , insert_name_records
-                                   , name_table_overrides
+                                  , insert_name_records
+                                  , name_table_overrides
 #endif
-                                   ));
+                                  );
   }
 
   bool sanitize_records (hb_sanitize_context_t *c) const
diff --git a/src/java.desktop/share/native/libharfbuzz/UPDATING.txt b/src/java.desktop/share/native/libharfbuzz/UPDATING.txt
index 6b4e7cc..3f72983 100644
--- a/src/java.desktop/share/native/libharfbuzz/UPDATING.txt
+++ b/src/java.desktop/share/native/libharfbuzz/UPDATING.txt
@@ -106,7 +106,7 @@
   Look for manual related layout jtreg tests (test/jdk/java/awt/font/TextLayout)
   and run on Windows,Linux and Mac.
   Use Font2DTest set to TextLayout and check the above languages. Probably
-  not going to see layout problems a code point at a time but it needs to
+  not going to see layout problems in code at this point of time but it needs to
   be checked.
 
   Different unicode combinations can be checked using Font2DTest.
diff --git a/src/java.desktop/share/native/libharfbuzz/graph/classdef-graph.hh b/src/java.desktop/share/native/libharfbuzz/graph/classdef-graph.hh
index c2e24a7..c143288 100644
--- a/src/java.desktop/share/native/libharfbuzz/graph/classdef-graph.hh
+++ b/src/java.desktop/share/native/libharfbuzz/graph/classdef-graph.hh
@@ -72,7 +72,7 @@
     class_def_link->width = SmallTypes::size;
     class_def_link->objidx = class_def_prime_id;
     class_def_link->position = link_position;
-    class_def_prime_vertex.parents.push (parent_id);
+    class_def_prime_vertex.add_parent (parent_id);
 
     return true;
   }
@@ -94,7 +94,13 @@
     }
 
     hb_bytes_t class_def_copy = serializer.copy_bytes ();
-    c.add_buffer ((char *) class_def_copy.arrayZ); // Give ownership to the context, it will cleanup the buffer.
+    if (!class_def_copy.arrayZ) return false;
+    // Give ownership to the context, it will cleanup the buffer.
+    if (!c.add_buffer ((char *) class_def_copy.arrayZ))
+    {
+      hb_free ((char *) class_def_copy.arrayZ);
+      return false;
+    }
 
     auto& obj = c.graph.vertices_[dest_obj].obj;
     obj.head = (char *) class_def_copy.arrayZ;
diff --git a/src/java.desktop/share/native/libharfbuzz/graph/coverage-graph.hh b/src/java.desktop/share/native/libharfbuzz/graph/coverage-graph.hh
index 49d0936..4f44e07 100644
--- a/src/java.desktop/share/native/libharfbuzz/graph/coverage-graph.hh
+++ b/src/java.desktop/share/native/libharfbuzz/graph/coverage-graph.hh
@@ -96,7 +96,7 @@
     coverage_link->width = SmallTypes::size;
     coverage_link->objidx = coverage_prime_id;
     coverage_link->position = link_position;
-    coverage_prime_vertex.parents.push (parent_id);
+    coverage_prime_vertex.add_parent (parent_id);
 
     return (Coverage*) coverage_prime_vertex.obj.head;
   }
@@ -118,7 +118,13 @@
     }
 
     hb_bytes_t coverage_copy = serializer.copy_bytes ();
-    c.add_buffer ((char *) coverage_copy.arrayZ); // Give ownership to the context, it will cleanup the buffer.
+    if (!coverage_copy.arrayZ) return false;
+    // Give ownership to the context, it will cleanup the buffer.
+    if (!c.add_buffer ((char *) coverage_copy.arrayZ))
+    {
+      hb_free ((char *) coverage_copy.arrayZ);
+      return false;
+    }
 
     auto& obj = c.graph.vertices_[dest_obj].obj;
     obj.head = (char *) coverage_copy.arrayZ;
diff --git a/src/java.desktop/share/native/libharfbuzz/graph/graph.hh b/src/java.desktop/share/native/libharfbuzz/graph/graph.hh
index 38ca5db..4a1f7eb 100644
--- a/src/java.desktop/share/native/libharfbuzz/graph/graph.hh
+++ b/src/java.desktop/share/native/libharfbuzz/graph/graph.hh
@@ -43,12 +43,28 @@
   {
     hb_serialize_context_t::object_t obj;
     int64_t distance = 0 ;
-    int64_t space = 0 ;
-    hb_vector_t<unsigned> parents;
+    unsigned space = 0 ;
     unsigned start = 0;
     unsigned end = 0;
     unsigned priority = 0;
+    private:
+    unsigned incoming_edges_ = 0;
+    unsigned single_parent = (unsigned) -1;
+    hb_hashmap_t<unsigned, unsigned> parents;
+    public:
 
+    auto parents_iter () const HB_AUTO_RETURN
+    (
+      hb_concat (
+        hb_iter (&single_parent, single_parent != (unsigned) -1),
+        parents.keys_ref ()
+      )
+    )
+
+    bool in_error () const
+    {
+      return parents.in_error ();
+    }
 
     bool link_positions_valid (unsigned num_objects, bool removed_nil)
     {
@@ -143,7 +159,9 @@
       hb_swap (a.obj, b.obj);
       hb_swap (a.distance, b.distance);
       hb_swap (a.space, b.space);
+      hb_swap (a.single_parent, b.single_parent);
       hb_swap (a.parents, b.parents);
+      hb_swap (a.incoming_edges_, b.incoming_edges_);
       hb_swap (a.start, b.start);
       hb_swap (a.end, b.end);
       hb_swap (a.priority, b.priority);
@@ -154,6 +172,7 @@
     {
       hb_hashmap_t<unsigned, unsigned> result;
 
+      result.alloc (obj.real_links.length);
       for (const auto& l : obj.real_links) {
         result.set (l.position, l.objidx);
       }
@@ -163,27 +182,83 @@
 
     bool is_shared () const
     {
-      return parents.length > 1;
+      return parents.get_population () > 1;
     }
 
     unsigned incoming_edges () const
     {
-      return parents.length;
+      if (HB_DEBUG_SUBSET_REPACK)
+       {
+        assert (incoming_edges_ == (single_parent != (unsigned) -1) +
+                (parents.values_ref () | hb_reduce (hb_add, 0)));
+       }
+      return incoming_edges_;
+    }
+
+    void reset_parents ()
+    {
+      incoming_edges_ = 0;
+      single_parent = (unsigned) -1;
+      parents.reset ();
+    }
+
+    void add_parent (unsigned parent_index)
+    {
+      assert (parent_index != (unsigned) -1);
+      if (incoming_edges_ == 0)
+      {
+        single_parent = parent_index;
+        incoming_edges_ = 1;
+        return;
+      }
+      else if (single_parent != (unsigned) -1)
+      {
+        assert (incoming_edges_ == 1);
+        if (!parents.set (single_parent, 1))
+          return;
+        single_parent = (unsigned) -1;
+      }
+
+      unsigned *v;
+      if (parents.has (parent_index, &v))
+      {
+        (*v)++;
+        incoming_edges_++;
+      }
+      else if (parents.set (parent_index, 1))
+        incoming_edges_++;
     }
 
     void remove_parent (unsigned parent_index)
     {
-      for (unsigned i = 0; i < parents.length; i++)
+      if (parent_index == single_parent)
       {
-        if (parents[i] != parent_index) continue;
-        parents.remove_unordered (i);
-        break;
+        single_parent = (unsigned) -1;
+        incoming_edges_--;
+        return;
+      }
+
+      unsigned *v;
+      if (parents.has (parent_index, &v))
+      {
+        incoming_edges_--;
+        if (*v > 1)
+          (*v)--;
+        else
+          parents.del (parent_index);
+
+        if (incoming_edges_ == 1)
+        {
+          single_parent = *parents.keys ();
+          parents.reset ();
+        }
       }
     }
 
     void remove_real_link (unsigned child_index, const void* offset)
     {
-      for (unsigned i = 0; i < obj.real_links.length; i++)
+      unsigned count = obj.real_links.length;
+      for (unsigned i = 0; i < count; i++)
       {
         auto& link = obj.real_links.arrayZ[i];
         if (link.objidx != child_index)
@@ -197,18 +272,53 @@
       }
     }
 
-    void remap_parents (const hb_vector_t<unsigned>& id_map)
+    bool remap_parents (const hb_vector_t<unsigned>& id_map)
     {
-      for (unsigned i = 0; i < parents.length; i++)
-        parents[i] = id_map[parents[i]];
+      if (single_parent != (unsigned) -1)
+      {
+        assert (single_parent < id_map.length);
+        single_parent = id_map[single_parent];
+        return true;
+      }
+
+      hb_hashmap_t<unsigned, unsigned> new_parents;
+      new_parents.alloc (parents.get_population ());
+      for (auto _ : parents)
+      {
+        assert (_.first < id_map.length);
+        assert (!new_parents.has (id_map[_.first]));
+        new_parents.set (id_map[_.first], _.second);
+      }
+
+      if (parents.in_error() || new_parents.in_error ())
+        return false;
+
+      parents = std::move (new_parents);
+      return true;
     }
 
     void remap_parent (unsigned old_index, unsigned new_index)
     {
-      for (unsigned i = 0; i < parents.length; i++)
+      if (single_parent != (unsigned) -1)
       {
-        if (parents[i] == old_index)
-          parents[i] = new_index;
+        if (single_parent == old_index)
+          single_parent = new_index;
+        return;
+      }
+
+      const unsigned *pv;
+      if (parents.has (old_index, &pv))
+      {
+        unsigned v = *pv;
+        if (!parents.set (new_index, v))
+          incoming_edges_ -= v;
+        parents.del (old_index);
+
+        if (incoming_edges_ == 1)
+        {
+          single_parent = *parents.keys ();
+          parents.reset ();
+        }
       }
     }
 
@@ -328,11 +438,12 @@
     bool removed_nil = false;
     vertices_.alloc (objects.length);
     vertices_scratch_.alloc (objects.length);
-    for (unsigned i = 0; i < objects.length; i++)
+    unsigned count = objects.length;
+    for (unsigned i = 0; i < count; i++)
     {
       // If this graph came from a serialization buffer object 0 is the
       // nil object. We don't need it for our purposes here so drop it.
-      if (i == 0 && !objects[i])
+      if (i == 0 && !objects.arrayZ[i])
       {
         removed_nil = true;
         continue;
@@ -340,9 +451,9 @@
 
       vertex_t* v = vertices_.push ();
       if (check_success (!vertices_.in_error ()))
-        v->obj = *objects[i];
+        v->obj = *objects.arrayZ[i];
 
-      check_success (v->link_positions_valid (objects.length, removed_nil));
+      check_success (v->link_positions_valid (count, removed_nil));
 
       if (!removed_nil) continue;
       // Fix indices to account for removed nil object.
@@ -354,7 +465,6 @@
 
   ~graph_t ()
   {
-    vertices_.fini ();
     for (char* b : buffers)
       hb_free (b);
   }
@@ -364,6 +474,18 @@
     return root ().equals (other.root (), *this, other, 0);
   }
 
+  void print () const {
+    for (int i = vertices_.length - 1; i >= 0; i--)
+    {
+      const auto& v = vertices_[i];
+      printf("%d: %u [", i, (unsigned int)v.table_size());
+      for (const auto &l : v.obj.real_links) {
+        printf("%u, ", l.objidx);
+      }
+      printf("]\n");
+    }
+  }
+
   // Sorts links of all objects in a consistent manner and zeroes all offsets.
   void normalize ()
   {
@@ -396,9 +518,10 @@
     return vertices_[i].obj;
   }
 
-  void add_buffer (char* buffer)
+  bool add_buffer (char* buffer)
   {
     buffers.push (buffer);
+    return !buffers.in_error ();
   }
 
   /*
@@ -414,7 +537,7 @@
     link->width = 2;
     link->objidx = child_id;
     link->position = (char*) offset - (char*) v.obj.head;
-    vertices_[child_id].parents.push (parent_id);
+    vertices_[child_id].add_parent (parent_id);
   }
 
   /*
@@ -443,7 +566,7 @@
 
     update_distances ();
 
-    hb_priority_queue_t queue;
+    hb_priority_queue_t<int64_t> queue;
     hb_vector_t<vertex_t> &sorted_graph = vertices_scratch_;
     if (unlikely (!check_success (sorted_graph.resize (vertices_.length)))) return;
     hb_vector_t<unsigned> id_map;
@@ -460,7 +583,7 @@
     {
       unsigned next_id = queue.pop_minimum().second;
 
-      hb_swap (sorted_graph[new_id], vertices_[next_id]);
+      sorted_graph[new_id] = std::move (vertices_[next_id]);
       const vertex_t& next = sorted_graph[new_id];
 
       if (unlikely (!check_success(new_id >= 0))) {
@@ -488,8 +611,8 @@
     check_success (!queue.in_error ());
     check_success (!sorted_graph.in_error ());
 
-    remap_all_obj_indices (id_map, &sorted_graph);
-    hb_swap (vertices_, sorted_graph);
+    check_success (remap_all_obj_indices (id_map, &sorted_graph));
+    vertices_ = std::move (sorted_graph);
 
     if (!check_success (new_id == -1))
       print_orphaned_nodes ();
@@ -579,8 +702,8 @@
     const auto& node = object (node_idx);
     if (offset < node.head || offset >= node.tail) return -1;
 
-    unsigned length = node.real_links.length;
-    for (unsigned i = 0; i < length; i++)
+    unsigned count = node.real_links.length;
+    for (unsigned i = 0; i < count; i++)
     {
       // Use direct access for increased performance, this is a hot method.
       const auto& link = node.real_links.arrayZ[i];
@@ -600,7 +723,7 @@
   {
     unsigned child_idx = index_for_offset (node_idx, offset);
     auto& child = vertices_[child_idx];
-    for (unsigned p : child.parents)
+    for (unsigned p : child.parents_iter ())
     {
       if (p != node_idx) {
         return duplicate (node_idx, child_idx);
@@ -683,12 +806,15 @@
       subgraph.set (root_idx, wide_parents (root_idx, parents));
       find_subgraph (root_idx, subgraph);
     }
+    if (subgraph.in_error ())
+      return false;
 
     unsigned original_root_idx = root_idx ();
     hb_map_t index_map;
     bool made_changes = false;
     for (auto entry : subgraph.iter ())
     {
+      assert (entry.first < vertices_.length);
       const auto& node = vertices_[entry.first];
       unsigned subgraph_incoming_edges = entry.second;
 
@@ -727,8 +853,7 @@
     remap_obj_indices (index_map, parents.iter (), true);
 
     // Update roots set with new indices as needed.
-    uint32_t next = HB_SET_VALUE_INVALID;
-    while (roots.next (&next))
+    for (auto next : roots)
     {
       const uint32_t *v;
       if (index_map.has (next, &v))
@@ -745,10 +870,10 @@
   {
     for (const auto& link : vertices_[node_idx].obj.all_links ())
     {
-      const uint32_t *v;
+      hb_codepoint_t *v;
       if (subgraph.has (link.objidx, &v))
       {
-        subgraph.set (link.objidx, *v + 1);
+        (*v)++;
         continue;
       }
       subgraph.set (link.objidx, 1);
@@ -820,7 +945,7 @@
     new_link->position = (const char*) new_offset - (const char*) new_v.obj.head;
 
     auto& child = vertices_[child_id];
-    child.parents.push (new_parent_idx);
+    child.add_parent (new_parent_idx);
 
     old_v.remove_real_link (child_id, old_offset);
     child.remove_parent (old_parent_idx);
@@ -864,18 +989,18 @@
     clone->obj.tail = child.obj.tail;
     clone->distance = child.distance;
     clone->space = child.space;
-    clone->parents.reset ();
+    clone->reset_parents ();
 
     unsigned clone_idx = vertices_.length - 2;
     for (const auto& l : child.obj.real_links)
     {
       clone->obj.real_links.push (l);
-      vertices_[l.objidx].parents.push (clone_idx);
+      vertices_[l.objidx].add_parent (clone_idx);
     }
     for (const auto& l : child.obj.virtual_links)
     {
       clone->obj.virtual_links.push (l);
-      vertices_[l.objidx].parents.push (clone_idx);
+      vertices_[l.objidx].add_parent (clone_idx);
     }
 
     check_success (!clone->obj.real_links.in_error ());
@@ -1004,13 +1129,13 @@
   {
     update_parents();
 
-    if (root().parents)
+    if (root().incoming_edges ())
       // Root cannot have parents.
       return false;
 
     for (unsigned i = 0; i < root_idx (); i++)
     {
-      if (!vertices_[i].parents)
+      if (!vertices_[i].incoming_edges ())
         return false;
     }
     return true;
@@ -1074,14 +1199,14 @@
     parents_invalid = true;
     update_parents();
 
-    if (root().parents) {
+    if (root().incoming_edges ()) {
       DEBUG_MSG (SUBSET_REPACK, nullptr, "Root node has incoming edges.");
     }
 
     for (unsigned i = 0; i < root_idx (); i++)
     {
       const auto& v = vertices_[i];
-      if (!v.parents)
+      if (!v.incoming_edges ())
         DEBUG_MSG (SUBSET_REPACK, nullptr, "Node %u is orphaned.", i);
     }
   }
@@ -1113,6 +1238,8 @@
 
   unsigned space_for (unsigned index, unsigned* root = nullptr) const
   {
+  loop:
+    assert (index < vertices_.length);
     const auto& node = vertices_[index];
     if (node.space)
     {
@@ -1121,22 +1248,24 @@
       return node.space;
     }
 
-    if (!node.parents)
+    if (!node.incoming_edges ())
     {
       if (root)
         *root = index;
       return 0;
     }
 
-    return space_for (node.parents[0], root);
+    index = *node.parents_iter ();
+    goto loop;
   }
 
   void err_other_error () { this->successful = false; }
 
   size_t total_size_in_bytes () const {
     size_t total_size = 0;
-    for (unsigned i = 0; i < vertices_.length; i++) {
-      size_t size = vertices_[i].obj.tail - vertices_[i].obj.head;
+    unsigned count = vertices_.length;
+    for (unsigned i = 0; i < count; i++) {
+      size_t size = vertices_.arrayZ[i].obj.tail - vertices_.arrayZ[i].obj.head;
       total_size += size;
     }
     return total_size;
@@ -1151,12 +1280,8 @@
   unsigned wide_parents (unsigned node_idx, hb_set_t& parents) const
   {
     unsigned count = 0;
-    hb_set_t visited;
-    for (unsigned p : vertices_[node_idx].parents)
+    for (unsigned p : vertices_[node_idx].parents_iter ())
     {
-      if (visited.has (p)) continue;
-      visited.add (p);
-
       // Only real links can be wide
       for (const auto& l : vertices_[p].obj.real_links)
       {
@@ -1183,21 +1308,21 @@
   {
     if (!parents_invalid) return;
 
-    for (unsigned i = 0; i < vertices_.length; i++)
-      vertices_[i].parents.reset ();
+    unsigned count = vertices_.length;
 
-    for (unsigned p = 0; p < vertices_.length; p++)
+    for (unsigned i = 0; i < count; i++)
+      vertices_.arrayZ[i].reset_parents ();
+
+    for (unsigned p = 0; p < count; p++)
     {
-      for (auto& l : vertices_[p].obj.all_links ())
-      {
-        vertices_[l.objidx].parents.push (p);
-      }
+      for (auto& l : vertices_.arrayZ[p].obj.all_links ())
+        vertices_[l.objidx].add_parent (p);
     }
 
-    for (unsigned i = 0; i < vertices_.length; i++)
+    for (unsigned i = 0; i < count; i++)
       // parents arrays must be accurate or downstream operations like cycle detection
       // and sorting won't work correctly.
-      check_success (!vertices_[i].parents.in_error ());
+      check_success (!vertices_.arrayZ[i].in_error ());
 
     parents_invalid = false;
   }
@@ -1239,15 +1364,12 @@
     // According to https://www3.cs.stonybrook.edu/~rezaul/papers/TR-07-54.pdf
     // for practical performance this is faster then using a more advanced queue
     // (such as a fibonacci queue) with a fast decrease priority.
-    for (unsigned i = 0; i < vertices_.length; i++)
-    {
-      if (i == vertices_.length - 1)
-        vertices_[i].distance = 0;
-      else
-        vertices_[i].distance = hb_int_max (int64_t);
-    }
+    unsigned count = vertices_.length;
+    for (unsigned i = 0; i < count; i++)
+      vertices_.arrayZ[i].distance = hb_int_max (int64_t);
+    vertices_.tail ().distance = 0;
 
-    hb_priority_queue_t queue;
+    hb_priority_queue_t<int64_t> queue;
     queue.insert (0, vertices_.length - 1);
 
     hb_vector_t<bool> visited;
@@ -1265,15 +1387,15 @@
       {
         if (visited[link.objidx]) continue;
 
-        const auto& child = vertices_[link.objidx].obj;
+        const auto& child = vertices_.arrayZ[link.objidx].obj;
         unsigned link_width = link.width ? link.width : 4; // treat virtual offsets as 32 bits wide
         int64_t child_weight = (child.tail - child.head) +
-                               ((int64_t) 1 << (link_width * 8)) * (vertices_[link.objidx].space + 1);
+                               ((int64_t) 1 << (link_width * 8)) * (vertices_.arrayZ[link.objidx].space + 1);
         int64_t child_distance = next_distance + child_weight;
 
-        if (child_distance < vertices_[link.objidx].distance)
+        if (child_distance < vertices_.arrayZ[link.objidx].distance)
         {
-          vertices_[link.objidx].distance = child_distance;
+          vertices_.arrayZ[link.objidx].distance = child_distance;
           queue.insert (child_distance, link.objidx);
         }
       }
@@ -1301,7 +1423,7 @@
     unsigned old_idx = link.objidx;
     link.objidx = new_idx;
     vertices_[old_idx].remove_parent (parent_idx);
-    vertices_[new_idx].parents.push (parent_idx);
+    vertices_[new_idx].add_parent (parent_idx);
   }
 
   /*
@@ -1329,17 +1451,20 @@
   /*
    * Updates all objidx's in all links using the provided mapping.
    */
-  void remap_all_obj_indices (const hb_vector_t<unsigned>& id_map,
+  bool remap_all_obj_indices (const hb_vector_t<unsigned>& id_map,
                               hb_vector_t<vertex_t>* sorted_graph) const
   {
-    for (unsigned i = 0; i < sorted_graph->length; i++)
+    unsigned count = sorted_graph->length;
+    for (unsigned i = 0; i < count; i++)
     {
-      (*sorted_graph)[i].remap_parents (id_map);
-      for (auto& link : (*sorted_graph)[i].obj.all_links_writer ())
+      if (!(*sorted_graph)[i].remap_parents (id_map))
+        return false;
+      for (auto& link : sorted_graph->arrayZ[i].obj.all_links_writer ())
       {
         link.objidx = id_map[link.objidx];
       }
     }
+    return true;
   }
 
   /*
@@ -1370,7 +1495,7 @@
     for (const auto& l : v.obj.all_links ())
       find_connected_nodes (l.objidx, targets, visited, connected);
 
-    for (unsigned p : v.parents)
+    for (unsigned p : v.parents_iter ())
       find_connected_nodes (p, targets, visited, connected);
   }
 
diff --git a/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-context.cc b/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-context.cc
index b204442..d66eb49 100644
--- a/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-context.cc
+++ b/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-context.cc
@@ -52,7 +52,11 @@
   if (!buffer)
     return -1;
 
-  add_buffer (buffer);
+  if (!add_buffer (buffer)) {
+    // Allocation did not get stored for freeing later.
+    hb_free (buffer);
+    return -1;
+  }
 
   return graph.new_node (buffer, buffer + size);
 }
diff --git a/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-context.hh b/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-context.hh
index 9fe9662..b25d538 100644
--- a/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-context.hh
+++ b/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-context.hh
@@ -40,16 +40,16 @@
   graph_t& graph;
   unsigned lookup_list_index;
   hb_hashmap_t<unsigned, graph::Lookup*> lookups;
-
+  hb_hashmap_t<unsigned, unsigned> subtable_to_extension;
 
   HB_INTERNAL gsubgpos_graph_context_t (hb_tag_t table_tag_,
                                         graph_t& graph_);
 
   HB_INTERNAL unsigned create_node (unsigned size);
 
-  void add_buffer (char* buffer)
+  bool add_buffer (char* buffer)
   {
-    graph.add_buffer (buffer);
+    return graph.add_buffer (buffer);
   }
 
  private:
diff --git a/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-graph.hh b/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-graph.hh
index c170638..a5f9223 100644
--- a/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-graph.hh
+++ b/src/java.desktop/share/native/libharfbuzz/graph/gsubgpos-graph.hh
@@ -166,7 +166,7 @@
     }
 
     if (all_new_subtables) {
-      add_sub_tables (c, this_index, type, all_new_subtables);
+      return add_sub_tables (c, this_index, type, all_new_subtables);
     }
 
     return true;
@@ -184,7 +184,7 @@
     return sub_table->split_subtables (c, parent_idx, objidx);
   }
 
-  void add_sub_tables (gsubgpos_graph_context_t& c,
+  bool add_sub_tables (gsubgpos_graph_context_t& c,
                        unsigned this_index,
                        unsigned type,
                        hb_vector_t<hb_pair_t<unsigned, hb_vector_t<unsigned>>>& subtable_ids)
@@ -200,7 +200,12 @@
     size_t new_size = v.table_size ()
                       + new_subtable_count * OT::Offset16::static_size;
     char* buffer = (char*) hb_calloc (1, new_size);
-    c.add_buffer (buffer);
+    if (!buffer) return false;
+    if (!c.add_buffer (buffer))
+    {
+      hb_free (buffer);
+     return false;
+    }
     hb_memcpy (buffer, v.obj.head, v.table_size());
 
     v.obj.head = buffer;
@@ -220,7 +225,7 @@
         if (is_ext)
         {
           unsigned ext_id = create_extension_subtable (c, subtable_id, type);
-          c.graph.vertices_[subtable_id].parents.push (ext_id);
+          c.graph.vertices_[subtable_id].add_parent (ext_id);
           subtable_id = ext_id;
         }
 
@@ -229,7 +234,7 @@
         link->objidx = subtable_id;
         link->position = (char*) &new_lookup->subTable[offset_index++] -
                          (char*) new_lookup;
-        c.graph.vertices_[subtable_id].parents.push (this_index);
+        c.graph.vertices_[subtable_id].add_parent (this_index);
       }
     }
 
@@ -239,6 +244,7 @@
     // The head location of the lookup has changed, invalidating the lookups map entry
     // in the context. Update the map.
     c.lookups.set (this_index, new_lookup);
+    return true;
   }
 
   void fix_existing_subtable_links (gsubgpos_graph_context_t& c,
@@ -293,24 +299,35 @@
                                 unsigned subtable_index)
   {
     unsigned type = lookupType;
+    unsigned ext_index = -1;
+    unsigned* existing_ext_index = nullptr;
+    if (c.subtable_to_extension.has(subtable_index, &existing_ext_index)) {
+      ext_index = *existing_ext_index;
+    } else {
+      ext_index = create_extension_subtable(c, subtable_index, type);
+      c.subtable_to_extension.set(subtable_index, ext_index);
+    }
 
-    unsigned ext_index = create_extension_subtable(c, subtable_index, type);
     if (ext_index == (unsigned) -1)
       return false;
 
+    auto& subtable_vertex = c.graph.vertices_[subtable_index];
     auto& lookup_vertex = c.graph.vertices_[lookup_index];
     for (auto& l : lookup_vertex.obj.real_links.writer ())
     {
-      if (l.objidx == subtable_index)
+      if (l.objidx == subtable_index) {
         // Change lookup to point at the extension.
         l.objidx = ext_index;
+        if (existing_ext_index)
+          subtable_vertex.remove_parent(lookup_index);
+      }
     }
 
     // Make extension point at the subtable.
     auto& ext_vertex = c.graph.vertices_[ext_index];
-    auto& subtable_vertex = c.graph.vertices_[subtable_index];
-    ext_vertex.parents.push (lookup_index);
-    subtable_vertex.remap_parent (lookup_index, ext_index);
+    ext_vertex.add_parent (lookup_index);
+    if (!existing_ext_index)
+      subtable_vertex.remap_parent (lookup_index, ext_index);
 
     return true;
   }
diff --git a/src/java.desktop/share/native/libharfbuzz/graph/markbasepos-graph.hh b/src/java.desktop/share/native/libharfbuzz/graph/markbasepos-graph.hh
index 84ef5f7..ae5ebd0 100644
--- a/src/java.desktop/share/native/libharfbuzz/graph/markbasepos-graph.hh
+++ b/src/java.desktop/share/native/libharfbuzz/graph/markbasepos-graph.hh
@@ -217,7 +217,7 @@
 
     const unsigned base_coverage_id = c.graph.index_for_offset (this_index, &baseCoverage);
     const unsigned base_size =
-        OT::Layout::GPOS_impl::PairPosFormat1_3<SmallTypes>::min_size +
+        OT::Layout::GPOS_impl::MarkBasePosFormat1_2<SmallTypes>::min_size +
         MarkArray::min_size +
         AnchorMatrix::min_size +
         c.graph.vertices_[base_coverage_id].table_size ();
@@ -318,8 +318,11 @@
   {
     hb_vector_t<class_info_t> class_to_info;
 
-    unsigned class_count= classCount;
-    class_to_info.resize (class_count);
+    unsigned class_count = classCount;
+    if (!class_count) return class_to_info;
+
+    if (!class_to_info.resize (class_count))
+      return hb_vector_t<class_info_t>();
 
     auto mark_array = c.graph.as_table<MarkArray> (this_index, &markArray);
     if (!mark_array) return hb_vector_t<class_info_t> ();
@@ -327,6 +330,7 @@
     for (unsigned mark = 0; mark < mark_count; mark++)
     {
       unsigned klass = (*mark_array.table)[mark].get_class ();
+      if (klass >= class_count) continue;
       class_to_info[klass].marks.add (mark);
     }
 
@@ -335,6 +339,7 @@
       unsigned mark = (link.position - 2) /
                      OT::Layout::GPOS_impl::MarkRecord::static_size;
       unsigned klass = (*mark_array.table)[mark].get_class ();
+      if (klass >= class_count) continue;
       class_to_info[klass].child_indices.push (link.objidx);
     }
 
@@ -479,7 +484,7 @@
       return ((MarkBasePosFormat1*)(&u.format1))->split_subtables (c, parent_index, this_index);
 #ifndef HB_NO_BEYOND_64K
     case 2: HB_FALLTHROUGH;
-      // Don't split 24bit PairPos's.
+      // Don't split 24bit MarkBasePos's.
 #endif
     default:
       return hb_vector_t<unsigned> ();
diff --git a/src/java.desktop/share/native/libharfbuzz/graph/pairpos-graph.hh b/src/java.desktop/share/native/libharfbuzz/graph/pairpos-graph.hh
index 1c13eb2..ad158cc 100644
--- a/src/java.desktop/share/native/libharfbuzz/graph/pairpos-graph.hh
+++ b/src/java.desktop/share/native/libharfbuzz/graph/pairpos-graph.hh
@@ -215,7 +215,7 @@
     auto gid_and_class =
         + coverage->iter ()
         | hb_map_retains_sorting ([&] (hb_codepoint_t gid) {
-          return hb_pair_t<hb_codepoint_t, hb_codepoint_t> (gid, class_def_1->get_class (gid));
+          return hb_codepoint_pair_t (gid, class_def_1->get_class (gid));
         })
         ;
     class_def_size_estimator_t estimator (gid_and_class);
@@ -386,14 +386,14 @@
     auto klass_map =
     + coverage_table->iter ()
     | hb_map_retains_sorting ([&] (hb_codepoint_t gid) {
-      return hb_pair_t<hb_codepoint_t, hb_codepoint_t> (gid, class_def_1_table->get_class (gid));
+      return hb_codepoint_pair_t (gid, class_def_1_table->get_class (gid));
     })
     | hb_filter ([&] (hb_codepoint_t klass) {
       return klass >= start && klass < end;
     }, hb_second)
-    | hb_map_retains_sorting ([&] (hb_pair_t<hb_codepoint_t, hb_codepoint_t> gid_and_class) {
+    | hb_map_retains_sorting ([&] (hb_codepoint_pair_t gid_and_class) {
       // Classes must be from 0...N so subtract start
-      return hb_pair_t<hb_codepoint_t, hb_codepoint_t> (gid_and_class.first, gid_and_class.second - start);
+      return hb_codepoint_pair_t (gid_and_class.first, gid_and_class.second - start);
     })
     ;
 
@@ -419,7 +419,7 @@
     class_def_link->width = SmallTypes::size;
     class_def_link->objidx = class_def_2_id;
     class_def_link->position = 10;
-    graph.vertices_[class_def_2_id].parents.push (pair_pos_prime_id);
+    graph.vertices_[class_def_2_id].add_parent (pair_pos_prime_id);
     graph.duplicate (pair_pos_prime_id, class_def_2_id);
 
     return pair_pos_prime_id;
@@ -519,7 +519,7 @@
     auto klass_map =
     + coverage.table->iter ()
     | hb_map_retains_sorting ([&] (hb_codepoint_t gid) {
-      return hb_pair_t<hb_codepoint_t, hb_codepoint_t> (gid, class_def_1.table->get_class (gid));
+      return hb_codepoint_pair_t (gid, class_def_1.table->get_class (gid));
     })
     | hb_filter ([&] (hb_codepoint_t klass) {
       return klass < count;
diff --git a/src/java.desktop/share/native/libharfbuzz/graph/serialize.hh b/src/java.desktop/share/native/libharfbuzz/graph/serialize.hh
index 040fd1d..06e4bf4 100644
--- a/src/java.desktop/share/native/libharfbuzz/graph/serialize.hh
+++ b/src/java.desktop/share/native/libharfbuzz/graph/serialize.hh
@@ -116,10 +116,10 @@
   for (int parent_idx = vertices.length - 1; parent_idx >= 0; parent_idx--)
   {
     // Don't need to check virtual links for overflow
-    for (const auto& link : vertices[parent_idx].obj.real_links)
+    for (const auto& link : vertices.arrayZ[parent_idx].obj.real_links)
     {
       int64_t offset = compute_offset (graph, parent_idx, link);
-      if (is_valid_offset (offset, link))
+      if (likely (is_valid_offset (offset, link)))
         continue;
 
       if (!overflows) return true;
@@ -226,6 +226,9 @@
 {
   hb_vector_t<char> buffer;
   size_t size = graph.total_size_in_bytes ();
+
+  if (!size) return hb_blob_get_empty ();
+
   if (!buffer.alloc (size)) {
     DEBUG_MSG (SUBSET_REPACK, nullptr, "Unable to allocate output buffer.");
     return nullptr;
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-common.hh b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-common.hh
index 8230cba..b2d1b7b 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-common.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-common.hh
@@ -851,43 +851,41 @@
        *
        *   https://github.com/harfbuzz/harfbuzz/issues/2860
        */
-      const EntryT *wouldbe_entry;
-      bool safe_to_break =
-        /* 1. */
-        !c->is_actionable (this, entry)
-      &&
-        /* 2. */
-        (
-          /* 2a. */
-          state == StateTableT::STATE_START_OF_TEXT
-        ||
-          /* 2b. */
-          (
-            (entry.flags & context_t::DontAdvance) &&
-            next_state == StateTableT::STATE_START_OF_TEXT
-          )
-        ||
-          /* 2c. */
-          (
-            wouldbe_entry = &machine.get_entry (StateTableT::STATE_START_OF_TEXT, klass)
-          ,
-            /* 2c'. */
-            !c->is_actionable (this, *wouldbe_entry)
-          &&
-            /* 2c". */
-            (
-              next_state == machine.new_state (wouldbe_entry->newState)
-            &&
-              (entry.flags & context_t::DontAdvance) == (wouldbe_entry->flags & context_t::DontAdvance)
-            )
-          )
-        )
-      &&
-        /* 3. */
-        !c->is_actionable (this, machine.get_entry (state, StateTableT::CLASS_END_OF_TEXT))
-      ;
 
-      if (!safe_to_break && buffer->backtrack_len () && buffer->idx < buffer->len)
+      const auto is_safe_to_break_extra = [&]()
+      {
+          /* 2c. */
+          const auto wouldbe_entry = machine.get_entry(StateTableT::STATE_START_OF_TEXT, klass);
+
+          /* 2c'. */
+          if (c->is_actionable (this, wouldbe_entry))
+              return false;
+
+          /* 2c". */
+          return next_state == machine.new_state(wouldbe_entry.newState)
+              && (entry.flags & context_t::DontAdvance) == (wouldbe_entry.flags & context_t::DontAdvance);
+      };
+
+      const auto is_safe_to_break = [&]()
+      {
+          /* 1. */
+          if (c->is_actionable (this, entry))
+              return false;
+
+          /* 2. */
+          // This one is meh, I know...
+          const auto ok =
+                 state == StateTableT::STATE_START_OF_TEXT
+              || ((entry.flags & context_t::DontAdvance) && next_state == StateTableT::STATE_START_OF_TEXT)
+              || is_safe_to_break_extra();
+          if (!ok)
+              return false;
+
+          /* 3. */
+          return !c->is_actionable (this, machine.get_entry (state, StateTableT::CLASS_END_OF_TEXT));
+      };
+
+      if (!is_safe_to_break () && buffer->backtrack_len () && buffer->idx < buffer->len)
         buffer->unsafe_to_break_from_outbuffer (buffer->backtrack_len () - 1, buffer->idx + 1);
 
       c->transition (this, entry);
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-trak-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-trak-table.hh
index cb53128..5c49d1f 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-trak-table.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout-trak-table.hh
@@ -111,13 +111,13 @@
         break;
       }
     }
-    if (!trackTableEntry) return 0.;
+    if (!trackTableEntry) return 0;
 
     /*
      * Choose size.
      */
     unsigned int sizes = nSizes;
-    if (!sizes) return 0.;
+    if (!sizes) return 0;
     if (sizes == 1) return trackTableEntry->get_value (base, 0, sizes);
 
     hb_array_t<const F16DOT16> size_table ((base+sizeTable).arrayZ, sizes);
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.cc b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.cc
index b0afbdf..fc5834c 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.cc
+++ b/src/java.desktop/share/native/libharfbuzz/hb-aat-layout.cc
@@ -55,7 +55,13 @@
                                                        buffer (buffer_),
                                                        sanitizer (),
                                                        ankr_table (&Null (AAT::ankr)),
-                                                       gdef_table (face->table.GDEF->table),
+                                                       gdef_table (
+#ifndef HB_NO_OT_LAYOUT
+                                                         face->table.GDEF->table
+#else
+                                                         &Null (GDEF)
+#endif
+                                                       ),
                                                        lookup_index (0)
 {
   sanitizer.init (blob);
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-algs.hh b/src/java.desktop/share/native/libharfbuzz/hb-algs.hh
index e2b970f..b2b7c25 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-algs.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-algs.hh
@@ -87,6 +87,19 @@
 static inline constexpr uint32_t hb_uint32_swap (uint32_t v)
 { return (hb_uint16_swap (v) << 16) | hb_uint16_swap (v >> 16); }
 
+#ifndef HB_FAST_INT_ACCESS
+#if defined(__OPTIMIZE__) && \
+    defined(__BYTE_ORDER) && \
+    (__BYTE_ORDER == __BIG_ENDIAN || \
+     (__BYTE_ORDER == __LITTLE_ENDIAN && \
+      hb_has_builtin(__builtin_bswap16) && \
+      hb_has_builtin(__builtin_bswap32)))
+#define HB_FAST_INT_ACCESS 1
+#else
+#define HB_FAST_INT_ACCESS 0
+#endif
+#endif
+
 template <typename Type, int Bytes = sizeof (Type)>
 struct BEInt;
 template <typename Type>
@@ -101,21 +114,25 @@
 template <typename Type>
 struct BEInt<Type, 2>
 {
+  struct __attribute__((packed)) packed_uint16_t { uint16_t v; };
+
   public:
   BEInt () = default;
-  constexpr BEInt (Type V) : v {uint8_t ((V >>  8) & 0xFF),
-                                uint8_t ((V      ) & 0xFF)} {}
 
-  struct __attribute__((packed)) packed_uint16_t { uint16_t v; };
-  constexpr operator Type () const
-  {
-#if defined(__OPTIMIZE__) && !defined(HB_NO_PACKED) && \
-    defined(__BYTE_ORDER) && \
-    (__BYTE_ORDER == __BIG_ENDIAN || \
-     (__BYTE_ORDER == __LITTLE_ENDIAN && \
-      hb_has_builtin(__builtin_bswap16)))
-    /* Spoon-feed the compiler a big-endian integer with alignment 1.
-     * https://github.com/harfbuzz/harfbuzz/pull/1398 */
+  BEInt (Type V)
+#if HB_FAST_INT_ACCESS
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+  { ((packed_uint16_t *) v)->v = __builtin_bswap16 (V); }
+#else /* __BYTE_ORDER == __BIG_ENDIAN */
+  { ((packed_uint16_t *) v)->v = V; }
+#endif
+#else
+    : v {uint8_t ((V >>  8) & 0xFF),
+         uint8_t ((V      ) & 0xFF)} {}
+#endif
+
+  constexpr operator Type () const {
+#if HB_FAST_INT_ACCESS
 #if __BYTE_ORDER == __LITTLE_ENDIAN
     return __builtin_bswap16 (((packed_uint16_t *) v)->v);
 #else /* __BYTE_ORDER == __BIG_ENDIAN */
@@ -146,22 +163,27 @@
 template <typename Type>
 struct BEInt<Type, 4>
 {
+  struct __attribute__((packed)) packed_uint32_t { uint32_t v; };
+
   public:
   BEInt () = default;
-  constexpr BEInt (Type V) : v {uint8_t ((V >> 24) & 0xFF),
-                                uint8_t ((V >> 16) & 0xFF),
-                                uint8_t ((V >>  8) & 0xFF),
-                                uint8_t ((V      ) & 0xFF)} {}
 
-  struct __attribute__((packed)) packed_uint32_t { uint32_t v; };
+  BEInt (Type V)
+#if HB_FAST_INT_ACCESS
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+  { ((packed_uint32_t *) v)->v = __builtin_bswap32 (V); }
+#else /* __BYTE_ORDER == __BIG_ENDIAN */
+  { ((packed_uint32_t *) v)->v = V; }
+#endif
+#else
+    : v {uint8_t ((V >> 24) & 0xFF),
+         uint8_t ((V >> 16) & 0xFF),
+         uint8_t ((V >>  8) & 0xFF),
+         uint8_t ((V      ) & 0xFF)} {}
+#endif
+
   constexpr operator Type () const {
-#if defined(__OPTIMIZE__) && !defined(HB_NO_PACKED) && \
-    defined(__BYTE_ORDER) && \
-    (__BYTE_ORDER == __BIG_ENDIAN || \
-     (__BYTE_ORDER == __LITTLE_ENDIAN && \
-      hb_has_builtin(__builtin_bswap32)))
-    /* Spoon-feed the compiler a big-endian integer with alignment 1.
-     * https://github.com/harfbuzz/harfbuzz/pull/1398 */
+#if HB_FAST_INT_ACCESS
 #if __BYTE_ORDER == __LITTLE_ENDIAN
     return __builtin_bswap32 (((packed_uint32_t *) v)->v);
 #else /* __BYTE_ORDER == __BIG_ENDIAN */
@@ -231,12 +253,123 @@
 }
 HB_FUNCOBJ (hb_bool);
 
+
+/* The MIT License
+
+   Copyright (C) 2012 Zilong Tan (eric.zltan@gmail.com)
+
+   Permission is hereby granted, free of charge, to any person
+   obtaining a copy of this software and associated documentation
+   files (the "Software"), to deal in the Software without
+   restriction, including without limitation the rights to use, copy,
+   modify, merge, publish, distribute, sublicense, and/or sell copies
+   of the Software, and to permit persons to whom the Software is
+   furnished to do so, 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.
+*/
+
+
+// Compression function for Merkle-Damgard construction.
+// This function is generated using the framework provided.
+#define mix(h) (                                        \
+                        (void) ((h) ^= (h) >> 23),              \
+                        (void) ((h) *= 0x2127599bf4325c37ULL),  \
+                        (h) ^= (h) >> 47)
+
+static inline uint64_t fasthash64(const void *buf, size_t len, uint64_t seed)
+{
+        struct __attribute__((packed)) packed_uint64_t { uint64_t v; };
+        const uint64_t    m = 0x880355f21e6d1965ULL;
+        const packed_uint64_t *pos = (const packed_uint64_t *)buf;
+        const packed_uint64_t *end = pos + (len / 8);
+        const unsigned char *pos2;
+        uint64_t h = seed ^ (len * m);
+        uint64_t v;
+
+#ifndef HB_OPTIMIZE_SIZE
+        if (((uintptr_t) pos & 7) == 0)
+        {
+          while (pos != end)
+          {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-align"
+            v  = * (const uint64_t *) (pos++);
+#pragma GCC diagnostic pop
+            h ^= mix(v);
+            h *= m;
+          }
+        }
+        else
+#endif
+        {
+          while (pos != end)
+          {
+            v  = pos++->v;
+            h ^= mix(v);
+            h *= m;
+          }
+        }
+
+        pos2 = (const unsigned char*)pos;
+        v = 0;
+
+        switch (len & 7) {
+        case 7: v ^= (uint64_t)pos2[6] << 48; HB_FALLTHROUGH;
+        case 6: v ^= (uint64_t)pos2[5] << 40; HB_FALLTHROUGH;
+        case 5: v ^= (uint64_t)pos2[4] << 32; HB_FALLTHROUGH;
+        case 4: v ^= (uint64_t)pos2[3] << 24; HB_FALLTHROUGH;
+        case 3: v ^= (uint64_t)pos2[2] << 16; HB_FALLTHROUGH;
+        case 2: v ^= (uint64_t)pos2[1] <<  8; HB_FALLTHROUGH;
+        case 1: v ^= (uint64_t)pos2[0];
+                h ^= mix(v);
+                h *= m;
+        }
+
+        return mix(h);
+}
+
+static inline uint32_t fasthash32(const void *buf, size_t len, uint32_t seed)
+{
+        // the following trick converts the 64-bit hashcode to Fermat
+        // residue, which shall retain information from both the higher
+        // and lower parts of hashcode.
+        uint64_t h = fasthash64(buf, len, seed);
+        return h - (h >> 32);
+}
+
 struct
 {
   private:
 
   template <typename T> constexpr auto
-  impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, hb_deref (v).hash ())
+  impl (const T& v, hb_priority<2>) const HB_RETURN (uint32_t, hb_deref (v).hash ())
+
+  // Horrible: std:hash() of integers seems to be identity in gcc / clang?!
+  // https://github.com/harfbuzz/harfbuzz/pull/4228
+  //
+  // For performance characteristics see:
+  // https://github.com/harfbuzz/harfbuzz/pull/4228#issuecomment-1565079537
+  template <typename T,
+            hb_enable_if (std::is_integral<T>::value && sizeof (T) <= sizeof (uint32_t))> constexpr auto
+  impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, (uint32_t) v * 2654435761u /* Knuh's multiplicative hash */)
+  template <typename T,
+            hb_enable_if (std::is_integral<T>::value && sizeof (T) > sizeof (uint32_t))> constexpr auto
+  impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, (uint32_t) (v ^ (v >> 32)) * 2654435761u /* Knuth's multiplicative hash */)
+
+  template <typename T,
+            hb_enable_if (std::is_floating_point<T>::value)> constexpr auto
+  impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, fasthash32 (std::addressof (v), sizeof (T), 0xf437ffe6))
 
   template <typename T> constexpr auto
   impl (const T& v, hb_priority<0>) const HB_RETURN (uint32_t, std::hash<hb_decay<decltype (hb_deref (v))>>{} (hb_deref (v)))
@@ -551,6 +684,8 @@
 template <typename T1, typename T2> static inline hb_pair_t<T1, T2>
 hb_pair (T1&& a, T2&& b) { return hb_pair_t<T1, T2> (a, b); }
 
+typedef hb_pair_t<hb_codepoint_t, hb_codepoint_t> hb_codepoint_pair_t;
+
 struct
 {
   template <typename Pair> constexpr typename Pair::first_t
@@ -626,8 +761,10 @@
 
   if (sizeof (T) == 8)
   {
-    unsigned int shift = 32;
-    return hb_popcount<uint32_t> ((uint32_t) v) + hb_popcount ((uint32_t) (v >> shift));
+    uint64_t y = (uint64_t) v;
+    y -= ((y >> 1) & 0x5555555555555555ull);
+    y = (y & 0x3333333333333333ull) + (y >> 2 & 0x3333333333333333ull);
+    return ((y + (y >> 4)) & 0xf0f0f0f0f0f0f0full) * 0x101010101010101ull >> 56;
   }
 
   if (sizeof (T) == 16)
@@ -851,7 +988,7 @@
 hb_memset (void *s, int c, unsigned int n)
 {
   /* It's illegal to pass NULL to memset(), even if n is zero. */
-  if (unlikely (!n)) return 0;
+  if (unlikely (!n)) return s;
   return memset (s, c, n);
 }
 
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-array.hh b/src/java.desktop/share/native/libharfbuzz/hb-array.hh
index 08b2598..439f182 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-array.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-array.hh
@@ -75,11 +75,25 @@
    */
   typedef Type& __item_t__;
   static constexpr bool is_random_access_iterator = true;
+  static constexpr bool has_fast_len = true;
+  Type& __item__ () const
+  {
+    if (unlikely (!length)) return CrapOrNull (Type);
+    return *arrayZ;
+  }
   Type& __item_at__ (unsigned i) const
   {
     if (unlikely (i >= length)) return CrapOrNull (Type);
     return arrayZ[i];
   }
+  void __next__ ()
+  {
+    if (unlikely (!length))
+      return;
+    length--;
+    backwards_length++;
+    arrayZ++;
+  }
   void __forward__ (unsigned n)
   {
     if (unlikely (n > length))
@@ -88,6 +102,14 @@
     backwards_length += n;
     arrayZ += n;
   }
+  void __prev__ ()
+  {
+    if (unlikely (!backwards_length))
+      return;
+    length++;
+    backwards_length--;
+    arrayZ--;
+  }
   void __rewind__ (unsigned n)
   {
     if (unlikely (n > backwards_length))
@@ -122,9 +144,14 @@
 
   uint32_t hash () const
   {
-    uint32_t current = 0;
+    // FNV-1a hash function
+    // https://github.com/harfbuzz/harfbuzz/pull/4228
+    uint32_t current = /*cbf29ce4*/0x84222325;
     for (auto &v : *this)
-      current = current * 31 + hb_hash (v);
+    {
+      current = current ^ hb_hash (v);
+      current = current * 16777619;
+    }
     return current;
   }
 
@@ -322,6 +349,7 @@
   HB_ITER_USING (iter_base_t);
   static constexpr bool is_random_access_iterator = true;
   static constexpr bool is_sorted_iterator = true;
+  static constexpr bool has_fast_len = true;
 
   hb_sorted_array_t () = default;
   hb_sorted_array_t (const hb_sorted_array_t&) = default;
@@ -449,41 +477,21 @@
 
 /* Specialize hash() for byte arrays. */
 
+#ifndef HB_OPTIMIZE_SIZE_MORE
 template <>
 inline uint32_t hb_array_t<const char>::hash () const
 {
-  uint32_t current = 0;
-  unsigned i = 0;
-
-#if defined(__OPTIMIZE__) && !defined(HB_NO_PACKED) && \
-    ((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__))
-  struct __attribute__((packed)) packed_uint32_t { uint32_t v; };
-  for (; i + 4 <= this->length; i += 4)
-    current = current * 31 + hb_hash ((uint32_t) ((packed_uint32_t *) &this->arrayZ[i])->v);
-#endif
-
-  for (; i < this->length; i++)
-    current = current * 31 + hb_hash (this->arrayZ[i]);
-  return current;
+  // https://github.com/harfbuzz/harfbuzz/pull/4228
+  return fasthash32(arrayZ, length, 0xf437ffe6 /* magic? */);
 }
 
 template <>
 inline uint32_t hb_array_t<const unsigned char>::hash () const
 {
-  uint32_t current = 0;
-  unsigned i = 0;
-
-#if defined(__OPTIMIZE__) && !defined(HB_NO_PACKED) && \
-    ((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__))
-  struct __attribute__((packed)) packed_uint32_t { uint32_t v; };
-  for (; i + 4 <= this->length; i += 4)
-    current = current * 31 + hb_hash ((uint32_t) ((packed_uint32_t *) &this->arrayZ[i])->v);
-#endif
-
-  for (; i < this->length; i++)
-    current = current * 31 + hb_hash (this->arrayZ[i]);
-  return current;
+  // https://github.com/harfbuzz/harfbuzz/pull/4228
+  return fasthash32(arrayZ, length, 0xf437ffe6 /* magic? */);
 }
+#endif
 
 
 typedef hb_array_t<const char> hb_bytes_t;
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-atomic.hh b/src/java.desktop/share/native/libharfbuzz/hb-atomic.hh
index 57e9476..459d82e 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-atomic.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-atomic.hh
@@ -204,6 +204,7 @@
 
   hb_atomic_ptr_t () = default;
   constexpr hb_atomic_ptr_t (T* v) : v (v) {}
+  hb_atomic_ptr_t (const hb_atomic_ptr_t &other) = delete;
 
   void init (T* v_ = nullptr) { set_relaxed (v_); }
   void set_relaxed (T* v_) { hb_atomic_ptr_impl_set_relaxed (&v, v_); }
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-bimap.hh b/src/java.desktop/share/native/libharfbuzz/hb-bimap.hh
index 9edefd9..f5414725 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-bimap.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-bimap.hh
@@ -39,10 +39,10 @@
     back_map.reset ();
   }
 
-  void resize (unsigned pop)
+  void alloc (unsigned pop)
   {
-    forw_map.resize (pop);
-    back_map.resize (pop);
+    forw_map.alloc (pop);
+    back_map.alloc (pop);
   }
 
   bool in_error () const { return forw_map.in_error () || back_map.in_error (); }
@@ -83,7 +83,6 @@
 
   unsigned int get_population () const { return forw_map.get_population (); }
 
-
   protected:
   hb_map_t  forw_map;
   hb_map_t  back_map;
@@ -94,9 +93,31 @@
   auto iter () const HB_AUTO_RETURN (+ forw_map.iter())
 };
 
-/* Inremental bimap: only lhs is given, rhs is incrementally assigned */
-struct hb_inc_bimap_t : hb_bimap_t
+/* Incremental bimap: only lhs is given, rhs is incrementally assigned */
+struct hb_inc_bimap_t
 {
+  bool in_error () const { return forw_map.in_error () || back_map.in_error (); }
+
+  unsigned int get_population () const { return forw_map.get_population (); }
+
+  void reset ()
+  {
+    forw_map.reset ();
+    back_map.reset ();
+  }
+
+  void alloc (unsigned pop)
+  {
+    forw_map.alloc (pop);
+    back_map.alloc (pop);
+  }
+
+  void clear ()
+  {
+    forw_map.clear ();
+    back_map.resize (0);
+  }
+
   /* Add a mapping from lhs to rhs with a unique value if lhs is unknown.
    * Return the rhs value as the result.
    */
@@ -105,32 +126,42 @@
     hb_codepoint_t  rhs = forw_map[lhs];
     if (rhs == HB_MAP_VALUE_INVALID)
     {
-      rhs = next_value++;
-      set (lhs, rhs);
+      rhs = back_map.length;
+      forw_map.set (lhs, rhs);
+      back_map.push (lhs);
     }
     return rhs;
   }
 
   hb_codepoint_t skip ()
-  { return next_value++; }
+  {
+    hb_codepoint_t start = back_map.length;
+    back_map.push (HB_MAP_VALUE_INVALID);
+    return start;
+  }
 
   hb_codepoint_t skip (unsigned count)
-  { return next_value += count; }
+  {
+    hb_codepoint_t start = back_map.length;
+    back_map.alloc (back_map.length + count);
+    for (unsigned i = 0; i < count; i++)
+      back_map.push (HB_MAP_VALUE_INVALID);
+    return start;
+  }
 
   hb_codepoint_t get_next_value () const
-  { return next_value; }
+  { return back_map.length; }
 
   void add_set (const hb_set_t *set)
   {
-    hb_codepoint_t i = HB_SET_VALUE_INVALID;
-    while (hb_set_next (set, &i)) add (i);
+    for (auto i : *set) add (i);
   }
 
   /* Create an identity map. */
   bool identity (unsigned int size)
   {
     clear ();
-    for (hb_codepoint_t i = 0; i < size; i++) set (i, i);
+    for (hb_codepoint_t i = 0; i < size; i++) add (i);
     return !in_error ();
   }
 
@@ -145,20 +176,30 @@
   {
     hb_codepoint_t  count = get_population ();
     hb_vector_t <hb_codepoint_t> work;
-    work.resize (count);
+    if (unlikely (!work.resize (count, false))) return;
 
     for (hb_codepoint_t rhs = 0; rhs < count; rhs++)
-      work[rhs] = back_map[rhs];
+      work.arrayZ[rhs] = back_map[rhs];
 
     work.qsort (cmp_id);
 
     clear ();
     for (hb_codepoint_t rhs = 0; rhs < count; rhs++)
-      set (work[rhs], rhs);
+      add (work.arrayZ[rhs]);
   }
 
+  hb_codepoint_t get (hb_codepoint_t lhs) const { return forw_map.get (lhs); }
+  hb_codepoint_t backward (hb_codepoint_t rhs) const { return back_map[rhs]; }
+
+  hb_codepoint_t operator [] (hb_codepoint_t lhs) const { return get (lhs); }
+  bool has (hb_codepoint_t lhs) const { return forw_map.has (lhs); }
+
   protected:
-  unsigned int next_value = 0;
+  hb_map_t forw_map;
+  hb_vector_t<hb_codepoint_t> back_map;
+
+  public:
+  auto keys () const HB_AUTO_RETURN (+ back_map.iter())
 };
 
 #endif /* HB_BIMAP_HH */
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-bit-page.hh b/src/java.desktop/share/native/libharfbuzz/hb-bit-page.hh
index 81e2a49..404a19c 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-bit-page.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-bit-page.hh
@@ -89,14 +89,18 @@
 
 struct hb_bit_page_t
 {
-  void init0 () { v.init0 (); }
-  void init1 () { v.init1 (); }
+  void init0 () { v.init0 (); population = 0; }
+  void init1 () { v.init1 (); population = PAGE_BITS; }
+
+  void dirty () { population = UINT_MAX; }
 
   static inline constexpr unsigned len ()
   { return ARRAY_LENGTH_CONST (v); }
 
+  operator bool () const { return !is_empty (); }
   bool is_empty () const
   {
+    if (has_population ()) return !population;
     return
     + hb_iter (v)
     | hb_none
@@ -104,14 +108,11 @@
   }
   uint32_t hash () const
   {
-    return
-    + hb_iter (v)
-    | hb_reduce ([] (uint32_t h, const elt_t &_) { return h * 31 + hb_hash (_); }, (uint32_t) 0u)
-    ;
+    return hb_bytes_t ((const char *) &v, sizeof (v)).hash ();
   }
 
-  void add (hb_codepoint_t g) { elt (g) |= mask (g); }
-  void del (hb_codepoint_t g) { elt (g) &= ~mask (g); }
+  void add (hb_codepoint_t g) { elt (g) |= mask (g); dirty (); }
+  void del (hb_codepoint_t g) { elt (g) &= ~mask (g); dirty (); }
   void set (hb_codepoint_t g, bool value) { if (value) add (g); else del (g); }
   bool get (hb_codepoint_t g) const { return elt (g) & mask (g); }
 
@@ -123,20 +124,21 @@
       *la |= (mask (b) << 1) - mask(a);
     else
     {
-      *la |= ~(mask (a) - 1);
+      *la |= ~(mask (a) - 1llu);
       la++;
 
       hb_memset (la, 0xff, (char *) lb - (char *) la);
 
-      *lb |= ((mask (b) << 1) - 1);
+      *lb |= ((mask (b) << 1) - 1llu);
     }
+    dirty ();
   }
   void del_range (hb_codepoint_t a, hb_codepoint_t b)
   {
     elt_t *la = &elt (a);
     elt_t *lb = &elt (b);
     if (la == lb)
-      *la &= ~((mask (b) << 1) - mask(a));
+      *la &= ~((mask (b) << 1llu) - mask(a));
     else
     {
       *la &= mask (a) - 1;
@@ -144,8 +146,9 @@
 
       hb_memset (la, 0, (char *) lb - (char *) la);
 
-      *lb &= ~((mask (b) << 1) - 1);
+      *lb &= ~((mask (b) << 1) - 1llu);
     }
+    dirty ();
   }
   void set_range (hb_codepoint_t a, hb_codepoint_t b, bool v)
   { if (v) add_range (a, b); else del_range (a, b); }
@@ -216,6 +219,7 @@
     return count;
   }
 
+  bool operator == (const hb_bit_page_t &other) const { return is_equal (other); }
   bool is_equal (const hb_bit_page_t &other) const
   {
     for (unsigned i = 0; i < len (); i++)
@@ -223,20 +227,28 @@
         return false;
     return true;
   }
+  bool operator <= (const hb_bit_page_t &larger_page) const { return is_subset (larger_page); }
   bool is_subset (const hb_bit_page_t &larger_page) const
   {
+    if (has_population () && larger_page.has_population () &&
+        population > larger_page.population)
+      return false;
+
     for (unsigned i = 0; i < len (); i++)
       if (~larger_page.v[i] & v[i])
         return false;
     return true;
   }
 
+  bool has_population () const { return population != UINT_MAX; }
   unsigned int get_population () const
   {
-    return
+    if (has_population ()) return population;
+    population =
     + hb_iter (v)
     | hb_reduce ([] (unsigned pop, const elt_t &_) { return pop + hb_popcount (_); }, 0u)
     ;
+    return population;
   }
 
   bool next (hb_codepoint_t *codepoint) const
@@ -332,9 +344,9 @@
   const elt_t& elt (hb_codepoint_t g) const { return v[(g & MASK) / ELT_BITS]; }
   static constexpr elt_t mask (hb_codepoint_t g) { return elt_t (1) << (g & ELT_MASK); }
 
+  mutable unsigned population;
   vector_t v;
 };
-static_assert (hb_bit_page_t::PAGE_BITS == sizeof (hb_bit_page_t) * 8, "");
 
 
 #endif /* HB_BIT_PAGE_HH */
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-bit-set-invertible.hh b/src/java.desktop/share/native/libharfbuzz/hb-bit-set-invertible.hh
index bf5a0b4..2e33554 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-bit-set-invertible.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-bit-set-invertible.hh
@@ -136,7 +136,7 @@
   /* Sink interface. */
   hb_bit_set_invertible_t& operator << (hb_codepoint_t v)
   { add (v); return *this; }
-  hb_bit_set_invertible_t& operator << (const hb_pair_t<hb_codepoint_t, hb_codepoint_t>& range)
+  hb_bit_set_invertible_t& operator << (const hb_codepoint_pair_t& range)
   { add_range (range.first, range.second); return *this; }
 
   bool intersects (hb_codepoint_t first, hb_codepoint_t last) const
@@ -162,7 +162,7 @@
       auto it1 = iter ();
       auto it2 = other.iter ();
       return hb_all (+ hb_zip (it1, it2)
-                     | hb_map ([](hb_pair_t<hb_codepoint_t, hb_codepoint_t> _) { return _.first == _.second; }));
+                     | hb_map ([](hb_codepoint_pair_t _) { return _.first == _.second; }));
     }
   }
 
@@ -345,6 +345,7 @@
   struct iter_t : hb_iter_with_fallback_t<iter_t, hb_codepoint_t>
   {
     static constexpr bool is_sorted_iterator = true;
+    static constexpr bool has_fast_len = true;
     iter_t (const hb_bit_set_invertible_t &s_ = Null (hb_bit_set_invertible_t),
             bool init = true) : s (&s_), v (INVALID), l(0)
     {
@@ -363,7 +364,7 @@
     unsigned __len__ () const { return l; }
     iter_t end () const { return iter_t (*s, false); }
     bool operator != (const iter_t& o) const
-    { return s != o.s || v != o.v; }
+    { return v != o.v || s != o.s; }
 
     protected:
     const hb_bit_set_invertible_t *s;
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-bit-set.hh b/src/java.desktop/share/native/libharfbuzz/hb-bit-set.hh
index 31ee52f..b900711 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-bit-set.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-bit-set.hh
@@ -30,7 +30,6 @@
 
 #include "hb.hh"
 #include "hb-bit-page.hh"
-#include "hb-machinery.hh"
 
 
 struct hb_bit_set_t
@@ -134,7 +133,11 @@
   {
     uint32_t h = 0;
     for (auto &map : page_map)
-      h = h * 31 + hb_hash (map.major) + hb_hash (pages[map.index]);
+    {
+      auto &page = pages.arrayZ[map.index];
+      if (unlikely (page.is_empty ())) continue;
+      h = h * 31 + hb_hash (map.major) + hb_hash (page);
+    }
     return h;
   }
 
@@ -179,6 +182,16 @@
     return true;
   }
 
+  /* Duplicated here from hb-machinery.hh to avoid including it. */
+  template<typename Type>
+  static inline const Type& StructAtOffsetUnaligned(const void *P, unsigned int offset)
+  {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-align"
+    return * reinterpret_cast<const Type*> ((const char *) P + offset);
+#pragma GCC diagnostic pop
+  }
+
   template <typename T>
   void set_array (bool v, const T *array, unsigned int count, unsigned int stride=sizeof(T))
   {
@@ -342,7 +355,7 @@
   /* Sink interface. */
   hb_bit_set_t& operator << (hb_codepoint_t v)
   { add (v); return *this; }
-  hb_bit_set_t& operator << (const hb_pair_t<hb_codepoint_t, hb_codepoint_t>& range)
+  hb_bit_set_t& operator << (const hb_codepoint_pair_t& range)
   { add_range (range.first, range.second); return *this; }
 
   bool intersects (hb_codepoint_t first, hb_codepoint_t last) const
@@ -402,7 +415,6 @@
       uint32_t spm = page_map[spi].major;
       uint32_t lpm = larger_set.page_map[lpi].major;
       auto sp = page_at (spi);
-      auto lp = larger_set.page_at (lpi);
 
       if (spm < lpm && !sp.is_empty ())
         return false;
@@ -410,6 +422,7 @@
       if (lpm < spm)
         continue;
 
+      auto lp = larger_set.page_at (lpi);
       if (!sp.is_subset (lp))
         return false;
 
@@ -549,6 +562,7 @@
         count--;
         page_map.arrayZ[count] = page_map.arrayZ[a];
         page_at (count).v = op (page_at (a).v, other.page_at (b).v);
+        page_at (count).dirty ();
       }
       else if (page_map.arrayZ[a - 1].major > other.page_map.arrayZ[b - 1].major)
       {
@@ -567,7 +581,7 @@
           count--;
           page_map.arrayZ[count].major = other.page_map.arrayZ[b].major;
           page_map.arrayZ[count].index = next_page++;
-          page_at (count).v = other.page_at (b).v;
+          page_at (count) = other.page_at (b);
         }
       }
     }
@@ -585,7 +599,7 @@
         count--;
         page_map.arrayZ[count].major = other.page_map.arrayZ[b].major;
         page_map.arrayZ[count].index = next_page++;
-        page_at (count).v = other.page_at (b).v;
+        page_at (count) = other.page_at (b);
       }
     assert (!count);
     resize (newCount);
@@ -623,6 +637,7 @@
         *codepoint = INVALID;
         return false;
       }
+      last_page_lookup = i;
     }
 
     const auto* pages_array = pages.arrayZ;
@@ -632,7 +647,6 @@
       if (pages_array[current.index].next (codepoint))
       {
         *codepoint += current.major * page_t::PAGE_BITS;
-        last_page_lookup = i;
         return true;
       }
       i++;
@@ -649,7 +663,6 @@
         return true;
       }
     }
-    last_page_lookup = 0;
     *codepoint = INVALID;
     return false;
   }
@@ -863,6 +876,7 @@
   struct iter_t : hb_iter_with_fallback_t<iter_t, hb_codepoint_t>
   {
     static constexpr bool is_sorted_iterator = true;
+    static constexpr bool has_fast_len = true;
     iter_t (const hb_bit_set_t &s_ = Null (hb_bit_set_t),
             bool init = true) : s (&s_), v (INVALID), l(0)
     {
@@ -899,7 +913,7 @@
 
     /* The extra page_map length is necessary; can't just rely on vector here,
      * since the next check would be tricked because a null page also has
-     * major==0, which we can't distinguish from an actualy major==0 page... */
+     * major==0, which we can't distinguish from an actually major==0 page... */
     unsigned i = last_page_lookup;
     if (likely (i < page_map.length))
     {
@@ -921,7 +935,7 @@
       memmove (page_map.arrayZ + i + 1,
                page_map.arrayZ + i,
                (page_map.length - 1 - i) * page_map.item_size);
-      page_map[i] = map;
+      page_map.arrayZ[i] = map;
     }
 
     last_page_lookup = i;
@@ -933,7 +947,7 @@
 
     /* The extra page_map length is necessary; can't just rely on vector here,
      * since the next check would be tricked because a null page also has
-     * major==0, which we can't distinguish from an actualy major==0 page... */
+     * major==0, which we can't distinguish from an actually major==0 page... */
     unsigned i = last_page_lookup;
     if (likely (i < page_map.length))
     {
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-json.hh b/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-json.hh
index 7b9fc55..2a90cbf 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-json.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-json.hh
@@ -32,7 +32,7 @@
 #include "hb.hh"
 
 
-#line 33 "hb-buffer-deserialize-json.hh"
+#line 36 "hb-buffer-deserialize-json.hh"
 static const unsigned char _deserialize_json_trans_keys[] = {
         0u, 0u, 9u, 123u, 9u, 34u, 97u, 117u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u,
         48u, 57u, 9u, 125u, 9u, 125u, 9u, 93u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u,
@@ -555,12 +555,12 @@
   hb_glyph_info_t info = {0};
   hb_glyph_position_t pos = {0};
 
-#line 552 "hb-buffer-deserialize-json.hh"
+#line 559 "hb-buffer-deserialize-json.hh"
         {
         cs = deserialize_json_start;
         }
 
-#line 555 "hb-buffer-deserialize-json.hh"
+#line 564 "hb-buffer-deserialize-json.hh"
         {
         int _slen;
         int _trans;
@@ -772,7 +772,7 @@
         *end_ptr = p;
 }
         break;
-#line 733 "hb-buffer-deserialize-json.hh"
+#line 776 "hb-buffer-deserialize-json.hh"
         }
 
 _again:
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-text-glyphs.hh b/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-text-glyphs.hh
index cf9c281..8e526ce 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-text-glyphs.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-text-glyphs.hh
@@ -32,7 +32,7 @@
 #include "hb.hh"
 
 
-#line 33 "hb-buffer-deserialize-text-glyphs.hh"
+#line 36 "hb-buffer-deserialize-text-glyphs.hh"
 static const unsigned char _deserialize_text_glyphs_trans_keys[] = {
         0u, 0u, 48u, 57u, 45u, 57u, 48u, 57u, 45u, 57u, 48u, 57u, 48u, 57u, 45u, 57u,
         48u, 57u, 44u, 44u, 45u, 57u, 48u, 57u, 44u, 57u, 43u, 124u, 9u, 124u, 9u, 124u,
@@ -349,12 +349,12 @@
   hb_glyph_info_t info = {0};
   hb_glyph_position_t pos = {0};
 
-#line 346 "hb-buffer-deserialize-text-glyphs.hh"
+#line 353 "hb-buffer-deserialize-text-glyphs.hh"
         {
         cs = deserialize_text_glyphs_start;
         }
 
-#line 349 "hb-buffer-deserialize-text-glyphs.hh"
+#line 358 "hb-buffer-deserialize-text-glyphs.hh"
         {
         int _slen;
         int _trans;
@@ -550,7 +550,7 @@
         *end_ptr = p;
 }
         break;
-#line 516 "hb-buffer-deserialize-text-glyphs.hh"
+#line 554 "hb-buffer-deserialize-text-glyphs.hh"
         }
 
 _again:
@@ -667,7 +667,7 @@
         *end_ptr = p;
 }
         break;
-#line 616 "hb-buffer-deserialize-text-glyphs.hh"
+#line 671 "hb-buffer-deserialize-text-glyphs.hh"
         }
         }
 
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-text-unicode.hh b/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-text-unicode.hh
index f0c9465..6a1706c 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-text-unicode.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-buffer-deserialize-text-unicode.hh
@@ -32,7 +32,7 @@
 #include "hb.hh"
 
 
-#line 33 "hb-buffer-deserialize-text-unicode.hh"
+#line 36 "hb-buffer-deserialize-text-unicode.hh"
 static const unsigned char _deserialize_text_unicode_trans_keys[] = {
         0u, 0u, 9u, 117u, 43u, 102u, 48u, 102u, 48u, 57u, 9u, 124u, 9u, 124u, 9u, 124u,
         9u, 124u, 0
@@ -197,12 +197,12 @@
   hb_glyph_info_t info = {0};
   const hb_glyph_position_t pos = {0};
 
-#line 194 "hb-buffer-deserialize-text-unicode.hh"
+#line 201 "hb-buffer-deserialize-text-unicode.hh"
         {
         cs = deserialize_text_unicode_start;
         }
 
-#line 197 "hb-buffer-deserialize-text-unicode.hh"
+#line 206 "hb-buffer-deserialize-text-unicode.hh"
         {
         int _slen;
         int _trans;
@@ -269,7 +269,7 @@
         *end_ptr = p;
 }
         break;
-#line 256 "hb-buffer-deserialize-text-unicode.hh"
+#line 273 "hb-buffer-deserialize-text-unicode.hh"
         }
 
 _again:
@@ -307,7 +307,7 @@
         *end_ptr = p;
 }
         break;
-#line 289 "hb-buffer-deserialize-text-unicode.hh"
+#line 311 "hb-buffer-deserialize-text-unicode.hh"
         }
         }
 
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-buffer-verify.cc b/src/java.desktop/share/native/libharfbuzz/hb-buffer-verify.cc
index f2fef31..3bdea30 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-buffer-verify.cc
+++ b/src/java.desktop/share/native/libharfbuzz/hb-buffer-verify.cc
@@ -162,14 +162,8 @@
     hb_buffer_set_flags (fragment, flags);
 
     hb_buffer_append (fragment, text_buffer, text_start, text_end);
-    if (!hb_shape_full (font, fragment, features, num_features, shapers))
-    {
-      buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "shaping failed while shaping fragment.");
-      hb_buffer_destroy (reconstruction);
-      hb_buffer_destroy (fragment);
-      return false;
-    }
-    else if (!fragment->successful || fragment->shaping_failed)
+    if (!hb_shape_full (font, fragment, features, num_features, shapers) ||
+        fragment->successful || fragment->shaping_failed)
     {
       hb_buffer_destroy (reconstruction);
       hb_buffer_destroy (fragment);
@@ -185,15 +179,18 @@
   }
 
   bool ret = true;
-  hb_buffer_diff_flags_t diff = hb_buffer_diff (reconstruction, buffer, (hb_codepoint_t) -1, 0);
-  if (diff & ~HB_BUFFER_DIFF_FLAG_GLYPH_FLAGS_MISMATCH)
+  if (likely (reconstruction->successful))
   {
-    buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "unsafe-to-break test failed.");
-    ret = false;
+    hb_buffer_diff_flags_t diff = hb_buffer_diff (reconstruction, buffer, (hb_codepoint_t) -1, 0);
+    if (diff & ~HB_BUFFER_DIFF_FLAG_GLYPH_FLAGS_MISMATCH)
+    {
+      buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "unsafe-to-break test failed.");
+      ret = false;
 
-    /* Return the reconstructed result instead so it can be inspected. */
-    hb_buffer_set_length (buffer, 0);
-    hb_buffer_append (buffer, reconstruction, 0, -1);
+      /* Return the reconstructed result instead so it can be inspected. */
+      hb_buffer_set_length (buffer, 0);
+      hb_buffer_append (buffer, reconstruction, 0, -1);
+    }
   }
 
   hb_buffer_destroy (reconstruction);
@@ -316,28 +313,13 @@
   /*
    * Shape the two fragment streams.
    */
-  if (!hb_shape_full (font, fragments[0], features, num_features, shapers))
-  {
-    buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "shaping failed while shaping fragment.");
-    ret = false;
+  if (!hb_shape_full (font, fragments[0], features, num_features, shapers) ||
+      !fragments[0]->successful || fragments[0]->shaping_failed)
     goto out;
-  }
-  else if (!fragments[0]->successful || fragments[0]->shaping_failed)
-  {
-    ret = true;
+
+  if (!hb_shape_full (font, fragments[1], features, num_features, shapers) ||
+      !fragments[1]->successful || fragments[1]->shaping_failed)
     goto out;
-  }
-  if (!hb_shape_full (font, fragments[1], features, num_features, shapers))
-  {
-    buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "shaping failed while shaping fragment.");
-    ret = false;
-    goto out;
-  }
-  else if (!fragments[1]->successful || fragments[1]->shaping_failed)
-  {
-    ret = true;
-    goto out;
-  }
 
   if (!forward)
   {
@@ -377,21 +359,23 @@
     hb_buffer_reverse (reconstruction);
   }
 
-  /*
-   * Diff results.
-   */
-  diff = hb_buffer_diff (reconstruction, buffer, (hb_codepoint_t) -1, 0);
-  if (diff & ~HB_BUFFER_DIFF_FLAG_GLYPH_FLAGS_MISMATCH)
+  if (likely (reconstruction->successful))
   {
-    buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "unsafe-to-concat test failed.");
-    ret = false;
+    /*
+     * Diff results.
+     */
+    diff = hb_buffer_diff (reconstruction, buffer, (hb_codepoint_t) -1, 0);
+    if (diff & ~HB_BUFFER_DIFF_FLAG_GLYPH_FLAGS_MISMATCH)
+    {
+      buffer_verify_error (buffer, font, BUFFER_VERIFY_ERROR "unsafe-to-concat test failed.");
+      ret = false;
 
-    /* Return the reconstructed result instead so it can be inspected. */
-    hb_buffer_set_length (buffer, 0);
-    hb_buffer_append (buffer, reconstruction, 0, -1);
+      /* Return the reconstructed result instead so it can be inspected. */
+      hb_buffer_set_length (buffer, 0);
+      hb_buffer_append (buffer, reconstruction, 0, -1);
+    }
   }
 
-
 out:
   hb_buffer_destroy (reconstruction);
   hb_buffer_destroy (fragments[0]);
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-buffer.cc b/src/java.desktop/share/native/libharfbuzz/hb-buffer.cc
index 69d8c96..5f9329e 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-buffer.cc
+++ b/src/java.desktop/share/native/libharfbuzz/hb-buffer.cc
@@ -268,7 +268,7 @@
   unicode = hb_unicode_funcs_reference (src.unicode);
   flags = src.flags;
   cluster_level = src.cluster_level;
-  replacement = src.invisible;
+  replacement = src.replacement;
   invisible = src.invisible;
   not_found = src.not_found;
 }
@@ -499,12 +499,12 @@
                         unsigned int cluster_start,
                         unsigned int cluster_end)
 {
-  hb_mask_t not_mask = ~mask;
-  value &= mask;
-
   if (!mask)
     return;
 
+  hb_mask_t not_mask = ~mask;
+  value &= mask;
+
   unsigned int count = len;
   for (unsigned int i = 0; i < count; i++)
     if (cluster_start <= info[i].cluster && info[i].cluster < cluster_end)
@@ -1327,7 +1327,7 @@
  * Sets the #hb_codepoint_t that replaces characters not found in
  * the font during shaping.
  *
- * The not-found glyph defaults to zero, sometimes knows as the
+ * The not-found glyph defaults to zero, sometimes known as the
  * ".notdef" glyph.  This API allows for differentiating the two.
  *
  * Since: 3.1.0
@@ -2076,7 +2076,7 @@
  * hb_buffer_diff:
  * @buffer: a buffer.
  * @reference: other buffer to compare to.
- * @dottedcircle_glyph: glyph id of U+25CC DOTTED CIRCLE, or (hb_codepont_t) -1.
+ * @dottedcircle_glyph: glyph id of U+25CC DOTTED CIRCLE, or (hb_codepoint_t) -1.
  * @position_fuzz: allowed absolute difference in position values.
  *
  * If dottedcircle_glyph is (hb_codepoint_t) -1 then #HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-buffer.h b/src/java.desktop/share/native/libharfbuzz/hb-buffer.h
index 9b21ffb..6fc215d 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-buffer.h
+++ b/src/java.desktop/share/native/libharfbuzz/hb-buffer.h
@@ -99,7 +99,7 @@
  *                                 layout, by avoiding re-shaping of each line
  *                                 after line-breaking, by limiting the
  *                                 reshaping to a small piece around the
- *                                 breaking positin only, even if the breaking
+ *                                 breaking position only, even if the breaking
  *                                 position carries the
  *                                 #HB_GLYPH_FLAG_UNSAFE_TO_BREAK or when
  *                                 hyphenation or other text transformation
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-buffer.hh b/src/java.desktop/share/native/libharfbuzz/hb-buffer.hh
index c147636..7f8ce14 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-buffer.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-buffer.hh
@@ -464,13 +464,16 @@
                       start, end,
                       true);
   }
+#ifndef HB_OPTIMIZE_SIZE
+  HB_ALWAYS_INLINE
+#endif
   void unsafe_to_concat (unsigned int start = 0, unsigned int end = -1)
   {
     if (likely ((flags & HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT) == 0))
       return;
     _set_glyph_flags (HB_GLYPH_FLAG_UNSAFE_TO_CONCAT,
                       start, end,
-                      true);
+                      false);
   }
   void unsafe_to_break_from_outbuffer (unsigned int start = 0, unsigned int end = -1)
   {
@@ -478,6 +481,9 @@
                       start, end,
                       true, true);
   }
+#ifndef HB_OPTIMIZE_SIZE
+  HB_ALWAYS_INLINE
+#endif
   void unsafe_to_concat_from_outbuffer (unsigned int start = 0, unsigned int end = -1)
   {
     if (likely ((flags & HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT) == 0))
@@ -493,6 +499,13 @@
 
   HB_NODISCARD HB_INTERNAL bool enlarge (unsigned int size);
 
+  HB_NODISCARD bool resize (unsigned length)
+  {
+    assert (!have_output);
+    if (unlikely (!ensure (length))) return false;
+    len = length;
+    return true;
+  }
   HB_NODISCARD bool ensure (unsigned int size)
   { return likely (!size || size < allocated) ? true : enlarge (size); }
 
@@ -553,7 +566,7 @@
   bool message (hb_font_t *font, const char *fmt, ...) HB_PRINTF_FUNC(3, 4)
   {
 #ifdef HB_NO_BUFFER_MESSAGE
-   return true;
+    return true;
 #else
     if (likely (!messaging ()))
       return true;
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-cache.hh b/src/java.desktop/share/native/libharfbuzz/hb-cache.hh
index f40c861..8c7e0c6 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-cache.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-cache.hh
@@ -62,14 +62,12 @@
   static_assert ((key_bits >= cache_bits), "");
   static_assert ((key_bits + value_bits <= cache_bits + 8 * sizeof (item_t)), "");
 
-  hb_cache_t () { init (); }
-
-  void init () { clear (); }
+  hb_cache_t () { clear (); }
 
   void clear ()
   {
-    for (unsigned i = 0; i < ARRAY_LENGTH (values); i++)
-      values[i] = -1;
+    for (auto &v : values)
+      v = -1;
   }
 
   bool get (unsigned int key, unsigned int *value) const
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-cff-interp-common.hh b/src/java.desktop/share/native/libharfbuzz/hb-cff-interp-common.hh
index e92e814..8d9ff5f 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-cff-interp-common.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-cff-interp-common.hh
@@ -26,6 +26,8 @@
 #ifndef HB_CFF_INTERP_COMMON_HH
 #define HB_CFF_INTERP_COMMON_HH
 
+extern HB_INTERNAL const unsigned char *endchar_str;
+
 namespace CFF {
 
 using namespace OT;
@@ -336,8 +338,6 @@
   hb_ubytes_t       str;
 };
 
-using byte_str_array_t = hb_vector_t<hb_ubytes_t>;
-
 /* stack */
 template <typename ELEM, int LIMIT>
 struct cff_stack_t
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-cff-interp-cs-common.hh b/src/java.desktop/share/native/libharfbuzz/hb-cff-interp-cs-common.hh
index 52b52c3..2628eff 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-cff-interp-cs-common.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-cff-interp-cs-common.hh
@@ -883,14 +883,12 @@
 
     unsigned max_ops = HB_CFF_MAX_OPS;
     for (;;) {
-      if (unlikely (!--max_ops))
+      OPSET::process_op (SUPER::env.fetch_op (), SUPER::env, param);
+      if (unlikely (SUPER::env.in_error () || !--max_ops))
       {
         SUPER::env.set_error ();
-        break;
-      }
-      OPSET::process_op (SUPER::env.fetch_op (), SUPER::env, param);
-      if (unlikely (SUPER::env.in_error ()))
         return false;
+      }
       if (SUPER::env.is_endchar ())
         break;
     }
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-common.cc b/src/java.desktop/share/native/libharfbuzz/hb-common.cc
index 8b94dcb..3afab42 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-common.cc
+++ b/src/java.desktop/share/native/libharfbuzz/hb-common.cc
@@ -815,7 +815,7 @@
   }
 
   const char *p = *pp;
-  while (*pp < end && (ISALNUM(**pp) || **pp == '_'))
+  while (*pp < end && (**pp != ' ' && **pp != '=' && **pp != '[' && **pp != quote))
     (*pp)++;
 
   if (p == *pp || *pp - p > 4)
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-common.h b/src/java.desktop/share/native/libharfbuzz/hb-common.h
index ebdeadd1..0d79567 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-common.h
+++ b/src/java.desktop/share/native/libharfbuzz/hb-common.h
@@ -104,6 +104,16 @@
  *
  **/
 typedef uint32_t hb_codepoint_t;
+
+/**
+ * HB_CODEPOINT_INVALID:
+ *
+ * Unused #hb_codepoint_t value.
+ *
+ * Since: 8.0.0
+ */
+#define HB_CODEPOINT_INVALID ((hb_codepoint_t) -1)
+
 /**
  * hb_position_t:
  *
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-config.hh b/src/java.desktop/share/native/libharfbuzz/hb-config.hh
index 52adaad..816c55c 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-config.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-config.hh
@@ -44,14 +44,14 @@
 #ifdef HB_TINY
 #define HB_LEAN
 #define HB_MINI
+#define HB_OPTIMIZE_SIZE
+#define HB_OPTIMIZE_SIZE_MORE
+#define HB_MINIMIZE_MEMORY_USAGE
 #define HB_NO_MT
 #define HB_NO_UCD_UNASSIGNED
 #ifndef NDEBUG
 #define NDEBUG
 #endif
-#ifndef __OPTIMIZE_SIZE__
-#define __OPTIMIZE_SIZE__
-#endif
 #endif
 
 #ifdef HB_LEAN
@@ -97,6 +97,12 @@
 #define HB_NO_BORING_EXPANSION
 #endif
 
+#ifdef __OPTIMIZE_SIZE__
+#ifndef HB_OPTIMIZE_SIZE
+#define HB_OPTIMIZE_SIZE
+#endif
+#endif
+
 #if defined(HAVE_CONFIG_OVERRIDE_H) || defined(HB_CONFIG_OVERRIDE_H)
 #ifndef HB_CONFIG_OVERRIDE_H
 #define HB_CONFIG_OVERRIDE_H "config-override.h"
@@ -108,7 +114,8 @@
 
 #ifdef HB_NO_BORING_EXPANSION
 #define HB_NO_BEYOND_64K
-#define HB_NO_AVAR2
+#define HB_NO_CUBIC_GLYF
+#define HB_NO_VAR_COMPOSITES
 #endif
 
 #ifdef HB_DISABLE_DEPRECATED
@@ -175,21 +182,27 @@
 #define HB_NO_OT_SHAPER_MYANMAR_ZAWGYI
 #endif
 
-#ifdef NDEBUG
-#ifndef HB_NDEBUG
-#define HB_NDEBUG
-#endif
+#ifdef HB_OPTIMIZE_SIZE_MORE
+#define HB_NO_OT_RULESETS_FAST_PATH
 #endif
 
-#ifdef __OPTIMIZE_SIZE__
-#ifndef HB_OPTIMIZE_SIZE
-#define HB_OPTIMIZE_SIZE
-#endif
+#ifdef HB_MINIMIZE_MEMORY_USAGE
+#define HB_NO_GDEF_CACHE
+#define HB_NO_OT_LAYOUT_LOOKUP_CACHE
+#define HB_NO_OT_FONT_ADVANCE_CACHE
+#define HB_NO_OT_FONT_CMAP_CACHE
 #endif
 
 #ifdef HB_OPTIMIZE_SIZE
-#define HB_NO_OT_LAYOUT_LOOKUP_CACHE
+#define HB_OPTIMIZE_SIZE_VAL 1
+#else
+#define HB_OPTIMIZE_SIZE_VAL 0
 #endif
 
+#ifdef HB_MINIMIZE_MEMORY_USAGE
+#define HB_MINIMIZE_MEMORY_USAGE_VAL 1
+#else
+#define HB_MINIMIZE_MEMORY_USAGE_VAL 0
+#endif
 
 #endif /* HB_CONFIG_HH */
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-debug.hh b/src/java.desktop/share/native/libharfbuzz/hb-debug.hh
index 91a24a7..341e61e 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-debug.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-debug.hh
@@ -265,8 +265,9 @@
   }
 }
 template <>
-/*static*/ inline void _hb_warn_no_return<hb_empty_t> (bool returned HB_UNUSED)
-{}
+/*static*/ inline void _hb_warn_no_return<hb_empty_t> (bool returned HB_UNUSED) {}
+template <>
+/*static*/ inline void _hb_warn_no_return<void> (bool returned HB_UNUSED) {}
 
 template <int max_level, typename ret_t>
 struct hb_auto_trace_t
@@ -389,6 +390,10 @@
 #define HB_DEBUG_UNISCRIBE (HB_DEBUG+0)
 #endif
 
+#ifndef HB_DEBUG_WASM
+#define HB_DEBUG_WASM (HB_DEBUG+0)
+#endif
+
 /*
  * With tracing.
  */
@@ -446,12 +451,26 @@
 #define HB_DEBUG_SUBSET_REPACK (HB_DEBUG+0)
 #endif
 
+#ifndef HB_DEBUG_PAINT
+#define HB_DEBUG_PAINT (HB_DEBUG+0)
+#endif
+#if HB_DEBUG_PAINT
+#define TRACE_PAINT(this) \
+  HB_UNUSED hb_auto_trace_t<HB_DEBUG_PAINT, void> trace \
+  (&c->debug_depth, c->get_name (), this, HB_FUNC, \
+   " ")
+#else
+#define TRACE_PAINT(this) HB_UNUSED hb_no_trace_t<void> trace
+#endif
+
+
 #ifndef HB_DEBUG_DISPATCH
 #define HB_DEBUG_DISPATCH ( \
         HB_DEBUG_APPLY + \
         HB_DEBUG_SANITIZE + \
         HB_DEBUG_SERIALIZE + \
         HB_DEBUG_SUBSET + \
+        HB_DEBUG_PAINT + \
         0)
 #endif
 #if HB_DEBUG_DISPATCH
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-deprecated.h b/src/java.desktop/share/native/libharfbuzz/hb-deprecated.h
index a9e63de..200e8ff 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-deprecated.h
+++ b/src/java.desktop/share/native/libharfbuzz/hb-deprecated.h
@@ -255,6 +255,52 @@
 hb_font_get_glyph_v_kerning (hb_font_t *font,
                              hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph);
 
+
+/**
+ * hb_font_get_glyph_shape_func_t:
+ * @font: #hb_font_t to work upon
+ * @font_data: @font user data pointer
+ * @glyph: The glyph ID to query
+ * @draw_funcs: The draw functions to send the shape data to
+ * @draw_data: The data accompanying the draw functions
+ * @user_data: User data pointer passed by the caller
+ *
+ * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
+ *
+ * Since: 4.0.0
+ * Deprecated: 7.0.0: Use #hb_font_draw_glyph_func_t instead
+ **/
+typedef void (*hb_font_get_glyph_shape_func_t) (hb_font_t *font, void *font_data,
+                                                hb_codepoint_t glyph,
+                                                hb_draw_funcs_t *draw_funcs, void *draw_data,
+                                                void *user_data);
+
+/**
+ * hb_font_funcs_set_glyph_shape_func:
+ * @ffuncs: A font-function structure
+ * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
+ * @user_data: Data to pass to @func
+ * @destroy: (nullable): The function to call when @user_data is not needed anymore
+ *
+ * Sets the implementation function for #hb_font_get_glyph_shape_func_t,
+ * which is the same as #hb_font_draw_glyph_func_t.
+ *
+ * Since: 4.0.0
+ * Deprecated: 7.0.0: Use hb_font_funcs_set_draw_glyph_func() instead
+ **/
+HB_DEPRECATED_FOR (hb_font_funcs_set_draw_glyph_func)
+HB_EXTERN void
+hb_font_funcs_set_glyph_shape_func (hb_font_funcs_t *ffuncs,
+                                    hb_font_get_glyph_shape_func_t func,
+                                    void *user_data, hb_destroy_func_t destroy);
+
+HB_DEPRECATED_FOR (hb_font_draw_glyph)
+HB_EXTERN void
+hb_font_get_glyph_shape (hb_font_t *font,
+                         hb_codepoint_t glyph,
+                         hb_draw_funcs_t *dfuncs, void *draw_data);
+
+
 #endif
 
 
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-draw.hh b/src/java.desktop/share/native/libharfbuzz/hb-draw.hh
index 6021ddb..e1adf9d 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-draw.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-draw.hh
@@ -93,50 +93,57 @@
                      !user_data ? nullptr : user_data->close_path); }
 
 
-  void move_to (void *draw_data, hb_draw_state_t &st,
-                float to_x, float to_y)
+  void
+  HB_ALWAYS_INLINE
+  move_to (void *draw_data, hb_draw_state_t &st,
+           float to_x, float to_y)
   {
-    if (st.path_open) close_path (draw_data, st);
+    if (unlikely (st.path_open)) close_path (draw_data, st);
     st.current_x = to_x;
     st.current_y = to_y;
   }
 
-  void line_to (void *draw_data, hb_draw_state_t &st,
-                float to_x, float to_y)
+  void
+  HB_ALWAYS_INLINE
+  line_to (void *draw_data, hb_draw_state_t &st,
+           float to_x, float to_y)
   {
-    if (!st.path_open) start_path (draw_data, st);
+    if (unlikely (!st.path_open)) start_path (draw_data, st);
     emit_line_to (draw_data, st, to_x, to_y);
     st.current_x = to_x;
     st.current_y = to_y;
   }
 
   void
+  HB_ALWAYS_INLINE
   quadratic_to (void *draw_data, hb_draw_state_t &st,
                 float control_x, float control_y,
                 float to_x, float to_y)
   {
-    if (!st.path_open) start_path (draw_data, st);
+    if (unlikely (!st.path_open)) start_path (draw_data, st);
     emit_quadratic_to (draw_data, st, control_x, control_y, to_x, to_y);
     st.current_x = to_x;
     st.current_y = to_y;
   }
 
   void
+  HB_ALWAYS_INLINE
   cubic_to (void *draw_data, hb_draw_state_t &st,
             float control1_x, float control1_y,
             float control2_x, float control2_y,
             float to_x, float to_y)
   {
-    if (!st.path_open) start_path (draw_data, st);
+    if (unlikely (!st.path_open)) start_path (draw_data, st);
     emit_cubic_to (draw_data, st, control1_x, control1_y, control2_x, control2_y, to_x, to_y);
     st.current_x = to_x;
     st.current_y = to_y;
   }
 
   void
+  HB_ALWAYS_INLINE
   close_path (void *draw_data, hb_draw_state_t &st)
   {
-    if (st.path_open)
+    if (likely (st.path_open))
     {
       if ((st.path_start_x != st.current_x) || (st.path_start_y != st.current_y))
         emit_line_to (draw_data, st, st.path_start_x, st.path_start_y);
@@ -168,6 +175,7 @@
 
   ~hb_draw_session_t () { close_path (); }
 
+  HB_ALWAYS_INLINE
   void move_to (float to_x, float to_y)
   {
     if (likely (not_slanted))
@@ -177,6 +185,7 @@
       funcs->move_to (draw_data, st,
                       to_x + to_y * slant, to_y);
   }
+  HB_ALWAYS_INLINE
   void line_to (float to_x, float to_y)
   {
     if (likely (not_slanted))
@@ -187,6 +196,7 @@
                       to_x + to_y * slant, to_y);
   }
   void
+  HB_ALWAYS_INLINE
   quadratic_to (float control_x, float control_y,
                 float to_x, float to_y)
   {
@@ -200,6 +210,7 @@
                            to_x + to_y * slant, to_y);
   }
   void
+  HB_ALWAYS_INLINE
   cubic_to (float control1_x, float control1_y,
             float control2_x, float control2_y,
             float to_x, float to_y)
@@ -215,6 +226,7 @@
                        control2_x + control2_y * slant, control2_y,
                        to_x + to_y * slant, to_y);
   }
+  HB_ALWAYS_INLINE
   void close_path ()
   {
     funcs->close_path (draw_data, st);
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-font.cc b/src/java.desktop/share/native/libharfbuzz/hb-font.cc
index 5cfed3b..9ce55bb 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-font.cc
+++ b/src/java.desktop/share/native/libharfbuzz/hb-font.cc
@@ -1066,7 +1066,7 @@
  * @glyph_stride: The stride between successive glyph IDs
  *
  * Fetches the nominal glyph IDs for a sequence of Unicode code points. Glyph
- * IDs must be returned in a #hb_codepoint_t output parameter. Stopes at the
+ * IDs must be returned in a #hb_codepoint_t output parameter. Stops at the
  * first unsupported glyph ID.
  *
  * Return value: the number of code points processed
@@ -1389,6 +1389,7 @@
   return font->get_glyph_from_name (name, len, glyph);
 }
 
+#ifndef HB_DISABLE_DEPRECATED
 /**
  * hb_font_get_glyph_shape:
  * @font: #hb_font_t to work upon
@@ -1410,6 +1411,7 @@
 {
   hb_font_draw_glyph (font, glyph, dfuncs, draw_data);
 }
+#endif
 
 /**
  * hb_font_draw_glyph:
@@ -2648,7 +2650,6 @@
       if (axes[axis_index].axisTag == tag)
         design_coords[axis_index] = v;
   }
-  font->face->table.avar->map_coords (normalized, coords_length);
 
   hb_ot_var_normalize_coords (font->face, coords_length, design_coords, normalized);
   _hb_font_adopt_var_coords (font, normalized, design_coords, coords_length);
@@ -2720,8 +2721,6 @@
     if (axes[axis_index].axisTag == tag)
       design_coords[axis_index] = value;
 
-  font->face->table.avar->map_coords (normalized, coords_length);
-
   hb_ot_var_normalize_coords (font->face, coords_length, design_coords, normalized);
   _hb_font_adopt_var_coords (font, normalized, design_coords, coords_length);
 
@@ -3058,6 +3057,7 @@
 #endif
 
 
+#ifndef HB_DISABLE_DEPRECATED
 void
 hb_font_funcs_set_glyph_shape_func (hb_font_funcs_t               *ffuncs,
                                    hb_font_get_glyph_shape_func_t  func,
@@ -3066,3 +3066,4 @@
 {
   hb_font_funcs_set_draw_glyph_func (ffuncs, func, user_data, destroy);
 }
+#endif
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-font.h b/src/java.desktop/share/native/libharfbuzz/hb-font.h
index 23301c1..f16658d 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-font.h
+++ b/src/java.desktop/share/native/libharfbuzz/hb-font.h
@@ -486,25 +486,6 @@
                                                          void *user_data);
 
 /**
- * hb_font_get_glyph_shape_func_t:
- * @font: #hb_font_t to work upon
- * @font_data: @font user data pointer
- * @glyph: The glyph ID to query
- * @draw_funcs: The draw functions to send the shape data to
- * @draw_data: The data accompanying the draw functions
- * @user_data: User data pointer passed by the caller
- *
- * A virtual method for the #hb_font_funcs_t of an #hb_font_t object.
- *
- * Since: 4.0.0
- * Deprecated: 7.0.0: Use #hb_font_draw_glyph_func_t instead
- **/
-typedef void (*hb_font_get_glyph_shape_func_t) (hb_font_t *font, void *font_data,
-                                                hb_codepoint_t glyph,
-                                                hb_draw_funcs_t *draw_funcs, void *draw_data,
-                                                void *user_data);
-
-/**
  * hb_font_draw_glyph_func_t:
  * @font: #hb_font_t to work upon
  * @font_data: @font user data pointer
@@ -804,32 +785,13 @@
                                         void *user_data, hb_destroy_func_t destroy);
 
 /**
- * hb_font_funcs_set_glyph_shape_func:
- * @ffuncs: A font-function structure
- * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
- * @user_data: Data to pass to @func
- * @destroy: (nullable): The function to call when @user_data is not needed anymore
- *
- * Sets the implementation function for #hb_font_get_glyph_shape_func_t,
- * which is the same as #hb_font_draw_glyph_func_t.
- *
- * Since: 4.0.0
- * Deprecated: 7.0.0: Use hb_font_funcs_set_draw_glyph_func() instead
- **/
-HB_EXTERN void
-hb_font_funcs_set_glyph_shape_func (hb_font_funcs_t *ffuncs,
-                                    hb_font_get_glyph_shape_func_t func,
-                                    void *user_data, hb_destroy_func_t destroy);
-
-/**
  * hb_font_funcs_set_draw_glyph_func:
  * @ffuncs: A font-function structure
  * @func: (closure user_data) (destroy destroy) (scope notified): The callback function to assign
  * @user_data: Data to pass to @func
  * @destroy: (nullable): The function to call when @user_data is not needed anymore
  *
- * Sets the implementation function for #hb_font_draw_glyph_func_t,
- * which is the same as #hb_font_get_glyph_shape_func_t.
+ * Sets the implementation function for #hb_font_draw_glyph_func_t.
  *
  * Since: 7.0.0
  **/
@@ -935,11 +897,6 @@
                              hb_codepoint_t *glyph);
 
 HB_EXTERN void
-hb_font_get_glyph_shape (hb_font_t *font,
-                         hb_codepoint_t glyph,
-                         hb_draw_funcs_t *dfuncs, void *draw_data);
-
-HB_EXTERN void
 hb_font_draw_glyph (hb_font_t *font,
                     hb_codepoint_t glyph,
                     hb_draw_funcs_t *dfuncs, void *draw_data);
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ft.cc b/src/java.desktop/share/native/libharfbuzz/hb-ft.cc
index 9b1fa8d..32f5d30 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ft.cc
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ft.cc
@@ -114,7 +114,7 @@
   ft_font->load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING;
 
   ft_font->cached_serial = (unsigned) -1;
-  ft_font->advance_cache.init ();
+  new (&ft_font->advance_cache) hb_ft_advance_cache_t;
 
   return ft_font;
 }
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-iter.hh b/src/java.desktop/share/native/libharfbuzz/hb-iter.hh
index bcd4eb8..ad45dcf 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-iter.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-iter.hh
@@ -63,6 +63,7 @@
   static constexpr bool is_iterator = true;
   static constexpr bool is_random_access_iterator = false;
   static constexpr bool is_sorted_iterator = false;
+  static constexpr bool has_fast_len = false; // Should be checked in combination with is_random_access_iterator.
 
   private:
   /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
@@ -393,7 +394,7 @@
 
   private:
   Iter it;
-  hb_reference_wrapper<Proj> f;
+  mutable hb_reference_wrapper<Proj> f;
 };
 
 template <typename Proj, hb_function_sortedness_t Sorted>
@@ -456,8 +457,8 @@
 
   private:
   Iter it;
-  hb_reference_wrapper<Pred> p;
-  hb_reference_wrapper<Proj> f;
+  mutable hb_reference_wrapper<Pred> p;
+  mutable hb_reference_wrapper<Proj> f;
 };
 template <typename Pred, typename Proj>
 struct hb_filter_iter_factory_t
@@ -841,7 +842,7 @@
   template <typename Iterable,
             hb_requires (hb_is_iterable (Iterable))>
   auto operator () (Iterable&& it, unsigned count) const HB_AUTO_RETURN
-  ( hb_zip (hb_range (count), it) | hb_map (hb_second) )
+  ( hb_zip (hb_range (count), it) | hb_map_retains_sorting (hb_second) )
 
   /* Specialization arrays. */
 
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-kern.hh b/src/java.desktop/share/native/libharfbuzz/hb-kern.hh
index fd47d56..1f2c8d5 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-kern.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-kern.hh
@@ -53,7 +53,7 @@
       return;
 
     buffer->unsafe_to_concat ();
-    OT::hb_ot_apply_context_t c (1, font, buffer);
+    OT::hb_ot_apply_context_t c (1, font, buffer, hb_blob_get_empty ());
     c.set_lookup_mask (kern_mask);
     c.set_lookup_props (OT::LookupFlag::IgnoreMarks);
     auto &skippy_iter = c.iter_input;
@@ -70,7 +70,7 @@
         continue;
       }
 
-      skippy_iter.reset (idx, 1);
+      skippy_iter.reset (idx);
       unsigned unsafe_to;
       if (!skippy_iter.next (&unsafe_to))
       {
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-limits.hh b/src/java.desktop/share/native/libharfbuzz/hb-limits.hh
index 0f60e9e..25c1e71 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-limits.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-limits.hh
@@ -89,6 +89,10 @@
 #endif
 
 
+#ifndef HB_GLYF_VAR_COMPOSITE_MAX_AXES
+#define HB_GLYF_VAR_COMPOSITE_MAX_AXES 4096
+#endif
+
 #ifndef HB_GLYF_MAX_POINTS
 #define HB_GLYF_MAX_POINTS 20000
 #endif
@@ -102,7 +106,7 @@
 #endif
 
 #ifndef HB_COLRV1_MAX_EDGE_COUNT
-#define HB_COLRV1_MAX_EDGE_COUNT 1024
+#define HB_COLRV1_MAX_EDGE_COUNT 65536
 #endif
 
 
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-machinery.hh b/src/java.desktop/share/native/libharfbuzz/hb-machinery.hh
index 3a048fc..580c9f0 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-machinery.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-machinery.hh
@@ -180,6 +180,9 @@
                                  hb_lazy_loader_t<Returned,Subclass,Data,WheresData,Stored>
                                 >::value Funcs;
 
+  hb_lazy_loader_t () = default;
+  hb_lazy_loader_t (const hb_lazy_loader_t &other) = delete;
+
   void init0 () {} /* Init, when memory is already set to 0. No-op for us. */
   void init ()  { instance.set_relaxed (nullptr); }
   void fini ()  { do_destroy (instance.get_acquire ()); init (); }
@@ -278,7 +281,11 @@
 template <typename T, unsigned int WheresFace>
 struct hb_face_lazy_loader_t : hb_lazy_loader_t<T,
                                                 hb_face_lazy_loader_t<T, WheresFace>,
-                                                hb_face_t, WheresFace> {};
+                                                hb_face_t, WheresFace>
+{
+  // Hack; have them here for API parity with hb_table_lazy_loader_t
+  hb_blob_t *get_blob () { return this->get ()->get_blob (); }
+};
 
 template <typename T, unsigned int WheresFace, bool core=false>
 struct hb_table_lazy_loader_t : hb_lazy_loader_t<T,
@@ -288,7 +295,7 @@
 {
   static hb_blob_t *create (hb_face_t *face)
   {
-    auto c = hb_sanitize_context_t ();
+    hb_sanitize_context_t c;
     if (core)
       c.set_num_glyphs (0); // So we don't recurse ad infinitum, or doesn't need num_glyphs
     return c.reference_table<T> (face);
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-map.cc b/src/java.desktop/share/native/libharfbuzz/hb-map.cc
index 48913a6..6ba943f 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-map.cc
+++ b/src/java.desktop/share/native/libharfbuzz/hb-map.cc
@@ -365,7 +365,7 @@
  * @key: (out): Key retrieved
  * @value: (out): Value retrieved
  *
- * Fetches the next key/value paire in @map.
+ * Fetches the next key/value pair in @map.
  *
  * Set @idx to -1 to get started.
  *
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-map.h b/src/java.desktop/share/native/libharfbuzz/hb-map.h
index 12d8970..b72e2ab 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-map.h
+++ b/src/java.desktop/share/native/libharfbuzz/hb-map.h
@@ -44,7 +44,7 @@
  *
  * Since: 1.7.7
  */
-#define HB_MAP_VALUE_INVALID ((hb_codepoint_t) -1)
+#define HB_MAP_VALUE_INVALID HB_CODEPOINT_INVALID
 
 /**
  * hb_map_t:
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-map.hh b/src/java.desktop/share/native/libharfbuzz/hb-map.hh
index 3b24dc9..d313237 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-map.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-map.hh
@@ -45,9 +45,9 @@
   hb_hashmap_t ()  { init (); }
   ~hb_hashmap_t () { fini (); }
 
-  hb_hashmap_t (const hb_hashmap_t& o) : hb_hashmap_t () { resize (o.population); hb_copy (o, *this); }
+  hb_hashmap_t (const hb_hashmap_t& o) : hb_hashmap_t () { alloc (o.population); hb_copy (o, *this); }
   hb_hashmap_t (hb_hashmap_t&& o) : hb_hashmap_t () { hb_swap (*this, o); }
-  hb_hashmap_t& operator= (const hb_hashmap_t& o)  { reset (); resize (o.population); hb_copy (o, *this); return *this; }
+  hb_hashmap_t& operator= (const hb_hashmap_t& o)  { reset (); alloc (o.population); hb_copy (o, *this); return *this; }
   hb_hashmap_t& operator= (hb_hashmap_t&& o)  { hb_swap (*this, o); return *this; }
 
   hb_hashmap_t (std::initializer_list<hb_pair_t<K, V>> lst) : hb_hashmap_t ()
@@ -60,29 +60,32 @@
   hb_hashmap_t (const Iterable &o) : hb_hashmap_t ()
   {
     auto iter = hb_iter (o);
-    if (iter.is_random_access_iterator)
-      resize (hb_len (iter));
+    if (iter.is_random_access_iterator || iter.has_fast_len)
+      alloc (hb_len (iter));
     hb_copy (iter, *this);
   }
 
   struct item_t
   {
     K key;
-    uint32_t hash : 30;
+    uint32_t is_real_ : 1;
     uint32_t is_used_ : 1;
-    uint32_t is_tombstone_ : 1;
+    uint32_t hash : 30;
     V value;
 
     item_t () : key (),
+                is_real_ (false), is_used_ (false),
                 hash (0),
-                is_used_ (false), is_tombstone_ (false),
                 value () {}
 
+    // Needed for https://github.com/harfbuzz/harfbuzz/issues/4138
+    K& get_key () { return key; }
+    V& get_value () { return value; }
+
     bool is_used () const { return is_used_; }
     void set_used (bool is_used) { is_used_ = is_used; }
-    bool is_tombstone () const { return is_tombstone_; }
-    void set_tombstone (bool is_tombstone) { is_tombstone_ = is_tombstone; }
-    bool is_real () const { return is_used_ && !is_tombstone_; }
+    void set_real (bool is_real) { is_real_ = is_real; }
+    bool is_real () const { return is_real_; }
 
     template <bool v = minus_one,
               hb_enable_if (v == false)>
@@ -98,10 +101,15 @@
     bool operator == (const K &o) const { return hb_deref (key) == hb_deref (o); }
     bool operator == (const item_t &o) const { return *this == o.key; }
     hb_pair_t<K, V> get_pair() const { return hb_pair_t<K, V> (key, value); }
-    hb_pair_t<const K &, const V &> get_pair_ref() const { return hb_pair_t<const K &, const V &> (key, value); }
+    hb_pair_t<const K &, V &> get_pair_ref() { return hb_pair_t<const K &, V &> (key, value); }
 
     uint32_t total_hash () const
-    { return (hash * 31) + hb_hash (value); }
+    { return (hash * 31u) + hb_hash (value); }
+
+    static constexpr bool is_trivial = hb_is_trivially_constructible(K) &&
+                                       hb_is_trivially_destructible(K) &&
+                                       hb_is_trivially_constructible(V) &&
+                                       hb_is_trivially_destructible(V);
   };
 
   hb_object_header_t header;
@@ -110,6 +118,7 @@
   unsigned int occupancy; /* Including tombstones. */
   unsigned int mask;
   unsigned int prime;
+  unsigned int max_chain_length;
   item_t *items;
 
   friend void swap (hb_hashmap_t& a, hb_hashmap_t& b)
@@ -123,6 +132,7 @@
     hb_swap (a.occupancy, b.occupancy);
     hb_swap (a.mask, b.mask);
     hb_swap (a.prime, b.prime);
+    hb_swap (a.max_chain_length, b.max_chain_length);
     hb_swap (a.items, b.items);
   }
   void init ()
@@ -133,16 +143,19 @@
     population = occupancy = 0;
     mask = 0;
     prime = 0;
+    max_chain_length = 0;
     items = nullptr;
   }
   void fini ()
   {
     hb_object_fini (this);
 
-    if (likely (items)) {
+    if (likely (items))
+    {
       unsigned size = mask + 1;
-      for (unsigned i = 0; i < size; i++)
-        items[i].~item_t ();
+      if (!item_t::is_trivial)
+        for (unsigned i = 0; i < size; i++)
+          items[i].~item_t ();
       hb_free (items);
       items = nullptr;
     }
@@ -157,7 +170,7 @@
 
   bool in_error () const { return !successful; }
 
-  bool resize (unsigned new_population = 0)
+  bool alloc (unsigned new_population = 0)
   {
     if (unlikely (!successful)) return false;
 
@@ -171,8 +184,11 @@
       successful = false;
       return false;
     }
-    for (auto &_ : hb_iter (new_items, new_size))
-      new (&_) item_t ();
+    if (!item_t::is_trivial)
+      for (auto &_ : hb_iter (new_items, new_size))
+        new (&_) item_t ();
+    else
+      hb_memset (new_items, 0, (size_t) new_size * sizeof (item_t));
 
     unsigned int old_size = size ();
     item_t *old_items = items;
@@ -181,6 +197,7 @@
     population = occupancy = 0;
     mask = new_size - 1;
     prime = prime_for (power);
+    max_chain_length = power * 2;
     items = new_items;
 
     /* Insert back old items. */
@@ -192,7 +209,8 @@
                        old_items[i].hash,
                        std::move (old_items[i].value));
       }
-      old_items[i].~item_t ();
+      if (!item_t::is_trivial)
+        old_items[i].~item_t ();
     }
 
     hb_free (old_items);
@@ -201,72 +219,129 @@
   }
 
   template <typename KK, typename VV>
-  bool set_with_hash (KK&& key, uint32_t hash, VV&& value, bool is_delete=false)
+  bool set_with_hash (KK&& key, uint32_t hash, VV&& value, bool overwrite = true)
   {
     if (unlikely (!successful)) return false;
-    if (unlikely ((occupancy + occupancy / 2) >= mask && !resize ())) return false;
-    item_t &item = item_for_hash (key, hash);
+    if (unlikely ((occupancy + occupancy / 2) >= mask && !alloc ())) return false;
 
-    if (is_delete && !(item == key))
-      return true; /* Trying to delete non-existent key. */
+    hash &= 0x3FFFFFFF; // We only store lower 30bit of hash
+    unsigned int tombstone = (unsigned int) -1;
+    unsigned int i = hash % prime;
+    unsigned length = 0;
+    unsigned step = 0;
+    while (items[i].is_used ())
+    {
+      if ((std::is_integral<K>::value || items[i].hash == hash) &&
+          items[i] == key)
+      {
+        if (!overwrite)
+          return false;
+        else
+          break;
+      }
+      if (!items[i].is_real () && tombstone == (unsigned) -1)
+        tombstone = i;
+      i = (i + ++step) & mask;
+      length++;
+    }
+
+    item_t &item = items[tombstone == (unsigned) -1 ? i : tombstone];
 
     if (item.is_used ())
     {
       occupancy--;
-      if (!item.is_tombstone ())
-        population--;
+      population -= item.is_real ();
     }
 
     item.key = std::forward<KK> (key);
     item.value = std::forward<VV> (value);
     item.hash = hash;
     item.set_used (true);
-    item.set_tombstone (is_delete);
+    item.set_real (true);
 
     occupancy++;
-    if (!is_delete)
-      population++;
+    population++;
+
+    if (unlikely (length > max_chain_length) && occupancy * 8 > mask)
+      alloc (mask - 8); // This ensures we jump to next larger size
 
     return true;
   }
 
   template <typename VV>
-  bool set (const K &key, VV&& value) { return set_with_hash (key, hb_hash (key), std::forward<VV> (value)); }
+  bool set (const K &key, VV&& value, bool overwrite = true) { return set_with_hash (key, hb_hash (key), std::forward<VV> (value), overwrite); }
   template <typename VV>
-  bool set (K &&key, VV&& value) { return set_with_hash (std::move (key), hb_hash (key), std::forward<VV> (value)); }
+  bool set (K &&key, VV&& value, bool overwrite = true)
+  {
+    uint32_t hash = hb_hash (key);
+    return set_with_hash (std::move (key), hash, std::forward<VV> (value), overwrite);
+  }
+  bool add (const K &key)
+  {
+    uint32_t hash = hb_hash (key);
+    return set_with_hash (key, hash, item_t::default_value ());
+  }
 
   const V& get_with_hash (const K &key, uint32_t hash) const
   {
-    if (unlikely (!items)) return item_t::default_value ();
-    auto &item = item_for_hash (key, hash);
-    return item.is_real () && item == key ? item.value : item_t::default_value ();
+    if (!items) return item_t::default_value ();
+    auto *item = fetch_item (key, hb_hash (key));
+    if (item)
+      return item->value;
+    return item_t::default_value ();
   }
   const V& get (const K &key) const
   {
-    if (unlikely (!items)) return item_t::default_value ();
+    if (!items) return item_t::default_value ();
     return get_with_hash (key, hb_hash (key));
   }
 
-  void del (const K &key) { set_with_hash (key, hb_hash (key), item_t::default_value (), true); }
+  void del (const K &key)
+  {
+    if (!items) return;
+    auto *item = fetch_item (key, hb_hash (key));
+    if (item)
+    {
+      item->set_real (false);
+      population--;
+    }
+  }
 
   /* Has interface. */
   const V& operator [] (K k) const { return get (k); }
   template <typename VV=V>
-  bool has (K key, VV **vp = nullptr) const
+  bool has (const K &key, VV **vp = nullptr) const
   {
-    if (unlikely (!items))
-      return false;
-    auto &item = item_for_hash (key, hb_hash (key));
-    if (item.is_real () && item == key)
+    if (!items) return false;
+    auto *item = fetch_item (key, hb_hash (key));
+    if (item)
     {
-      if (vp) *vp = std::addressof (item.value);
+      if (vp) *vp = std::addressof (item->value);
       return true;
     }
-    else
-      return false;
+    return false;
+  }
+  item_t *fetch_item (const K &key, uint32_t hash) const
+  {
+    hash &= 0x3FFFFFFF; // We only store lower 30bit of hash
+    unsigned int i = hash % prime;
+    unsigned step = 0;
+    while (items[i].is_used ())
+    {
+      if ((std::is_integral<K>::value || items[i].hash == hash) &&
+          items[i] == key)
+      {
+        if (items[i].is_real ())
+          return &items[i];
+        else
+          return nullptr;
+      }
+      i = (i + ++step) & mask;
+    }
+    return nullptr;
   }
   /* Projection. */
-  V operator () (K k) const { return get (k); }
+  const V& operator () (K k) const { return get (k); }
 
   unsigned size () const { return mask ? mask + 1 : 0; }
 
@@ -323,39 +398,37 @@
 
   auto iter_items () const HB_AUTO_RETURN
   (
-    + hb_iter (items, size ())
+    + hb_iter (items, this->size ())
     | hb_filter (&item_t::is_real)
   )
   auto iter_ref () const HB_AUTO_RETURN
   (
-    + iter_items ()
+    + this->iter_items ()
     | hb_map (&item_t::get_pair_ref)
   )
   auto iter () const HB_AUTO_RETURN
   (
-    + iter_items ()
+    + this->iter_items ()
     | hb_map (&item_t::get_pair)
   )
   auto keys_ref () const HB_AUTO_RETURN
   (
-    + iter_items ()
-    | hb_map (&item_t::key)
+    + this->iter_items ()
+    | hb_map (&item_t::get_key)
   )
   auto keys () const HB_AUTO_RETURN
   (
-    + iter_items ()
-    | hb_map (&item_t::key)
+    + this->keys_ref ()
     | hb_map (hb_ridentity)
   )
   auto values_ref () const HB_AUTO_RETURN
   (
-    + iter_items ()
-    | hb_map (&item_t::value)
+    + this->iter_items ()
+    | hb_map (&item_t::get_value)
   )
   auto values () const HB_AUTO_RETURN
   (
-    + iter_items ()
-    | hb_map (&item_t::value)
+    + this->values_ref ()
     | hb_map (hb_ridentity)
   )
 
@@ -393,23 +466,6 @@
   hb_hashmap_t& operator << (const hb_pair_t<K&&, V&&>& v)
   { set (std::move (v.first), std::move (v.second)); return *this; }
 
-  item_t& item_for_hash (const K &key, uint32_t hash) const
-  {
-    hash &= 0x3FFFFFFF; // We only store lower 30bit of hash
-    unsigned int i = hash % prime;
-    unsigned int step = 0;
-    unsigned int tombstone = (unsigned) -1;
-    while (items[i].is_used ())
-    {
-      if (items[i].hash == hash && items[i] == key)
-        return items[i];
-      if (tombstone == (unsigned) -1 && items[i].is_tombstone ())
-        tombstone = i;
-      i = (i + ++step) & mask;
-    }
-    return items[tombstone == (unsigned) -1 ? i : tombstone];
-  }
-
   static unsigned int prime_for (unsigned int shift)
   {
     /* Following comment and table copied from glib. */
@@ -480,7 +536,7 @@
   hb_map_t (hb_map_t &&o) : hashmap (std::move ((hashmap &) o)) {}
   hb_map_t& operator= (const hb_map_t&) = default;
   hb_map_t& operator= (hb_map_t&&) = default;
-  hb_map_t (std::initializer_list<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> lst) : hashmap (lst) {}
+  hb_map_t (std::initializer_list<hb_codepoint_pair_t> lst) : hashmap (lst) {}
   template <typename Iterable,
             hb_requires (hb_is_iterable (Iterable))>
   hb_map_t (const Iterable &o) : hashmap (o) {}
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-meta.hh b/src/java.desktop/share/native/libharfbuzz/hb-meta.hh
index 44f1ca3..c3af0e7 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-meta.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-meta.hh
@@ -153,8 +153,8 @@
   hb_reference_wrapper (T v) : v (v) {}
   bool operator == (const hb_reference_wrapper& o) const { return v == o.v; }
   bool operator != (const hb_reference_wrapper& o) const { return v != o.v; }
-  operator T () const { return v; }
-  T get () const { return v; }
+  operator T& () { return v; }
+  T& get () { return v; }
   T v;
 };
 template <typename T>
@@ -163,8 +163,8 @@
   hb_reference_wrapper (T& v) : v (std::addressof (v)) {}
   bool operator == (const hb_reference_wrapper& o) const { return v == o.v; }
   bool operator != (const hb_reference_wrapper& o) const { return v != o.v; }
-  operator T& () const { return *v; }
-  T& get () const { return *v; }
+  operator T& () { return *v; }
+  T& get () { return *v; }
   T* v;
 };
 
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-multimap.hh b/src/java.desktop/share/native/libharfbuzz/hb-multimap.hh
index b4a8cc6..0184279 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-multimap.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-multimap.hh
@@ -38,10 +38,10 @@
 {
   void add (hb_codepoint_t k, hb_codepoint_t v)
   {
-    hb_codepoint_t *i;
-    if (multiples_indices.has (k, &i))
+    hb_vector_t<hb_codepoint_t> *m;
+    if (multiples.has (k, &m))
     {
-      multiples_values[*i].push (v);
+      m->push (v);
       return;
     }
 
@@ -51,12 +51,7 @@
       hb_codepoint_t old = *old_v;
       singulars.del (k);
 
-      multiples_indices.set (k, multiples_values.length);
-      auto *vec = multiples_values.push ();
-
-      vec->push (old);
-      vec->push (v);
-
+      multiples.set (k, hb_vector_t<hb_codepoint_t> {old, v});
       return;
     }
 
@@ -69,22 +64,31 @@
     if (singulars.has (k, &v))
       return hb_array (v, 1);
 
-    hb_codepoint_t *i;
-    if (multiples_indices.has (k, &i))
-      return multiples_values[*i].as_array ();
+    hb_vector_t<hb_codepoint_t> *m;
+    if (multiples.has (k, &m))
+      return m->as_array ();
 
     return hb_array_t<const hb_codepoint_t> ();
   }
 
   bool in_error () const
   {
-    return singulars.in_error () || multiples_indices.in_error () || multiples_values.in_error ();
+    if (singulars.in_error () || multiples.in_error ())
+      return true;
+    for (const auto &m : multiples.values_ref ())
+      if (m.in_error ())
+        return true;
+    return false;
+  }
+
+  void alloc (unsigned size)
+  {
+    singulars.alloc (size);
   }
 
   protected:
   hb_map_t singulars;
-  hb_map_t multiples_indices;
-  hb_vector_t<hb_vector_t<hb_codepoint_t>> multiples_values;
+  hb_hashmap_t<hb_codepoint_t, hb_vector_t<hb_codepoint_t>> multiples;
 };
 
 
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-null.hh b/src/java.desktop/share/native/libharfbuzz/hb-null.hh
index 8a9ebbf..4a5270e 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-null.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-null.hh
@@ -37,7 +37,7 @@
 
 /* Global nul-content Null pool.  Enlarge as necessary. */
 
-#define HB_NULL_POOL_SIZE 448
+#define HB_NULL_POOL_SIZE 640
 
 template <typename T, typename>
 struct _hb_has_min_size : hb_false_type {};
@@ -85,7 +85,7 @@
 template <typename T, typename>
 struct _hb_static_size : hb_integral_constant<unsigned, sizeof (T)> {};
 template <typename T>
-struct _hb_static_size<T, hb_void_t<decltype (T::min_size)>> : hb_integral_constant<unsigned, T::static_size> {};
+struct _hb_static_size<T, hb_void_t<decltype (T::static_size)>> : hb_integral_constant<unsigned, T::static_size> {};
 template <typename T>
 using hb_static_size = _hb_static_size<T, void>;
 #define hb_static_size(T) hb_static_size<T>::value
@@ -176,7 +176,7 @@
 static inline Type& Crap () {
   static_assert (hb_null_size (Type) <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE.");
   Type *obj = reinterpret_cast<Type *> (_hb_CrapPool);
-  memcpy (obj, &Null (Type), sizeof (*obj));
+  memcpy (obj, std::addressof (Null (Type)), sizeof (*obj));
   return *obj;
 }
 template <typename QType>
@@ -211,11 +211,11 @@
   T * operator = (T *v_)   { return v = v_; }
   T * operator -> () const { return get (); }
   T & operator * () const  { return *get (); }
-  T ** operator & () const { return &v; }
+  T ** operator & () const { return std::addressof (v); }
   /* Only auto-cast to const types. */
   template <typename C> operator const C * () const { return get (); }
   operator const char * () const { return (const char *) get (); }
-  T * get () const { return v ? v : const_cast<T *> (&Null (T)); }
+  T * get () const { return v ? v : const_cast<T *> (std::addressof (Null (T))); }
   T * get_raw () const { return v; }
 
   private:
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-number-parser.hh b/src/java.desktop/share/native/libharfbuzz/hb-number-parser.hh
index 07f3ebe..9d2867e 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-number-parser.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-number-parser.hh
@@ -31,7 +31,7 @@
 #include "hb.hh"
 
 
-#line 32 "hb-number-parser.hh"
+#line 35 "hb-number-parser.hh"
 static const unsigned char _double_parser_trans_keys[] = {
         0u, 0u, 43u, 57u, 46u, 57u, 48u, 57u, 43u, 57u, 48u, 57u, 48u, 101u, 48u, 57u,
         46u, 101u, 0
@@ -135,12 +135,12 @@
 
   int cs;
 
-#line 132 "hb-number-parser.hh"
+#line 139 "hb-number-parser.hh"
         {
         cs = double_parser_start;
         }
 
-#line 135 "hb-number-parser.hh"
+#line 144 "hb-number-parser.hh"
         {
         int _slen;
         int _trans;
@@ -198,7 +198,7 @@
           exp_overflow = true;
 }
         break;
-#line 187 "hb-number-parser.hh"
+#line 202 "hb-number-parser.hh"
         }
 
 _again:
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-open-file.hh b/src/java.desktop/share/native/libharfbuzz/hb-open-file.hh
index c02eb41..387b143 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-open-file.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-open-file.hh
@@ -131,7 +131,7 @@
     sfnt_version = sfnt_tag;
     /* Take space for numTables, searchRange, entrySelector, RangeShift
      * and the TableRecords themselves.  */
-    unsigned num_items = it.len ();
+    unsigned num_items = hb_len (it);
     if (unlikely (!tables.serialize (c, num_items))) return_trace (false);
 
     const char *dir_end = (const char *) c->head;
@@ -145,7 +145,7 @@
       unsigned len = blob->length;
 
       /* Allocate room for the table and copy it. */
-      char *start = (char *) c->allocate_size<void> (len);
+      char *start = (char *) c->allocate_size<void> (len, false);
       if (unlikely (!start)) return false;
 
       TableRecord &rec = tables.arrayZ[i];
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-open-type.hh b/src/java.desktop/share/native/libharfbuzz/hb-open-type.hh
index 4639d80..25142da 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-open-type.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-open-type.hh
@@ -312,6 +312,8 @@
 template <typename Type, typename OffsetType, bool has_null=true>
 struct OffsetTo : Offset<OffsetType, has_null>
 {
+  using target_t = Type;
+
   // Make sure Type is not unbounded; works only for types that are fully defined at OffsetTo time.
   static_assert (has_null == false ||
                  (hb_has_null_size (Type) || !hb_has_min_size (Type)), "");
@@ -416,12 +418,15 @@
   {
     TRACE_SANITIZE (this);
     if (unlikely (!c->check_struct (this))) return_trace (false);
-    if (unlikely (this->is_null ())) return_trace (true);
+    //if (unlikely (this->is_null ())) return_trace (true);
     if (unlikely ((const char *) base + (unsigned) *this < (const char *) base)) return_trace (false);
     return_trace (true);
   }
 
   template <typename ...Ts>
+#ifndef HB_OPTIMIZE_SIZE
+  HB_ALWAYS_INLINE
+#endif
   bool sanitize (hb_sanitize_context_t *c, const void *base, Ts&&... ds) const
   {
     TRACE_SANITIZE (this);
@@ -462,24 +467,16 @@
 
   HB_DELETE_CREATE_COPY_ASSIGN (UnsizedArrayOf);
 
-  const Type& operator [] (int i_) const
+  const Type& operator [] (unsigned int i) const
   {
-    unsigned int i = (unsigned int) i_;
-    const Type *p = &arrayZ[i];
-    if (unlikely ((const void *) p < (const void *) arrayZ)) return Null (Type); /* Overflowed. */
-    _hb_compiler_memory_r_barrier ();
-    return *p;
+    return arrayZ[i];
   }
-  Type& operator [] (int i_)
+  Type& operator [] (unsigned int i)
   {
-    unsigned int i = (unsigned int) i_;
-    Type *p = &arrayZ[i];
-    if (unlikely ((const void *) p < (const void *) arrayZ)) return Crap (Type); /* Overflowed. */
-    _hb_compiler_memory_r_barrier ();
-    return *p;
+    return arrayZ[i];
   }
 
-  unsigned int get_size (unsigned int len) const
+  static unsigned int get_size (unsigned int len)
   { return len * Type::static_size; }
 
   template <typename T> operator T * () { return arrayZ; }
@@ -533,6 +530,7 @@
   }
 
   template <typename ...Ts>
+  HB_ALWAYS_INLINE
   bool sanitize (hb_sanitize_context_t *c, unsigned int count, Ts&&... ds) const
   {
     TRACE_SANITIZE (this);
@@ -721,6 +719,7 @@
   }
 
   template <typename ...Ts>
+  HB_ALWAYS_INLINE
   bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
   {
     TRACE_SANITIZE (this);
@@ -736,7 +735,7 @@
   bool sanitize_shallow (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (len.sanitize (c) && c->check_array (arrayZ, len));
+    return_trace (len.sanitize (c) && c->check_array_sized (arrayZ, len, sizeof (LenType)));
   }
 
   public:
@@ -797,7 +796,7 @@
 using List16OfOffset16To = List16OfOffsetTo<Type, HBUINT16>;
 
 /* An array starting at second element. */
-template <typename Type, typename LenType=HBUINT16>
+template <typename Type, typename LenType>
 struct HeadlessArrayOf
 {
   static constexpr unsigned item_size = Type::static_size;
@@ -861,6 +860,7 @@
   }
 
   template <typename ...Ts>
+  HB_ALWAYS_INLINE
   bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
   {
     TRACE_SANITIZE (this);
@@ -878,7 +878,7 @@
   {
     TRACE_SANITIZE (this);
     return_trace (lenP1.sanitize (c) &&
-                  (!lenP1 || c->check_array (arrayZ, lenP1 - 1)));
+                  (!lenP1 || c->check_array_sized (arrayZ, lenP1 - 1, sizeof (LenType))));
   }
 
   public:
@@ -887,6 +887,7 @@
   public:
   DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ);
 };
+template <typename Type> using HeadlessArray16Of = HeadlessArrayOf<Type, HBUINT16>;
 
 /* An array storing length-1. */
 template <typename Type, typename LenType=HBUINT16>
@@ -912,6 +913,7 @@
   { return lenM1.static_size + (lenM1 + 1) * Type::static_size; }
 
   template <typename ...Ts>
+  HB_ALWAYS_INLINE
   bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
   {
     TRACE_SANITIZE (this);
@@ -929,7 +931,7 @@
   {
     TRACE_SANITIZE (this);
     return_trace (lenM1.sanitize (c) &&
-                  (c->check_array (arrayZ, lenM1 + 1)));
+                  (c->check_array_sized (arrayZ, lenM1 + 1, sizeof (LenType))));
   }
 
   public:
@@ -1096,6 +1098,7 @@
   { return header.static_size + header.nUnits * header.unitSize; }
 
   template <typename ...Ts>
+  HB_ALWAYS_INLINE
   bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
   {
     TRACE_SANITIZE (this);
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff-common.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff-common.hh
index d31a328..081c333 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff-common.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff-common.hh
@@ -48,12 +48,24 @@
 
 struct code_pair_t
 {
-  hb_codepoint_t code;
+  unsigned code;
   hb_codepoint_t glyph;
 };
 
+
 using str_buff_t = hb_vector_t<unsigned char>;
 using str_buff_vec_t = hb_vector_t<str_buff_t>;
+using glyph_to_sid_map_t = hb_vector_t<code_pair_t>;
+
+struct length_f_t
+{
+  template <typename Iterable,
+            hb_requires (hb_is_iterable (Iterable))>
+  unsigned operator () (const Iterable &_) const { return hb_len (hb_iter (_)); }
+
+  unsigned operator () (unsigned _) const { return _; }
+}
+HB_FUNCOBJ (length_f);
 
 /* CFF INDEX */
 template <typename COUNT>
@@ -62,42 +74,52 @@
   unsigned int offset_array_size () const
   { return offSize * (count + 1); }
 
-  CFFIndex *copy (hb_serialize_context_t *c) const
-  {
-    TRACE_SERIALIZE (this);
-    unsigned int size = get_size ();
-    CFFIndex *out = c->allocate_size<CFFIndex> (size, false);
-    if (likely (out))
-      hb_memcpy (out, this, size);
-    return_trace (out);
-  }
-
   template <typename Iterable,
             hb_requires (hb_is_iterable (Iterable))>
   bool serialize (hb_serialize_context_t *c,
-                  const Iterable &iterable)
+                  const Iterable &iterable,
+                  const unsigned *p_data_size = nullptr)
   {
     TRACE_SERIALIZE (this);
+    unsigned data_size;
+    if (p_data_size)
+      data_size = *p_data_size;
+    else
+      total_size (iterable, &data_size);
+
     auto it = hb_iter (iterable);
-    serialize_header(c, + it | hb_map (hb_iter) | hb_map (hb_len));
+    if (unlikely (!serialize_header (c, +it, data_size))) return_trace (false);
+    unsigned char *ret = c->allocate_size<unsigned char> (data_size, false);
+    if (unlikely (!ret)) return_trace (false);
     for (const auto &_ : +it)
-      hb_iter (_).copy (c);
+    {
+      unsigned len = _.length;
+      if (!len)
+        continue;
+      if (len <= 1)
+      {
+        *ret++ = *_.arrayZ;
+        continue;
+      }
+      hb_memcpy (ret, _.arrayZ, len);
+      ret += len;
+    }
     return_trace (true);
   }
 
   template <typename Iterator,
             hb_requires (hb_is_iterator (Iterator))>
   bool serialize_header (hb_serialize_context_t *c,
-                        Iterator it)
+                         Iterator it,
+                         unsigned data_size)
   {
     TRACE_SERIALIZE (this);
 
-    unsigned total = + it | hb_reduce (hb_add, 0);
-    unsigned off_size = (hb_bit_storage (total + 1) + 7) / 8;
+    unsigned off_size = (hb_bit_storage (data_size + 1) + 7) / 8;
 
     /* serialize CFFIndex header */
     if (unlikely (!c->extend_min (this))) return_trace (false);
-    this->count = it.len ();
+    this->count = hb_len (it);
     if (!this->count) return_trace (true);
     if (unlikely (!c->extend (this->offSize))) return_trace (false);
     this->offSize = off_size;
@@ -106,25 +128,88 @@
 
     /* serialize indices */
     unsigned int offset = 1;
-    unsigned int i = 0;
-    for (unsigned _ : +it)
+    if (HB_OPTIMIZE_SIZE_VAL)
     {
-      set_offset_at (i++, offset);
-      offset += _;
+      unsigned int i = 0;
+      for (const auto &_ : +it)
+      {
+        set_offset_at (i++, offset);
+        offset += length_f (_);
+      }
+      set_offset_at (i, offset);
     }
-    set_offset_at (i, offset);
+    else
+      switch (off_size)
+      {
+        case 1:
+        {
+          HBUINT8 *p = (HBUINT8 *) offsets;
+          for (const auto &_ : +it)
+          {
+            *p++ = offset;
+            offset += length_f (_);
+          }
+          *p = offset;
+        }
+        break;
+        case 2:
+        {
+          HBUINT16 *p = (HBUINT16 *) offsets;
+          for (const auto &_ : +it)
+          {
+            *p++ = offset;
+            offset += length_f (_);
+          }
+          *p = offset;
+        }
+        break;
+        case 3:
+        {
+          HBUINT24 *p = (HBUINT24 *) offsets;
+          for (const auto &_ : +it)
+          {
+            *p++ = offset;
+            offset += length_f (_);
+          }
+          *p = offset;
+        }
+        break;
+        case 4:
+        {
+          HBUINT32 *p = (HBUINT32 *) offsets;
+          for (const auto &_ : +it)
+          {
+            *p++ = offset;
+            offset += length_f (_);
+          }
+          *p = offset;
+        }
+        break;
+        default:
+        break;
+      }
 
+    assert (offset == data_size + 1);
     return_trace (true);
   }
 
   template <typename Iterable,
             hb_requires (hb_is_iterable (Iterable))>
-  static unsigned total_size (const Iterable &iterable)
+  static unsigned total_size (const Iterable &iterable, unsigned *data_size = nullptr)
   {
-    auto it = + hb_iter (iterable) | hb_map (hb_iter) | hb_map (hb_len);
-    if (!it) return 0;
+    auto it = + hb_iter (iterable);
+    if (!it)
+    {
+      if (data_size) *data_size = 0;
+      return min_size;
+    }
 
-    unsigned total = + it | hb_reduce (hb_add, 0);
+    unsigned total = 0;
+    for (const auto &_ : +it)
+      total += length_f (_);
+
+    if (data_size) *data_size = total;
+
     unsigned off_size = (hb_bit_storage (total + 1) + 7) / 8;
 
     return min_size + HBUINT8::static_size + (hb_len (it) + 1) * off_size + total;
@@ -133,13 +218,16 @@
   void set_offset_at (unsigned int index, unsigned int offset)
   {
     assert (index <= count);
-    HBUINT8 *p = offsets + offSize * index + offSize;
+
     unsigned int size = offSize;
-    for (; size; size--)
+    const HBUINT8 *p = offsets;
+    switch (size)
     {
-      --p;
-      *p = offset & 0xFF;
-      offset >>= 8;
+      case 1: ((HBUINT8  *) p)[index] = offset; break;
+      case 2: ((HBUINT16 *) p)[index] = offset; break;
+      case 3: ((HBUINT24 *) p)[index] = offset; break;
+      case 4: ((HBUINT32 *) p)[index] = offset; break;
+      default: return;
     }
   }
 
@@ -149,37 +237,30 @@
     assert (index <= count);
 
     unsigned int size = offSize;
-    const HBUINT8 *p = offsets + size * index;
+    const HBUINT8 *p = offsets;
     switch (size)
     {
-      case 1: return * (HBUINT8  *) p;
-      case 2: return * (HBUINT16 *) p;
-      case 3: return * (HBUINT24 *) p;
-      case 4: return * (HBUINT32 *) p;
+      case 1: return ((HBUINT8  *) p)[index];
+      case 2: return ((HBUINT16 *) p)[index];
+      case 3: return ((HBUINT24 *) p)[index];
+      case 4: return ((HBUINT32 *) p)[index];
       default: return 0;
     }
   }
 
-  unsigned int length_at (unsigned int index) const
-  {
-    unsigned offset0 = offset_at (index);
-    unsigned offset1 = offset_at (index + 1);
-    if (unlikely (offset1 < offset0 || offset1 > offset_at (count)))
-      return 0;
-    return offset1 - offset0;
-  }
-
   const unsigned char *data_base () const
-  { return (const unsigned char *) this + min_size + offSize.static_size + offset_array_size (); }
+  { return (const unsigned char *) this + min_size + offSize.static_size - 1 + offset_array_size (); }
   public:
 
   hb_ubytes_t operator [] (unsigned int index) const
   {
     if (unlikely (index >= count)) return hb_ubytes_t ();
     _hb_compiler_memory_r_barrier ();
-    unsigned length = length_at (index);
-    if (unlikely (!length)) return hb_ubytes_t ();
-    return hb_ubytes_t (data_base () + offset_at (index) - 1, length);
+    unsigned offset0 = offset_at (index);
+    unsigned offset1 = offset_at (index + 1);
+    if (unlikely (offset1 < offset0 || offset1 > offset_at (count)))
+      return hb_ubytes_t ();
+    return hb_ubytes_t (data_base () + offset0, offset1 - offset0);
   }
 
   unsigned int get_size () const
@@ -197,7 +278,7 @@
                            (count < count + 1u &&
                             c->check_struct (&offSize) && offSize >= 1 && offSize <= 4 &&
                             c->check_array (offsets, offSize, count + 1u) &&
-                            c->check_array ((const HBUINT8*) data_base (), 1, offset_at (count) - 1)))));
+                            c->check_array ((const HBUINT8*) data_base (), 1, offset_at (count))))));
   }
 
   public:
@@ -211,47 +292,6 @@
   DEFINE_SIZE_MIN (COUNT::static_size);
 };
 
-template <typename COUNT, typename TYPE>
-struct CFFIndexOf : CFFIndex<COUNT>
-{
-  template <typename DATA, typename PARAM1, typename PARAM2>
-  bool serialize (hb_serialize_context_t *c,
-                  unsigned int offSize_,
-                  const DATA *dataArray,
-                  unsigned int dataArrayLen,
-                  const hb_vector_t<unsigned int> &dataSizeArray,
-                  const PARAM1 &param1,
-                  const PARAM2 &param2)
-  {
-    TRACE_SERIALIZE (this);
-    /* serialize CFFIndex header */
-    if (unlikely (!c->extend_min (this))) return_trace (false);
-    this->count = dataArrayLen;
-    this->offSize = offSize_;
-    if (unlikely (!c->allocate_size<HBUINT8> (offSize_ * (dataArrayLen + 1), false)))
-      return_trace (false);
-
-    /* serialize indices */
-    unsigned int  offset = 1;
-    unsigned int  i = 0;
-    for (; i < dataArrayLen; i++)
-    {
-      this->set_offset_at (i, offset);
-      offset += dataSizeArray[i];
-    }
-    this->set_offset_at (i, offset);
-
-    /* serialize data */
-    for (unsigned int i = 0; i < dataArrayLen; i++)
-    {
-      TYPE *dest = c->start_embed<TYPE> ();
-      if (unlikely (!dest || !dest->serialize (c, dataArray[i], param1, param2)))
-        return_trace (false);
-    }
-    return_trace (true);
-  }
-};
-
 /* Top Dict, Font Dict, Private Dict */
 struct Dict : UnsizedByteStr
 {
@@ -327,7 +367,7 @@
 };
 
 template <typename COUNT>
-struct FDArray : CFFIndexOf<COUNT, FontDict>
+struct FDArray : CFFIndex<COUNT>
 {
   template <typename DICTVAL, typename INFO, typename Iterator, typename OP_SERIALIZER>
   bool serialize (hb_serialize_context_t *c,
@@ -338,7 +378,11 @@
 
     /* serialize INDEX data */
     hb_vector_t<unsigned> sizes;
+    if (it.is_random_access_iterator)
+      sizes.alloc (hb_len (it));
+
     c->push ();
+    char *data_base = c->head;
     + it
     | hb_map ([&] (const hb_pair_t<const DICTVAL&, const INFO&> &_)
     {
@@ -348,10 +392,16 @@
               })
     | hb_sink (sizes)
     ;
+    unsigned data_size = c->head - data_base;
     c->pop_pack (false);
 
+    if (unlikely (sizes.in_error ())) return_trace (false);
+
+    /* It just happens that the above is packed right after the header below.
+     * Such a hack. */
+
     /* serialize INDEX header */
-    return_trace (CFFIndex<COUNT>::serialize_header (c, hb_iter (sizes)));
+    return_trace (CFFIndex<COUNT>::serialize_header (c, hb_iter (sizes), data_size));
   }
 };
 
@@ -368,8 +418,11 @@
     return_trace (true);
   }
 
-  hb_codepoint_t get_fd (hb_codepoint_t glyph) const
-  { return (hb_codepoint_t) fds[glyph]; }
+  unsigned get_fd (hb_codepoint_t glyph) const
+  { return fds[glyph]; }
+
+  hb_pair_t<unsigned, hb_codepoint_t> get_fd_range (hb_codepoint_t glyph) const
+  { return {fds[glyph], glyph + 1}; }
 
   unsigned int get_size (unsigned int num_glyphs) const
   { return HBUINT8::static_size * num_glyphs; }
@@ -427,12 +480,20 @@
     return +1;
   }
 
-  hb_codepoint_t get_fd (hb_codepoint_t glyph) const
+  unsigned get_fd (hb_codepoint_t glyph) const
   {
     auto *range = hb_bsearch (glyph, &ranges[0], nRanges () - 1, sizeof (ranges[0]), _cmp_range);
     return range ? range->fd : ranges[nRanges () - 1].fd;
   }
 
+  hb_pair_t<unsigned, hb_codepoint_t> get_fd_range (hb_codepoint_t glyph) const
+  {
+    auto *range = hb_bsearch (glyph, &ranges[0], nRanges () - 1, sizeof (ranges[0]), _cmp_range);
+    unsigned fd = range ? range->fd : ranges[nRanges () - 1].fd;
+    hb_codepoint_t end = range ? range[1].first : ranges[nRanges () - 1].first;
+    return {fd, end};
+  }
+
   GID_TYPE        &nRanges ()       { return ranges.len; }
   GID_TYPE         nRanges () const { return ranges.len; }
   GID_TYPE       &sentinel ()       { return StructAfter<GID_TYPE> (ranges[nRanges () - 1]); }
@@ -469,7 +530,7 @@
     }
   }
 
-  hb_codepoint_t get_fd (hb_codepoint_t glyph) const
+  unsigned get_fd (hb_codepoint_t glyph) const
   {
     if (this == &Null (FDSelect)) return 0;
 
@@ -480,6 +541,18 @@
     default:return 0;
     }
   }
+  /* Returns pair of fd and one after last glyph in range. */
+  hb_pair_t<unsigned, hb_codepoint_t> get_fd_range (hb_codepoint_t glyph) const
+  {
+    if (this == &Null (FDSelect)) return {0, 1};
+
+    switch (format)
+    {
+    case 0: return u.format0.get_fd_range (glyph);
+    case 3: return u.format3.get_fd_range (glyph);
+    default:return {0, 1};
+    }
+  }
 
   bool sanitize (hb_sanitize_context_t *c, unsigned int fdcount) const
   {
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.cc
index 505af15..6fcc8c4 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.cc
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.cc
@@ -574,11 +574,11 @@
 
 struct get_seac_param_t
 {
-  get_seac_param_t (const OT::cff1::accelerator_t *_cff) : cff (_cff) {}
+  get_seac_param_t (const OT::cff1::accelerator_subset_t *_cff) : cff (_cff) {}
 
   bool has_seac () const { return base && accent; }
 
-  const OT::cff1::accelerator_t *cff;
+  const OT::cff1::accelerator_subset_t *cff;
   hb_codepoint_t  base = 0;
   hb_codepoint_t  accent = 0;
 };
@@ -596,7 +596,7 @@
   }
 };
 
-bool OT::cff1::accelerator_t::get_seac_components (hb_codepoint_t glyph, hb_codepoint_t *base, hb_codepoint_t *accent) const
+bool OT::cff1::accelerator_subset_t::get_seac_components (hb_codepoint_t glyph, hb_codepoint_t *base, hb_codepoint_t *accent) const
 {
   if (unlikely (!is_valid () || (glyph >= num_glyphs))) return false;
 
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.hh
index 60bc308..d1310c6 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff1-table.hh
@@ -28,7 +28,7 @@
 #define HB_OT_CFF1_TABLE_HH
 
 #include "hb-ot-cff-common.hh"
-#include "hb-subset-cff1.hh"
+#include "hb-subset-cff-common.hh"
 #include "hb-draw.hh"
 #include "hb-paint.hh"
 
@@ -44,7 +44,7 @@
  * CFF -- Compact Font Format (CFF)
  * https://www.adobe.com/content/dam/acom/en/devnet/font/pdfs/5176.CFF.pdf
  */
-#define HB_OT_TAG_cff1 HB_TAG('C','F','F',' ')
+#define HB_OT_TAG_CFF1 HB_TAG('C','F','F',' ')
 
 #define CFF_UNDEF_SID   CFF_UNDEF_CODE
 
@@ -52,7 +52,6 @@
 enum CharsetID { ISOAdobeCharset = 0, ExpertCharset = 1, ExpertSubsetCharset = 2 };
 
 typedef CFFIndex<HBUINT16>  CFF1Index;
-template <typename Type> struct CFF1IndexOf : CFFIndexOf<HBUINT16, Type> {};
 
 typedef CFFIndex<HBUINT16> CFF1Index;
 typedef CFF1Index          CFF1CharStrings;
@@ -110,6 +109,7 @@
 
   hb_codepoint_t get_code (hb_codepoint_t glyph) const
   {
+    /* TODO: Add cache like get_sid. */
     assert (glyph > 0);
     glyph--;
     for (unsigned int i = 0; i < nRanges (); i++)
@@ -173,11 +173,7 @@
   bool serialize (hb_serialize_context_t *c, const Encoding &src)
   {
     TRACE_SERIALIZE (this);
-    unsigned int size = src.get_size ();
-    Encoding *dest = c->allocate_size<Encoding> (size);
-    if (unlikely (!dest)) return_trace (false);
-    hb_memcpy (dest, &src, size);
-    return_trace (true);
+    return_trace (c->embed (src));
   }
 
   /* serialize a subset Encoding */
@@ -312,26 +308,29 @@
 };
 
 /* Charset */
-struct Charset0 {
-  bool sanitize (hb_sanitize_context_t *c, unsigned int num_glyphs) const
+struct Charset0
+{
+  bool sanitize (hb_sanitize_context_t *c, unsigned int num_glyphs, unsigned *num_charset_entries) const
   {
     TRACE_SANITIZE (this);
-    return_trace (c->check_struct (this) && sids[num_glyphs - 1].sanitize (c));
+    if (num_charset_entries) *num_charset_entries = num_glyphs;
+    return_trace (sids.sanitize (c, num_glyphs - 1));
   }
 
   hb_codepoint_t get_sid (hb_codepoint_t glyph, unsigned num_glyphs) const
   {
     if (unlikely (glyph >= num_glyphs)) return 0;
-    if (glyph == 0)
+    if (unlikely (glyph == 0))
       return 0;
     else
       return sids[glyph - 1];
   }
 
-  void collect_glyph_to_sid_map (hb_map_t *mapping, unsigned int num_glyphs) const
+  void collect_glyph_to_sid_map (glyph_to_sid_map_t *mapping, unsigned int num_glyphs) const
   {
+    mapping->resize (num_glyphs, false);
     for (hb_codepoint_t gid = 1; gid < num_glyphs; gid++)
-      mapping->set (gid, sids[gid - 1]);
+      mapping->arrayZ[gid] = {sids[gid - 1], gid};
   }
 
   hb_codepoint_t get_glyph (hb_codepoint_t sid, unsigned int num_glyphs) const
@@ -347,13 +346,13 @@
     return 0;
   }
 
-  unsigned int get_size (unsigned int num_glyphs) const
+  static unsigned int get_size (unsigned int num_glyphs)
   {
     assert (num_glyphs > 0);
-    return HBUINT16::static_size * (num_glyphs - 1);
+    return UnsizedArrayOf<HBUINT16>::get_size (num_glyphs - 1);
   }
 
-  HBUINT16  sids[HB_VAR_ARRAY];
+  UnsizedArrayOf<HBUINT16> sids;
 
   DEFINE_SIZE_ARRAY(0, sids);
 };
@@ -374,38 +373,62 @@
 
 template <typename TYPE>
 struct Charset1_2 {
-  bool sanitize (hb_sanitize_context_t *c, unsigned int num_glyphs) const
+  bool sanitize (hb_sanitize_context_t *c, unsigned int num_glyphs, unsigned *num_charset_entries) const
   {
     TRACE_SANITIZE (this);
     if (unlikely (!c->check_struct (this)))
       return_trace (false);
     num_glyphs--;
-    for (unsigned int i = 0; num_glyphs > 0; i++)
+    unsigned i;
+    for (i = 0; num_glyphs > 0; i++)
     {
       if (unlikely (!ranges[i].sanitize (c) || (num_glyphs < ranges[i].nLeft + 1)))
         return_trace (false);
       num_glyphs -= (ranges[i].nLeft + 1);
     }
+    if (num_charset_entries)
+      *num_charset_entries = i;
     return_trace (true);
   }
 
-  hb_codepoint_t get_sid (hb_codepoint_t glyph, unsigned num_glyphs) const
+  hb_codepoint_t get_sid (hb_codepoint_t glyph, unsigned num_glyphs,
+                          code_pair_t *cache = nullptr) const
   {
     if (unlikely (glyph >= num_glyphs)) return 0;
-    if (glyph == 0) return 0;
-    glyph--;
-    for (unsigned int i = 0;; i++)
+    unsigned i;
+    hb_codepoint_t start_glyph;
+    if (cache && likely (cache->glyph <= glyph))
     {
-      if (glyph <= ranges[i].nLeft)
-        return (hb_codepoint_t) ranges[i].first + glyph;
-      glyph -= (ranges[i].nLeft + 1);
+      i = cache->code;
+      start_glyph = cache->glyph;
+    }
+    else
+    {
+      if (unlikely (glyph == 0)) return 0;
+      i = 0;
+      start_glyph = 1;
+    }
+    glyph -= start_glyph;
+    for (;; i++)
+    {
+      unsigned count = ranges[i].nLeft;
+      if (glyph <= count)
+      {
+        if (cache)
+          *cache = {i, start_glyph};
+        return ranges[i].first + glyph;
+      }
+      count++;
+      start_glyph += count;
+      glyph -= count;
     }
 
     return 0;
   }
 
-  void collect_glyph_to_sid_map (hb_map_t *mapping, unsigned int num_glyphs) const
+  void collect_glyph_to_sid_map (glyph_to_sid_map_t *mapping, unsigned int num_glyphs) const
   {
+    mapping->resize (num_glyphs, false);
     hb_codepoint_t gid = 1;
     if (gid >= num_glyphs)
       return;
@@ -413,8 +436,9 @@
     {
       hb_codepoint_t sid = ranges[i].first;
       unsigned count = ranges[i].nLeft + 1;
+      unsigned last = gid + count;
       for (unsigned j = 0; j < count; j++)
-        mapping->set (gid++, sid++);
+        mapping->arrayZ[gid++] = {sid++, last - 1};
 
       if (gid >= num_glyphs)
         break;
@@ -439,21 +463,26 @@
 
   unsigned int get_size (unsigned int num_glyphs) const
   {
-    unsigned int size = HBUINT8::static_size;
-    int glyph = (int)num_glyphs;
+    int glyph = (int) num_glyphs;
+    unsigned num_ranges = 0;
 
     assert (glyph > 0);
     glyph--;
     for (unsigned int i = 0; glyph > 0; i++)
     {
       glyph -= (ranges[i].nLeft + 1);
-      size += Charset_Range<TYPE>::static_size;
+      num_ranges++;
     }
 
-    return size;
+    return get_size_for_ranges (num_ranges);
   }
 
-  Charset_Range<TYPE>   ranges[HB_VAR_ARRAY];
+  static unsigned int get_size_for_ranges (unsigned int num_ranges)
+  {
+    return UnsizedArrayOf<Charset_Range<TYPE> >::get_size (num_ranges);
+  }
+
+  UnsizedArrayOf<Charset_Range<TYPE>> ranges;
 
   DEFINE_SIZE_ARRAY (0, ranges);
 };
@@ -469,11 +498,7 @@
   bool serialize (hb_serialize_context_t *c, const Charset &src, unsigned int num_glyphs)
   {
     TRACE_SERIALIZE (this);
-    unsigned int size = src.get_size (num_glyphs);
-    Charset *dest = c->allocate_size<Charset> (size);
-    if (unlikely (!dest)) return_trace (false);
-    hb_memcpy (dest, &src, size);
-    return_trace (true);
+    return_trace (c->embed ((const char *) &src, src.get_size (num_glyphs)));
   }
 
   /* serialize a subset Charset */
@@ -490,13 +515,13 @@
     {
     case 0:
     {
-      Charset0 *fmt0 = c->allocate_size<Charset0> (Charset0::min_size + HBUINT16::static_size * (num_glyphs - 1));
+      Charset0 *fmt0 = c->allocate_size<Charset0> (Charset0::get_size (num_glyphs), false);
       if (unlikely (!fmt0)) return_trace (false);
       unsigned int glyph = 0;
       for (unsigned int i = 0; i < sid_ranges.length; i++)
       {
-        hb_codepoint_t sid = sid_ranges[i].code;
-        for (int left = (int)sid_ranges[i].glyph; left >= 0; left--)
+        hb_codepoint_t sid = sid_ranges.arrayZ[i].code;
+        for (int left = (int)sid_ranges.arrayZ[i].glyph; left >= 0; left--)
           fmt0->sids[glyph++] = sid++;
       }
     }
@@ -504,29 +529,35 @@
 
     case 1:
     {
-      Charset1 *fmt1 = c->allocate_size<Charset1> (Charset1::min_size + Charset1_Range::static_size * sid_ranges.length);
+      Charset1 *fmt1 = c->allocate_size<Charset1> (Charset1::get_size_for_ranges (sid_ranges.length), false);
       if (unlikely (!fmt1)) return_trace (false);
+      hb_codepoint_t all_glyphs = 0;
       for (unsigned int i = 0; i < sid_ranges.length; i++)
       {
-        if (unlikely (!(sid_ranges[i].glyph <= 0xFF)))
-          return_trace (false);
-        fmt1->ranges[i].first = sid_ranges[i].code;
-        fmt1->ranges[i].nLeft = sid_ranges[i].glyph;
+        auto &_ = sid_ranges.arrayZ[i];
+        all_glyphs |= _.glyph;
+        fmt1->ranges[i].first = _.code;
+        fmt1->ranges[i].nLeft = _.glyph;
       }
+      if (unlikely (!(all_glyphs <= 0xFF)))
+        return_trace (false);
     }
     break;
 
     case 2:
     {
-      Charset2 *fmt2 = c->allocate_size<Charset2> (Charset2::min_size + Charset2_Range::static_size * sid_ranges.length);
+      Charset2 *fmt2 = c->allocate_size<Charset2> (Charset2::get_size_for_ranges (sid_ranges.length), false);
       if (unlikely (!fmt2)) return_trace (false);
+      hb_codepoint_t all_glyphs = 0;
       for (unsigned int i = 0; i < sid_ranges.length; i++)
       {
-        if (unlikely (!(sid_ranges[i].glyph <= 0xFFFF)))
-          return_trace (false);
-        fmt2->ranges[i].first = sid_ranges[i].code;
-        fmt2->ranges[i].nLeft = sid_ranges[i].glyph;
+        auto &_ = sid_ranges.arrayZ[i];
+        all_glyphs |= _.glyph;
+        fmt2->ranges[i].first = _.code;
+        fmt2->ranges[i].nLeft = _.glyph;
       }
+      if (unlikely (!(all_glyphs <= 0xFFFF)))
+        return_trace (false);
     }
     break;
 
@@ -545,18 +576,19 @@
     }
   }
 
-  hb_codepoint_t get_sid (hb_codepoint_t glyph, unsigned int num_glyphs) const
+  hb_codepoint_t get_sid (hb_codepoint_t glyph, unsigned int num_glyphs,
+                          code_pair_t *cache = nullptr) const
   {
     switch (format)
     {
     case 0: return u.format0.get_sid (glyph, num_glyphs);
-    case 1: return u.format1.get_sid (glyph, num_glyphs);
-    case 2: return u.format2.get_sid (glyph, num_glyphs);
+    case 1: return u.format1.get_sid (glyph, num_glyphs, cache);
+    case 2: return u.format2.get_sid (glyph, num_glyphs, cache);
     default:return 0;
     }
   }
 
-  void collect_glyph_to_sid_map (hb_map_t *mapping, unsigned int num_glyphs) const
+  void collect_glyph_to_sid_map (glyph_to_sid_map_t *mapping, unsigned int num_glyphs) const
   {
     switch (format)
     {
@@ -578,7 +610,7 @@
     }
   }
 
-  bool sanitize (hb_sanitize_context_t *c) const
+  bool sanitize (hb_sanitize_context_t *c, unsigned *num_charset_entries) const
   {
     TRACE_SANITIZE (this);
     if (unlikely (!c->check_struct (this)))
@@ -586,9 +618,9 @@
 
     switch (format)
     {
-    case 0: return_trace (u.format0.sanitize (c, c->get_num_glyphs ()));
-    case 1: return_trace (u.format1.sanitize (c, c->get_num_glyphs ()));
-    case 2: return_trace (u.format2.sanitize (c, c->get_num_glyphs ()));
+    case 0: return_trace (u.format0.sanitize (c, c->get_num_glyphs (), num_charset_entries));
+    case 1: return_trace (u.format1.sanitize (c, c->get_num_glyphs (), num_charset_entries));
+    case 2: return_trace (u.format2.sanitize (c, c->get_num_glyphs (), num_charset_entries));
     default:return_trace (false);
     }
   }
@@ -606,10 +638,10 @@
 struct CFF1StringIndex : CFF1Index
 {
   bool serialize (hb_serialize_context_t *c, const CFF1StringIndex &strings,
-                  const hb_inc_bimap_t &sidmap)
+                  const hb_vector_t<unsigned> &sidmap)
   {
     TRACE_SERIALIZE (this);
-    if (unlikely ((strings.count == 0) || (sidmap.get_population () == 0)))
+    if (unlikely ((strings.count == 0) || (sidmap.length == 0)))
     {
       if (unlikely (!c->extend_min (this->count)))
         return_trace (false);
@@ -617,15 +649,13 @@
       return_trace (true);
     }
 
-    byte_str_array_t bytesArray;
-    if (!bytesArray.resize (sidmap.get_population ()))
-      return_trace (false);
-    for (unsigned int i = 0; i < strings.count; i++)
-    {
-      hb_codepoint_t  j = sidmap[i];
-      if (j != HB_MAP_VALUE_INVALID)
-        bytesArray[j] = strings[i];
-    }
+    if (unlikely (sidmap.in_error ())) return_trace (false);
+
+    // Save this in a vector since serialize() iterates it twice.
+    hb_vector_t<hb_ubytes_t> bytesArray (+ hb_iter (sidmap)
+                                         | hb_map (strings));
+
+    if (unlikely (bytesArray.in_error ())) return_trace (false);
 
     bool result = CFF1Index::serialize (c, bytesArray);
     return_trace (result);
@@ -932,7 +962,7 @@
   }
 };
 
-struct cff1_private_dict_opset_subset : dict_opset_t
+struct cff1_private_dict_opset_subset_t : dict_opset_t
 {
   static void process_op (op_code_t op, num_interp_env_t& env, cff1_private_dict_values_subset_t& dictval)
   {
@@ -978,7 +1008,7 @@
 typedef dict_interpreter_t<cff1_font_dict_opset_t, cff1_font_dict_values_t> cff1_font_dict_interpreter_t;
 
 typedef CFF1Index CFF1NameIndex;
-typedef CFF1IndexOf<TopDict> CFF1TopDictIndex;
+typedef CFF1Index CFF1TopDictIndex;
 
 struct cff1_font_dict_values_mod_t
 {
@@ -1019,7 +1049,7 @@
 
 struct cff1
 {
-  static constexpr hb_tag_t tableTag = HB_OT_TAG_cff1;
+  static constexpr hb_tag_t tableTag = HB_OT_TAG_CFF1;
 
   bool sanitize (hb_sanitize_context_t *c) const
   {
@@ -1031,8 +1061,12 @@
   template <typename PRIVOPSET, typename PRIVDICTVAL>
   struct accelerator_templ_t
   {
-    void init (hb_face_t *face)
+    static constexpr hb_tag_t tableTag = cff1::tableTag;
+
+    accelerator_templ_t (hb_face_t *face)
     {
+      if (!face) return;
+
       topDict.init ();
       fontDicts.init ();
       privateDicts.init ();
@@ -1046,22 +1080,22 @@
       const OT::cff1 *cff = this->blob->template as<OT::cff1> ();
 
       if (cff == &Null (OT::cff1))
-      { fini (); return; }
+        goto fail;
 
       nameIndex = &cff->nameIndex (cff);
       if ((nameIndex == &Null (CFF1NameIndex)) || !nameIndex->sanitize (&sc))
-      { fini (); return; }
+        goto fail;
 
       topDictIndex = &StructAtOffset<CFF1TopDictIndex> (nameIndex, nameIndex->get_size ());
       if ((topDictIndex == &Null (CFF1TopDictIndex)) || !topDictIndex->sanitize (&sc) || (topDictIndex->count == 0))
-      { fini (); return; }
+        goto fail;
 
       { /* parse top dict */
         const hb_ubytes_t topDictStr = (*topDictIndex)[0];
-        if (unlikely (!topDictStr.sanitize (&sc))) { fini (); return; }
+        if (unlikely (!topDictStr.sanitize (&sc)))   goto fail;
         cff1_top_dict_interp_env_t env (topDictStr);
         cff1_top_dict_interpreter_t top_interp (env);
-        if (unlikely (!top_interp.interpret (topDict))) { fini (); return; }
+        if (unlikely (!top_interp.interpret (topDict)))   goto fail;
       }
 
       if (is_predef_charset ())
@@ -1069,7 +1103,7 @@
       else
       {
         charset = &StructAtOffsetOrNull<Charset> (cff, topDict.CharsetOffset);
-        if (unlikely ((charset == &Null (Charset)) || !charset->sanitize (&sc))) { fini (); return; }
+        if (unlikely ((charset == &Null (Charset)) || !charset->sanitize (&sc, &num_charset_entries)))   goto fail;
       }
 
       fdCount = 1;
@@ -1079,7 +1113,7 @@
         fdSelect = &StructAtOffsetOrNull<CFF1FDSelect> (cff, topDict.FDSelectOffset);
         if (unlikely ((fdArray == &Null (CFF1FDArray)) || !fdArray->sanitize (&sc) ||
             (fdSelect == &Null (CFF1FDSelect)) || !fdSelect->sanitize (&sc, fdArray->count)))
-        { fini (); return; }
+          goto fail;
 
         fdCount = fdArray->count;
       }
@@ -1092,36 +1126,36 @@
       encoding = &Null (Encoding);
       if (is_CID ())
       {
-        if (unlikely (charset == &Null (Charset))) { fini (); return; }
+        if (unlikely (charset == &Null (Charset)))   goto fail;
       }
       else
       {
         if (!is_predef_encoding ())
         {
           encoding = &StructAtOffsetOrNull<Encoding> (cff, topDict.EncodingOffset);
-          if (unlikely ((encoding == &Null (Encoding)) || !encoding->sanitize (&sc))) { fini (); return; }
+          if (unlikely ((encoding == &Null (Encoding)) || !encoding->sanitize (&sc)))   goto fail;
         }
       }
 
       stringIndex = &StructAtOffset<CFF1StringIndex> (topDictIndex, topDictIndex->get_size ());
       if ((stringIndex == &Null (CFF1StringIndex)) || !stringIndex->sanitize (&sc))
-      { fini (); return; }
+        goto fail;
 
       globalSubrs = &StructAtOffset<CFF1Subrs> (stringIndex, stringIndex->get_size ());
       if ((globalSubrs != &Null (CFF1Subrs)) && !globalSubrs->sanitize (&sc))
-      { fini (); return; }
+        goto fail;
 
       charStrings = &StructAtOffsetOrNull<CFF1CharStrings> (cff, topDict.charStringsOffset);
 
       if ((charStrings == &Null (CFF1CharStrings)) || unlikely (!charStrings->sanitize (&sc)))
-      { fini (); return; }
+        goto fail;
 
       num_glyphs = charStrings->count;
       if (num_glyphs != sc.get_num_glyphs ())
-      { fini (); return; }
+        goto fail;
 
       if (unlikely (!privateDicts.resize (fdCount)))
-      { fini (); return; }
+        goto fail;
       for (unsigned int i = 0; i < fdCount; i++)
         privateDicts[i].init ();
 
@@ -1131,27 +1165,27 @@
         for (unsigned int i = 0; i < fdCount; i++)
         {
           hb_ubytes_t fontDictStr = (*fdArray)[i];
-          if (unlikely (!fontDictStr.sanitize (&sc))) { fini (); return; }
+          if (unlikely (!fontDictStr.sanitize (&sc)))   goto fail;
           cff1_font_dict_values_t *font;
           cff1_top_dict_interp_env_t env (fontDictStr);
           cff1_font_dict_interpreter_t font_interp (env);
           font = fontDicts.push ();
-          if (unlikely (fontDicts.in_error ())) { fini (); return; }
+          if (unlikely (fontDicts.in_error ()))   goto fail;
 
           font->init ();
-          if (unlikely (!font_interp.interpret (*font))) { fini (); return; }
+          if (unlikely (!font_interp.interpret (*font)))   goto fail;
           PRIVDICTVAL *priv = &privateDicts[i];
           const hb_ubytes_t privDictStr = StructAtOffset<UnsizedByteStr> (cff, font->privateDictInfo.offset).as_ubytes (font->privateDictInfo.size);
-          if (unlikely (!privDictStr.sanitize (&sc))) { fini (); return; }
+          if (unlikely (!privDictStr.sanitize (&sc)))   goto fail;
           num_interp_env_t env2 (privDictStr);
           dict_interpreter_t<PRIVOPSET, PRIVDICTVAL> priv_interp (env2);
           priv->init ();
-          if (unlikely (!priv_interp.interpret (*priv))) { fini (); return; }
+          if (unlikely (!priv_interp.interpret (*priv)))   goto fail;
 
           priv->localSubrs = &StructAtOffsetOrNull<CFF1Subrs> (&privDictStr, priv->subrsOffset);
           if (priv->localSubrs != &Null (CFF1Subrs) &&
               unlikely (!priv->localSubrs->sanitize (&sc)))
-          { fini (); return; }
+            goto fail;
         }
       }
       else  /* non-CID */
@@ -1160,20 +1194,25 @@
         PRIVDICTVAL *priv = &privateDicts[0];
 
         const hb_ubytes_t privDictStr = StructAtOffset<UnsizedByteStr> (cff, font->privateDictInfo.offset).as_ubytes (font->privateDictInfo.size);
-        if (unlikely (!privDictStr.sanitize (&sc))) { fini (); return; }
+        if (unlikely (!privDictStr.sanitize (&sc)))   goto fail;
         num_interp_env_t env (privDictStr);
         dict_interpreter_t<PRIVOPSET, PRIVDICTVAL> priv_interp (env);
         priv->init ();
-        if (unlikely (!priv_interp.interpret (*priv))) { fini (); return; }
+        if (unlikely (!priv_interp.interpret (*priv)))   goto fail;
 
         priv->localSubrs = &StructAtOffsetOrNull<CFF1Subrs> (&privDictStr, priv->subrsOffset);
         if (priv->localSubrs != &Null (CFF1Subrs) &&
             unlikely (!priv->localSubrs->sanitize (&sc)))
-        { fini (); return; }
+          goto fail;
       }
-    }
 
-    void fini ()
+      return;
+
+      fail:
+        _fini ();
+    }
+    ~accelerator_templ_t () { _fini (); }
+    void _fini ()
     {
       sc.end_processing ();
       topDict.fini ();
@@ -1183,6 +1222,8 @@
       blob = nullptr;
     }
 
+    hb_blob_t *get_blob () const { return blob; }
+
     bool is_valid () const { return blob; }
     bool   is_CID () const { return topDict.is_CID (); }
 
@@ -1203,13 +1244,14 @@
 
     bool is_predef_encoding () const { return topDict.EncodingOffset <= ExpertEncoding; }
 
-    hb_codepoint_t glyph_to_code (hb_codepoint_t glyph) const
+    hb_codepoint_t glyph_to_code (hb_codepoint_t glyph,
+                                  code_pair_t *glyph_to_sid_cache = nullptr) const
     {
       if (encoding != &Null (Encoding))
         return encoding->get_code (glyph);
       else
       {
-        hb_codepoint_t sid = glyph_to_sid (glyph);
+        hb_codepoint_t sid = glyph_to_sid (glyph, glyph_to_sid_cache);
         if (sid == 0) return 0;
         hb_codepoint_t code = 0;
         switch (topDict.EncodingOffset)
@@ -1227,12 +1269,14 @@
       }
     }
 
-    hb_map_t *create_glyph_to_sid_map () const
+    glyph_to_sid_map_t *create_glyph_to_sid_map () const
     {
       if (charset != &Null (Charset))
       {
-        hb_map_t *mapping = hb_map_create ();
-        mapping->set (0, 0);
+        auto *mapping = (glyph_to_sid_map_t *) hb_malloc (sizeof (glyph_to_sid_map_t));
+        if (unlikely (!mapping)) return nullptr;
+        mapping = new (mapping) glyph_to_sid_map_t ();
+        mapping->push (code_pair_t {0, 1});
         charset->collect_glyph_to_sid_map (mapping, num_glyphs);
         return mapping;
       }
@@ -1240,10 +1284,11 @@
         return nullptr;
     }
 
-    hb_codepoint_t glyph_to_sid (hb_codepoint_t glyph) const
+    hb_codepoint_t glyph_to_sid (hb_codepoint_t glyph,
+                                 code_pair_t *cache = nullptr) const
     {
       if (charset != &Null (Charset))
-        return charset->get_sid (glyph, num_glyphs);
+        return charset->get_sid (glyph, num_glyphs, cache);
       else
       {
         hb_codepoint_t sid = 0;
@@ -1312,19 +1357,17 @@
     hb_vector_t<PRIVDICTVAL> privateDicts;
 
     unsigned int             num_glyphs = 0;
+    unsigned int             num_charset_entries = 0;
   };
 
   struct accelerator_t : accelerator_templ_t<cff1_private_dict_opset_t, cff1_private_dict_values_t>
   {
-    accelerator_t (hb_face_t *face)
+    accelerator_t (hb_face_t *face) : SUPER (face)
     {
-      SUPER::init (face);
-
       glyph_names.set_relaxed (nullptr);
 
       if (!is_valid ()) return;
       if (is_CID ()) return;
-
     }
     ~accelerator_t ()
     {
@@ -1334,8 +1377,6 @@
         names->fini ();
         hb_free (names);
       }
-
-      SUPER::fini ();
     }
 
     bool get_glyph_name (hb_codepoint_t glyph,
@@ -1386,9 +1427,10 @@
           /* TODO */
 
           /* fill glyph names */
+          code_pair_t glyph_to_sid_cache {0, HB_CODEPOINT_INVALID};
           for (hb_codepoint_t gid = 0; gid < num_glyphs; gid++)
           {
-            hb_codepoint_t      sid = glyph_to_sid (gid);
+            hb_codepoint_t      sid = glyph_to_sid (gid, &glyph_to_sid_cache);
             gname_t     gname;
             gname.sid = sid;
             if (sid < cff1_std_strings_length)
@@ -1426,7 +1468,6 @@
 
     HB_INTERNAL bool get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const;
     HB_INTERNAL bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, hb_color_t foreground) const;
-    HB_INTERNAL bool get_seac_components (hb_codepoint_t glyph, hb_codepoint_t *base, hb_codepoint_t *accent) const;
     HB_INTERNAL bool get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const;
 
     private:
@@ -1453,9 +1494,24 @@
     typedef accelerator_templ_t<cff1_private_dict_opset_t, cff1_private_dict_values_t> SUPER;
   };
 
-  struct accelerator_subset_t : accelerator_templ_t<cff1_private_dict_opset_subset, cff1_private_dict_values_subset_t> {};
+  struct accelerator_subset_t : accelerator_templ_t<cff1_private_dict_opset_subset_t, cff1_private_dict_values_subset_t>
+  {
+    accelerator_subset_t (hb_face_t *face) : SUPER (face) {}
+    ~accelerator_subset_t ()
+    {
+      if (cff_accelerator)
+        cff_subset_accelerator_t::destroy (cff_accelerator);
+    }
 
-  bool subset (hb_subset_context_t *c) const { return hb_subset_cff1 (c); }
+    HB_INTERNAL bool subset (hb_subset_context_t *c) const;
+    HB_INTERNAL bool serialize (hb_serialize_context_t *c,
+                                struct cff1_subset_plan &plan) const;
+    HB_INTERNAL bool get_seac_components (hb_codepoint_t glyph, hb_codepoint_t *base, hb_codepoint_t *accent) const;
+
+    mutable CFF::cff_subset_accelerator_t* cff_accelerator = nullptr;
+
+    typedef accelerator_templ_t<cff1_private_dict_opset_subset_t, cff1_private_dict_values_subset_t> SUPER;
+  };
 
   protected:
   HB_INTERNAL static hb_codepoint_t lookup_standard_encoding_for_code (hb_codepoint_t sid);
@@ -1479,6 +1535,10 @@
   cff1_accelerator_t (hb_face_t *face) : cff1::accelerator_t (face) {}
 };
 
+struct cff1_subset_accelerator_t : cff1::accelerator_subset_t {
+  cff1_subset_accelerator_t (hb_face_t *face) : cff1::accelerator_subset_t (face) {}
+};
+
 } /* namespace OT */
 
 #endif /* HB_OT_CFF1_TABLE_HH */
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.hh
index bfbc26b..db10f22 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-cff2-table.hh
@@ -28,7 +28,7 @@
 #define HB_OT_CFF2_TABLE_HH
 
 #include "hb-ot-cff-common.hh"
-#include "hb-subset-cff2.hh"
+#include "hb-subset-cff-common.hh"
 #include "hb-draw.hh"
 #include "hb-paint.hh"
 
@@ -38,10 +38,9 @@
  * CFF2 -- Compact Font Format (CFF) Version 2
  * https://docs.microsoft.com/en-us/typography/opentype/spec/cff2
  */
-#define HB_OT_TAG_cff2 HB_TAG('C','F','F','2')
+#define HB_OT_TAG_CFF2 HB_TAG('C','F','F','2')
 
 typedef CFFIndex<HBUINT32>  CFF2Index;
-template <typename Type> struct CFF2IndexOf : CFFIndexOf<HBUINT32, Type> {};
 
 typedef CFF2Index         CFF2CharStrings;
 typedef Subrs<HBUINT32>   CFF2Subrs;
@@ -379,7 +378,7 @@
 
 struct cff2
 {
-  static constexpr hb_tag_t tableTag = HB_OT_TAG_cff2;
+  static constexpr hb_tag_t tableTag = HB_OT_TAG_CFF2;
 
   bool sanitize (hb_sanitize_context_t *c) const
   {
@@ -391,8 +390,12 @@
   template <typename PRIVOPSET, typename PRIVDICTVAL>
   struct accelerator_templ_t
   {
+    static constexpr hb_tag_t tableTag = cff2::tableTag;
+
     accelerator_templ_t (hb_face_t *face)
     {
+      if (!face) return;
+
       topDict.init ();
       fontDicts.init ();
       privateDicts.init ();
@@ -464,7 +467,6 @@
           goto fail;
       }
 
-
       return;
 
       fail:
@@ -481,11 +483,13 @@
       blob = nullptr;
     }
 
-    hb_map_t *create_glyph_to_sid_map () const
+    hb_vector_t<uint16_t> *create_glyph_to_sid_map () const
     {
       return nullptr;
     }
 
+    hb_blob_t *get_blob () const { return blob; }
+
     bool is_valid () const { return blob; }
 
     protected:
@@ -518,9 +522,24 @@
     HB_INTERNAL bool get_path (hb_font_t *font, hb_codepoint_t glyph, hb_draw_session_t &draw_session) const;
   };
 
-  typedef accelerator_templ_t<cff2_private_dict_opset_subset_t, cff2_private_dict_values_subset_t> accelerator_subset_t;
+  struct accelerator_subset_t : accelerator_templ_t<cff2_private_dict_opset_subset_t, cff2_private_dict_values_subset_t>
+  {
+    accelerator_subset_t (hb_face_t *face) : SUPER (face) {}
+    ~accelerator_subset_t ()
+    {
+      if (cff_accelerator)
+        cff_subset_accelerator_t::destroy (cff_accelerator);
+    }
 
-  bool subset (hb_subset_context_t *c) const { return hb_subset_cff2 (c); }
+    HB_INTERNAL bool subset (hb_subset_context_t *c) const;
+    HB_INTERNAL bool serialize (hb_serialize_context_t *c,
+                                struct cff2_subset_plan &plan,
+                                hb_array_t<int> normalized_coords) const;
+
+    mutable CFF::cff_subset_accelerator_t* cff_accelerator = nullptr;
+
+    typedef accelerator_templ_t<cff2_private_dict_opset_subset_t, cff2_private_dict_values_subset_t> SUPER;
+  };
 
   public:
   FixedVersion<HBUINT8>         version;        /* Version of CFF2 table. set to 0x0200u */
@@ -535,6 +554,10 @@
   cff2_accelerator_t (hb_face_t *face) : cff2::accelerator_t (face) {}
 };
 
+struct cff2_subset_accelerator_t : cff2::accelerator_subset_t {
+  cff2_subset_accelerator_t (hb_face_t *face) : cff2::accelerator_subset_t (face) {}
+};
+
 } /* namespace OT */
 
 #endif /* HB_OT_CFF2_TABLE_HH */
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-cmap-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-cmap-table.hh
index eb1dd2b..7e6ced3 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-cmap-table.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-cmap-table.hh
@@ -277,10 +277,10 @@
       }
     } writer(c);
 
-    writer.end_code_ = c->allocate_size<HBUINT16> (HBUINT16::static_size * segcount);
-    c->allocate_size<HBUINT16> (2); // padding
-    writer.start_code_ = c->allocate_size<HBUINT16> (HBUINT16::static_size * segcount);
-    writer.id_delta_ = c->allocate_size<HBINT16> (HBINT16::static_size * segcount);
+    writer.end_code_ = c->allocate_size<HBUINT16> (HBUINT16::static_size * segcount, false);
+    (void) c->allocate_size<HBUINT16> (2); // padding
+    writer.start_code_ = c->allocate_size<HBUINT16> (HBUINT16::static_size * segcount, false);
+    writer.id_delta_ = c->allocate_size<HBINT16> (HBINT16::static_size * segcount, false);
 
     if (unlikely (!writer.end_code_ || !writer.start_code_ || !writer.id_delta_)) return false;
 
@@ -325,7 +325,7 @@
   {
     auto format4_iter =
     + it
-    | hb_filter ([&] (const hb_pair_t<hb_codepoint_t, hb_codepoint_t> _)
+    | hb_filter ([&] (const hb_codepoint_pair_t _)
                  { return _.first <= 0xFFFF; })
     ;
 
@@ -335,7 +335,7 @@
     if (unlikely (!c->extend_min (this))) return;
     this->format = 4;
 
-    hb_vector_t<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> cp_to_gid {
+    hb_vector_t<hb_codepoint_pair_t> cp_to_gid {
       format4_iter
     };
 
@@ -757,8 +757,7 @@
       hb_codepoint_t gid = this->groups[i].glyphID;
       if (!gid)
       {
-        /* Intention is: if (hb_is_same (T, CmapSubtableFormat13)) continue; */
-        if (! T::group_get_glyph (this->groups[i], end)) continue;
+        if (T::formatNumber == 13) continue;
         start++;
         gid++;
       }
@@ -766,11 +765,13 @@
       if (unlikely ((unsigned int) (gid + end - start) >= num_glyphs))
         end = start + (hb_codepoint_t) num_glyphs - gid;
 
+      mapping->alloc (mapping->get_population () + end - start + 1);
+
       for (unsigned cp = start; cp <= end; cp++)
       {
         unicodes->add (cp);
         mapping->set (cp, gid);
-        gid++;
+        gid += T::increment;
       }
     }
   }
@@ -794,6 +795,9 @@
 
 struct CmapSubtableFormat12 : CmapSubtableLongSegmented<CmapSubtableFormat12>
 {
+  static constexpr int increment = 1;
+  static constexpr int formatNumber = 12;
+
   static hb_codepoint_t group_get_glyph (const CmapSubtableLongGroup &group,
                                          hb_codepoint_t u)
   { return likely (group.startCharCode <= group.endCharCode) ?
@@ -866,6 +870,9 @@
 
 struct CmapSubtableFormat13 : CmapSubtableLongSegmented<CmapSubtableFormat13>
 {
+  static constexpr int increment = 0;
+  static constexpr int formatNumber = 13;
+
   static hb_codepoint_t group_get_glyph (const CmapSubtableLongGroup &group,
                                          hb_codepoint_t u HB_UNUSED)
   { return group.glyphID; }
@@ -917,8 +924,7 @@
   DefaultUVS* copy (hb_serialize_context_t *c,
                     const hb_set_t *unicodes) const
   {
-    DefaultUVS *out = c->start_embed<DefaultUVS> ();
-    if (unlikely (!out)) return nullptr;
+    auto *out = c->start_embed<DefaultUVS> ();
     auto snap = c->snapshot ();
 
     HBUINT32 len;
@@ -931,8 +937,7 @@
       hb_codepoint_t start = HB_SET_VALUE_INVALID;
       hb_codepoint_t end = HB_SET_VALUE_INVALID;
 
-      for (hb_codepoint_t u = HB_SET_VALUE_INVALID;
-           unicodes->next (&u);)
+      for (auto u : *unicodes)
       {
         if (!as_array ().bsearch (u))
           continue;
@@ -1067,9 +1072,7 @@
                        const hb_set_t *glyphs_requested,
                        const hb_map_t *glyph_map) const
   {
-    NonDefaultUVS *out = c->start_embed<NonDefaultUVS> ();
-    if (unlikely (!out)) return nullptr;
-
+    auto *out = c->start_embed<NonDefaultUVS> ();
     auto it =
     + as_array ()
     | hb_filter ([&] (const UVSMapping& _)
@@ -1767,7 +1770,6 @@
     TRACE_SUBSET (this);
 
     cmap *cmap_prime = c->serializer->start_embed<cmap> ();
-    if (unlikely (!c->serializer->check_success (cmap_prime))) return_trace (false);
 
     auto encodingrec_iter =
     + hb_iter (encodingRecord)
@@ -1798,7 +1800,7 @@
 
     auto it =
     + c->plan->unicode_to_new_gid_list.iter ()
-    | hb_filter ([&] (const hb_pair_t<hb_codepoint_t, hb_codepoint_t> _)
+    | hb_filter ([&] (const hb_codepoint_pair_t _)
                  { return (_.second != HB_MAP_VALUE_INVALID); })
     ;
 
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-font.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-font.cc
index 884cea0..deec909 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-font.cc
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-font.cc
@@ -38,8 +38,8 @@
 
 #include "hb-ot-cmap-table.hh"
 #include "hb-ot-glyf-table.hh"
-#include "hb-ot-cff1-table.hh"
 #include "hb-ot-cff2-table.hh"
+#include "hb-ot-cff1-table.hh"
 #include "hb-ot-hmtx-table.hh"
 #include "hb-ot-post-table.hh"
 #include "hb-ot-stat-table.hh" // Just so we compile it; unused otherwise.
@@ -64,13 +64,17 @@
 using hb_ot_font_cmap_cache_t    = hb_cache_t<21, 16, 8, true>;
 using hb_ot_font_advance_cache_t = hb_cache_t<24, 16, 8, true>;
 
+#ifndef HB_NO_OT_FONT_CMAP_CACHE
 static hb_user_data_key_t hb_ot_font_cmap_cache_user_data_key;
+#endif
 
 struct hb_ot_font_t
 {
   const hb_ot_face_t *ot_face;
 
+#ifndef HB_NO_OT_FONT_CMAP_CACHE
   hb_ot_font_cmap_cache_t *cmap_cache;
+#endif
 
   /* h_advance caching */
   mutable hb_atomic_int_t cached_coords_serial;
@@ -86,6 +90,7 @@
 
   ot_font->ot_face = &font->face->table;
 
+#ifndef HB_NO_OT_FONT_CMAP_CACHE
   // retry:
   auto *cmap_cache  = (hb_ot_font_cmap_cache_t *) hb_face_get_user_data (font->face,
                                                                          &hb_ot_font_cmap_cache_user_data_key);
@@ -93,7 +98,7 @@
   {
     cmap_cache = (hb_ot_font_cmap_cache_t *) hb_malloc (sizeof (hb_ot_font_cmap_cache_t));
     if (unlikely (!cmap_cache)) goto out;
-    cmap_cache->init ();
+    new (cmap_cache) hb_ot_font_cmap_cache_t ();
     if (unlikely (!hb_face_set_user_data (font->face,
                                           &hb_ot_font_cmap_cache_user_data_key,
                                           cmap_cache,
@@ -112,6 +117,7 @@
   }
   out:
   ot_font->cmap_cache = cmap_cache;
+#endif
 
   return ot_font;
 }
@@ -136,7 +142,11 @@
 {
   const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
   const hb_ot_face_t *ot_face = ot_font->ot_face;
-  return ot_face->cmap->get_nominal_glyph (unicode, glyph, ot_font->cmap_cache);
+  hb_ot_font_cmap_cache_t *cmap_cache = nullptr;
+#ifndef HB_NO_OT_FONT_CMAP_CACHE
+  cmap_cache = ot_font->cmap_cache;
+#endif
+  return ot_face->cmap->get_nominal_glyph (unicode, glyph, cmap_cache);
 }
 
 static unsigned int
@@ -151,10 +161,14 @@
 {
   const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
   const hb_ot_face_t *ot_face = ot_font->ot_face;
+  hb_ot_font_cmap_cache_t *cmap_cache = nullptr;
+#ifndef HB_NO_OT_FONT_CMAP_CACHE
+  cmap_cache = ot_font->cmap_cache;
+#endif
   return ot_face->cmap->get_nominal_glyphs (count,
                                             first_unicode, unicode_stride,
                                             first_glyph, glyph_stride,
-                                            ot_font->cmap_cache);
+                                            cmap_cache);
 }
 
 static hb_bool_t
@@ -167,9 +181,13 @@
 {
   const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
   const hb_ot_face_t *ot_face = ot_font->ot_face;
+  hb_ot_font_cmap_cache_t *cmap_cache = nullptr;
+#ifndef HB_NO_OT_FONT_CMAP_CACHE
+  cmap_cache = ot_font->cmap_cache;
+#endif
   return ot_face->cmap->get_variation_glyph (unicode,
                                              variation_selector, glyph,
-                                             ot_font->cmap_cache);
+                                             cmap_cache);
 }
 
 static void
@@ -188,7 +206,7 @@
 
   hb_position_t *orig_first_advance = first_advance;
 
-#ifndef HB_NO_VAR
+#if !defined(HB_NO_VAR) && !defined(HB_NO_OT_FONT_ADVANCE_CACHE)
   const OT::HVAR &HVAR = *hmtx.var_table;
   const OT::VariationStore &varStore = &HVAR + HVAR.varStore;
   OT::VariationStore::cache_t *varStore_cache = font->num_coords * count >= 128 ? varStore.create_cache () : nullptr;
@@ -212,8 +230,8 @@
         use_cache = false;
         goto out;
       }
+      new (cache) hb_ot_font_advance_cache_t;
 
-      cache->init ();
       if (unlikely (!ot_font->advance_cache.cmpexch (nullptr, cache)))
       {
         hb_free (cache);
@@ -237,7 +255,7 @@
   { /* Use cache. */
     if (ot_font->cached_coords_serial.get_acquire () != (int) font->serial_coords)
     {
-      ot_font->advance_cache->init ();
+      ot_font->advance_cache->clear ();
       ot_font->cached_coords_serial.set_release (font->serial_coords);
     }
 
@@ -258,7 +276,7 @@
     }
   }
 
-#ifndef HB_NO_VAR
+#if !defined(HB_NO_VAR) && !defined(HB_NO_OT_FONT_ADVANCE_CACHE)
   OT::VariationStore::destroy_cache (varStore_cache);
 #endif
 
@@ -293,7 +311,7 @@
 
   if (vmtx.has_data ())
   {
-#ifndef HB_NO_VAR
+#if !defined(HB_NO_VAR) && !defined(HB_NO_OT_FONT_ADVANCE_CACHE)
     const OT::VVAR &VVAR = *vmtx.var_table;
     const OT::VariationStore &varStore = &VVAR + VVAR.varStore;
     OT::VariationStore::cache_t *varStore_cache = font->num_coords ? varStore.create_cache () : nullptr;
@@ -308,7 +326,7 @@
       first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
     }
 
-#ifndef HB_NO_VAR
+#if !defined(HB_NO_VAR) && !defined(HB_NO_OT_FONT_ADVANCE_CACHE)
     OT::VariationStore::destroy_cache (varStore_cache);
 #endif
   }
@@ -418,8 +436,8 @@
 #endif
   if (ot_face->glyf->get_extents (font, glyph, extents)) return true;
 #ifndef HB_NO_OT_FONT_CFF
-  if (ot_face->cff1->get_extents (font, glyph, extents)) return true;
   if (ot_face->cff2->get_extents (font, glyph, extents)) return true;
+  if (ot_face->cff1->get_extents (font, glyph, extents)) return true;
 #endif
 
   return false;
@@ -507,8 +525,8 @@
                                     embolden ? &outline : draw_data, font->slant_xy);
     if (!font->face->table.glyf->get_path (font, glyph, draw_session))
 #ifndef HB_NO_CFF
-    if (!font->face->table.cff1->get_path (font, glyph, draw_session))
     if (!font->face->table.cff2->get_path (font, glyph, draw_session))
+    if (!font->face->table.cff1->get_path (font, glyph, draw_session))
 #endif
     {}
   }
@@ -547,8 +565,8 @@
 #endif
   if (font->face->table.glyf->paint_glyph (font, glyph, paint_funcs, paint_data, foreground)) return;
 #ifndef HB_NO_CFF
-  if (font->face->table.cff1->paint_glyph (font, glyph, paint_funcs, paint_data, foreground)) return;
   if (font->face->table.cff2->paint_glyph (font, glyph, paint_funcs, paint_data, foreground)) return;
+  if (font->face->table.cff1->paint_glyph (font, glyph, paint_funcs, paint_data, foreground)) return;
 #endif
 }
 #endif
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-hdmx-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-hdmx-table.hh
index e13321e..77e68db 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-hdmx-table.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-hdmx-table.hh
@@ -46,21 +46,23 @@
 
   template<typename Iterator,
            hb_requires (hb_is_iterator (Iterator))>
-  bool serialize (hb_serialize_context_t *c, unsigned pixelSize, Iterator it)
+  bool serialize (hb_serialize_context_t *c,
+                  unsigned pixelSize,
+                  Iterator it,
+                  const hb_vector_t<hb_codepoint_pair_t> new_to_old_gid_list,
+                  unsigned num_glyphs)
   {
     TRACE_SERIALIZE (this);
 
-    unsigned length = it.len ();
-
-    if (unlikely (!c->extend (this, length)))  return_trace (false);
+    if (unlikely (!c->extend (this, num_glyphs)))  return_trace (false);
 
     this->pixelSize = pixelSize;
     this->maxWidth =
     + it
     | hb_reduce (hb_max, 0u);
 
-    + it
-    | hb_sink (widthsZ.as_array (length));
+    for (auto &_ : new_to_old_gid_list)
+      widthsZ[_.first] = *it++;
 
     return_trace (true);
   }
@@ -89,7 +91,11 @@
 
   template<typename Iterator,
            hb_requires (hb_is_iterator (Iterator))>
-  bool serialize (hb_serialize_context_t *c, unsigned version, Iterator it)
+  bool serialize (hb_serialize_context_t *c,
+                  unsigned version,
+                  Iterator it,
+                  const hb_vector_t<hb_codepoint_pair_t> &new_to_old_gid_list,
+                  unsigned num_glyphs)
   {
     TRACE_SERIALIZE (this);
 
@@ -97,10 +103,10 @@
 
     this->version = version;
     this->numRecords = it.len ();
-    this->sizeDeviceRecord = DeviceRecord::get_size (it ? (*it).second.len () : 0);
+    this->sizeDeviceRecord = DeviceRecord::get_size (num_glyphs);
 
     for (const hb_item_type<Iterator>& _ : +it)
-      c->start_embed<DeviceRecord> ()->serialize (c, _.first, _.second);
+      c->start_embed<DeviceRecord> ()->serialize (c, _.first, _.second, new_to_old_gid_list, num_glyphs);
 
     return_trace (c->successful ());
   }
@@ -110,31 +116,30 @@
   {
     TRACE_SUBSET (this);
 
-    hdmx *hdmx_prime = c->serializer->start_embed <hdmx> ();
-    if (unlikely (!hdmx_prime)) return_trace (false);
+    auto *hdmx_prime = c->serializer->start_embed <hdmx> ();
 
+    unsigned num_input_glyphs = get_num_glyphs ();
     auto it =
     + hb_range ((unsigned) numRecords)
-    | hb_map ([c, this] (unsigned _)
+    | hb_map ([c, num_input_glyphs, this] (unsigned _)
         {
           const DeviceRecord *device_record =
             &StructAtOffset<DeviceRecord> (&firstDeviceRecord,
                                            _ * sizeDeviceRecord);
           auto row =
-            + hb_range (c->plan->num_output_glyphs ())
-            | hb_map (c->plan->reverse_glyph_map)
-            | hb_map ([this, c, device_record] (hb_codepoint_t _)
+            + hb_iter (c->plan->new_to_old_gid_list)
+            | hb_map ([num_input_glyphs, device_record] (hb_codepoint_pair_t _)
                       {
-                        if (c->plan->is_empty_glyph (_))
-                          return Null (HBUINT8);
-                        return device_record->widthsZ.as_array (get_num_glyphs ()) [_];
+                        return device_record->widthsZ.as_array (num_input_glyphs) [_.second];
                       })
             ;
           return hb_pair ((unsigned) device_record->pixelSize, +row);
         })
     ;
 
-    hdmx_prime->serialize (c->serializer, version, it);
+    hdmx_prime->serialize (c->serializer, version, it,
+                           c->plan->new_to_old_gid_list,
+                           c->plan->num_output_glyphs ());
     return_trace (true);
   }
 
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-hmtx-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-hmtx-table.hh
index e830fd0..39e1f48 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-hmtx-table.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-hmtx-table.hh
@@ -83,7 +83,7 @@
   bool subset_update_header (hb_subset_context_t *c,
                              unsigned int num_hmetrics,
                              const hb_hashmap_t<hb_codepoint_t, hb_pair_t<unsigned, int>> *mtx_map,
-                             const hb_map_t *bounds_map) const
+                             const hb_vector_t<unsigned> &bounds_vec) const
   {
     hb_blob_t *src_blob = hb_sanitize_context_t ().reference_table<H> (c->plan->source, H::tableTag);
     hb_blob_t *dest_blob = hb_blob_copy_writable_or_fail (src_blob);
@@ -114,6 +114,7 @@
         HB_ADD_MVAR_VAR (HB_OT_METRICS_TAG_VERTICAL_CARET_OFFSET,   caretOffset);
       }
 
+      bool empty = true;
       int min_lsb = 0x7FFF;
       int min_rsb = 0x7FFF;
       int max_extent = -0x7FFF;
@@ -125,9 +126,10 @@
         int lsb = _.second.second;
         max_adv = hb_max (max_adv, adv);
 
-        if (bounds_map->has (gid))
+        if (bounds_vec[gid] != 0xFFFFFFFF)
         {
-          unsigned bound_width = bounds_map->get (gid);
+          empty = false;
+          unsigned bound_width = bounds_vec[gid];
           int rsb = adv - lsb - bound_width;
           int extent = lsb + bound_width;
           min_lsb = hb_min (min_lsb, lsb);
@@ -137,7 +139,7 @@
       }
 
       table->advanceMax = max_adv;
-      if (!bounds_map->is_empty ())
+      if (!empty)
       {
         table->minLeadingBearing = min_lsb;
         table->minTrailingBearing = min_rsb;
@@ -156,32 +158,32 @@
            hb_requires (hb_is_iterator (Iterator))>
   void serialize (hb_serialize_context_t *c,
                   Iterator it,
-                  unsigned num_long_metrics)
+                  const hb_vector_t<hb_codepoint_pair_t> new_to_old_gid_list,
+                  unsigned num_long_metrics,
+                  unsigned total_num_metrics)
   {
-    unsigned idx = 0;
-    for (auto _ : it)
+    LongMetric* long_metrics = c->allocate_size<LongMetric> (num_long_metrics * LongMetric::static_size);
+    FWORD* short_metrics = c->allocate_size<FWORD> ((total_num_metrics - num_long_metrics) * FWORD::static_size);
+    if (!long_metrics || !short_metrics) return;
+
+    short_metrics -= num_long_metrics;
+
+    for (auto _ : new_to_old_gid_list)
     {
-      if (idx < num_long_metrics)
+      hb_codepoint_t gid = _.first;
+      auto mtx = *it++;
+
+      if (gid < num_long_metrics)
       {
-        LongMetric lm;
-        lm.advance = _.first;
-        lm.sb = _.second;
-        if (unlikely (!c->embed<LongMetric> (&lm))) return;
+        LongMetric& lm = long_metrics[gid];
+        lm.advance = mtx.first;
+        lm.sb = mtx.second;
       }
-      else if (idx < 0x10000u)
-      {
-        FWORD *sb = c->allocate_size<FWORD> (FWORD::static_size);
-        if (unlikely (!sb)) return;
-        *sb = _.second;
-      }
+      // TODO(beyond-64k): This assumes that maxp.numGlyphs is 0xFFFF.
+      else if (gid < 0x10000u)
+        short_metrics[gid] = mtx.second;
       else
-      {
-        // TODO: This does not do tail optimization.
-        UFWORD *adv = c->allocate_size<UFWORD> (UFWORD::static_size);
-        if (unlikely (!adv)) return;
-        *adv = _.first;
-      }
-      idx++;
+        ((UFWORD*) short_metrics)[gid] = mtx.first;
     }
   }
 
@@ -189,8 +191,7 @@
   {
     TRACE_SUBSET (this);
 
-    T *table_prime = c->serializer->start_embed <T> ();
-    if (unlikely (!table_prime)) return_trace (false);
+    auto *table_prime = c->serializer->start_embed <T> ();
 
     accelerator_t _mtx (c->plan->source);
     unsigned num_long_metrics;
@@ -199,6 +200,8 @@
       /* Determine num_long_metrics to encode. */
       auto& plan = c->plan;
 
+      // TODO Don't consider retaingid holes here.
+
       num_long_metrics = hb_min (plan->num_output_glyphs (), 0xFFFFu);
       unsigned int last_advance = get_new_gid_advance_unscaled (plan, mtx_map, num_long_metrics - 1, _mtx);
       while (num_long_metrics > 1 &&
@@ -209,31 +212,36 @@
     }
 
     auto it =
-    + hb_range (c->plan->num_output_glyphs ())
-    | hb_map ([c, &_mtx, mtx_map] (unsigned _)
+    + hb_iter (c->plan->new_to_old_gid_list)
+    | hb_map ([c, &_mtx, mtx_map] (hb_codepoint_pair_t _)
               {
-                if (!mtx_map->has (_))
+                hb_codepoint_t new_gid = _.first;
+                hb_codepoint_t old_gid = _.second;
+
+                hb_pair_t<unsigned, int> *v = nullptr;
+                if (!mtx_map->has (new_gid, &v))
                 {
-                  hb_codepoint_t old_gid;
-                  if (!c->plan->old_gid_for_new_gid (_, &old_gid))
-                    return hb_pair (0u, 0);
                   int lsb = 0;
                   if (!_mtx.get_leading_bearing_without_var_unscaled (old_gid, &lsb))
                     (void) _glyf_get_leading_bearing_without_var_unscaled (c->plan->source, old_gid, !T::is_horizontal, &lsb);
                   return hb_pair (_mtx.get_advance_without_var_unscaled (old_gid), +lsb);
                 }
-                return mtx_map->get (_);
+                return *v;
               })
     ;
 
-    table_prime->serialize (c->serializer, it, num_long_metrics);
+    table_prime->serialize (c->serializer,
+                            it,
+                            c->plan->new_to_old_gid_list,
+                            num_long_metrics,
+                            c->plan->num_output_glyphs ());
 
     if (unlikely (c->serializer->in_error ()))
       return_trace (false);
 
     // Amend header num hmetrics
     if (unlikely (!subset_update_header (c, num_long_metrics, mtx_map,
-                                         T::is_horizontal ? &c->plan->bounds_width_map : &c->plan->bounds_height_map)))
+                                         T::is_horizontal ? c->plan->bounds_width_vec : c->plan->bounds_height_vec)))
       return_trace (false);
 
     return_trace (true);
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-base-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-base-table.hh
index bcf1222..0e57a6c 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-base-table.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-base-table.hh
@@ -170,8 +170,8 @@
   {
     TRACE_SANITIZE (this);
     return_trace (likely (c->check_struct (this) &&
-                          minCoord.sanitize (c, this) &&
-                          maxCoord.sanitize (c, this)));
+                          minCoord.sanitize (c, base) &&
+                          maxCoord.sanitize (c, base)));
   }
 
   protected:
@@ -187,7 +187,6 @@
                                  * of MinMax table (may be NULL) */
   public:
   DEFINE_SIZE_STATIC (8);
-
 };
 
 struct MinMax
@@ -274,7 +273,7 @@
   {
     TRACE_SANITIZE (this);
     return_trace (likely (c->check_struct (this) &&
-                          minMax.sanitize (c, this)));
+                          minMax.sanitize (c, base)));
   }
 
   protected:
@@ -297,7 +296,8 @@
   const BaseCoord &get_base_coord (int baseline_tag_index) const
   { return (this+baseValues).get_base_coord (baseline_tag_index); }
 
-  bool has_data () const { return baseValues; }
+  bool has_values () const { return baseValues; }
+  bool has_min_max () const { return defaultMinMax; /* TODO What if only per-language is present? */ }
 
   bool sanitize (hb_sanitize_context_t *c) const
   {
@@ -383,7 +383,7 @@
                      const BaseCoord **coord) const
   {
     const BaseScript &base_script = (this+baseScriptList).get_base_script (script_tag);
-    if (!base_script.has_data ())
+    if (!base_script.has_values ())
     {
       *coord = nullptr;
       return false;
@@ -410,7 +410,7 @@
                     const BaseCoord **max_coord) const
   {
     const BaseScript &base_script = (this+baseScriptList).get_base_script (script_tag);
-    if (!base_script.has_data ())
+    if (!base_script.has_min_max ())
     {
       *min_coord = *max_coord = nullptr;
       return false;
@@ -425,8 +425,8 @@
   {
     TRACE_SANITIZE (this);
     return_trace (likely (c->check_struct (this) &&
-                          (this+baseTagList).sanitize (c) &&
-                          (this+baseScriptList).sanitize (c)));
+                          baseTagList.sanitize (c, this) &&
+                          baseScriptList.sanitize (c, this)));
   }
 
   protected:
@@ -473,14 +473,13 @@
     return true;
   }
 
-  /* TODO: Expose this separately sometime? */
   bool get_min_max (hb_font_t      *font,
                     hb_direction_t  direction,
                     hb_tag_t        script_tag,
                     hb_tag_t        language_tag,
                     hb_tag_t        feature_tag,
                     hb_position_t  *min,
-                    hb_position_t  *max)
+                    hb_position_t  *max) const
   {
     const BaseCoord *min_coord, *max_coord;
     if (!get_axis (direction).get_min_max (script_tag, language_tag, feature_tag,
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-common.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-common.hh
index 1ff697b..9216a9a 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-common.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-common.hh
@@ -55,19 +55,22 @@
     hb_serialize_context_t *c,
     const hb_set_t &klasses,
     bool use_class_zero,
-    hb_sorted_vector_t<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> &glyph_and_klass, /* IN/OUT */
+    hb_sorted_vector_t<hb_codepoint_pair_t> &glyph_and_klass, /* IN/OUT */
     hb_map_t *klass_map /*IN/OUT*/);
 
 struct hb_collect_feature_substitutes_with_var_context_t
 {
   const hb_map_t *axes_index_tag_map;
-  const hb_hashmap_t<hb_tag_t, int> *axes_location;
+  const hb_hashmap_t<hb_tag_t, Triple> *axes_location;
   hb_hashmap_t<unsigned, hb::shared_ptr<hb_set_t>> *record_cond_idx_map;
   hb_hashmap_t<unsigned, const Feature*> *feature_substitutes_map;
+  bool& insert_catch_all_feature_variation_record;
 
   // not stored in subset_plan
   hb_set_t *feature_indices;
   bool apply;
+  bool variation_applied;
+  bool universal;
   unsigned cur_record_idx;
   hb_hashmap_t<hb::shared_ptr<hb_map_t>, unsigned> *conditionset_map;
 };
@@ -188,27 +191,15 @@
   static return_t default_return_value () { return hb_empty_t (); }
 
   hb_set_t *layout_variation_indices;
-  hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *varidx_delta_map;
-  hb_font_t *font;
-  const VariationStore *var_store;
   const hb_set_t *glyph_set;
   const hb_map_t *gpos_lookups;
-  float *store_cache;
 
   hb_collect_variation_indices_context_t (hb_set_t *layout_variation_indices_,
-                                          hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *varidx_delta_map_,
-                                          hb_font_t *font_,
-                                          const VariationStore *var_store_,
                                           const hb_set_t *glyph_set_,
-                                          const hb_map_t *gpos_lookups_,
-                                          float *store_cache_) :
+                                          const hb_map_t *gpos_lookups_) :
                                         layout_variation_indices (layout_variation_indices_),
-                                        varidx_delta_map (varidx_delta_map_),
-                                        font (font_),
-                                        var_store (var_store_),
                                         glyph_set (glyph_set_),
-                                        gpos_lookups (gpos_lookups_),
-                                        store_cache (store_cache_) {}
+                                        gpos_lookups (gpos_lookups_) {}
 };
 
 template<typename OutputArray>
@@ -807,7 +798,7 @@
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->start_embed (*this);
-    if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
 
     out->featureParams.serialize_subset (c, featureParams, this, tag);
 
@@ -981,7 +972,7 @@
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->start_embed (*this);
-    if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
 
     + hb_enumerate (*this)
     | hb_filter (l->feature_index_map, hb_first)
@@ -1078,7 +1069,7 @@
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->start_embed (*this);
-    if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
 
     const uint32_t *v;
     out->reqFeatureIndex = l->feature_index_map->has (reqFeatureIndex, &v) ? *v : 0xFFFFu;
@@ -1188,7 +1179,7 @@
       return false;
 
     auto *out = c->serializer->start_embed (*this);
-    if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
 
     bool defaultLang = false;
     if (has_default_lang_sys ())
@@ -1247,7 +1238,7 @@
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->start_embed (*this);
-    if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
 
     for (auto _ : + hb_enumerate (*this))
     {
@@ -1367,7 +1358,7 @@
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->start_embed (*this);
-    if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
     out->lookupType = lookupType;
     out->lookupFlag = lookupFlag;
 
@@ -1456,7 +1447,7 @@
   {
     TRACE_SUBSET (this);
     auto *out = c->serializer->start_embed (this);
-    if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
 
     + hb_enumerate (*this)
     | hb_filter (l->lookup_index_map, hb_first)
@@ -1482,7 +1473,7 @@
 static bool ClassDef_remap_and_serialize (hb_serialize_context_t *c,
                                           const hb_set_t &klasses,
                                           bool use_class_zero,
-                                          hb_sorted_vector_t<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> &glyph_and_klass, /* IN/OUT */
+                                          hb_sorted_vector_t<hb_codepoint_pair_t> &glyph_and_klass, /* IN/OUT */
                                           hb_map_t *klass_map /*IN/OUT*/)
 {
   if (!klass_map)
@@ -1573,7 +1564,7 @@
     TRACE_SUBSET (this);
     const hb_map_t &glyph_map = c->plan->glyph_map_gsub;
 
-    hb_sorted_vector_t<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> glyph_and_klass;
+    hb_sorted_vector_t<hb_codepoint_pair_t> glyph_and_klass;
     hb_set_t orig_klasses;
 
     hb_codepoint_t start = startGlyph;
@@ -1592,10 +1583,13 @@
       orig_klasses.add (klass);
     }
 
-    unsigned glyph_count = glyph_filter
-                           ? hb_len (hb_iter (glyph_map.keys()) | hb_filter (glyph_filter))
-                           : glyph_map.get_population ();
-    use_class_zero = use_class_zero && glyph_count <= glyph_and_klass.length;
+    if (use_class_zero)
+    {
+      unsigned glyph_count = glyph_filter
+                             ? hb_len (hb_iter (glyph_map.keys()) | hb_filter (glyph_filter))
+                             : glyph_map.get_population ();
+      use_class_zero = glyph_count <= glyph_and_klass.length;
+    }
     if (!ClassDef_remap_and_serialize (c->serializer,
                                        orig_klasses,
                                        use_class_zero,
@@ -1769,6 +1763,7 @@
       return_trace (true);
     }
 
+    unsigned unsorted = false;
     unsigned num_ranges = 1;
     hb_codepoint_t prev_gid = (*it).first;
     unsigned prev_klass = (*it).second;
@@ -1789,6 +1784,10 @@
       if (cur_gid != prev_gid + 1 ||
           cur_klass != prev_klass)
       {
+
+        if (unlikely (cur_gid < prev_gid))
+          unsorted = true;
+
         if (unlikely (!record)) break;
         record->last = prev_gid;
         num_ranges++;
@@ -1804,8 +1803,14 @@
       prev_gid = cur_gid;
     }
 
+    if (unlikely (c->in_error ())) return_trace (false);
+
     if (likely (record)) record->last = prev_gid;
     rangeRecord.len = num_ranges;
+
+    if (unlikely (unsorted))
+      rangeRecord.as_array ().qsort (RangeRecord<Types>::cmp_range);
+
     return_trace (true);
   }
 
@@ -1819,7 +1824,7 @@
     const hb_map_t &glyph_map = c->plan->glyph_map_gsub;
     const hb_set_t &glyph_set = *c->plan->glyphset_gsub ();
 
-    hb_sorted_vector_t<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> glyph_and_klass;
+    hb_sorted_vector_t<hb_codepoint_pair_t> glyph_and_klass;
     hb_set_t orig_klasses;
 
     if (glyph_set.get_population () * hb_bit_storage ((unsigned) rangeRecord.len) / 2
@@ -1905,7 +1910,7 @@
   {
     if (rangeRecord.len > glyphs->get_population () * hb_bit_storage ((unsigned) rangeRecord.len) / 2)
     {
-      for (hb_codepoint_t g = HB_SET_VALUE_INVALID; glyphs->next (&g);)
+      for (auto g : *glyphs)
         if (get_class (g))
           return true;
       return false;
@@ -1920,13 +1925,22 @@
     {
       /* Match if there's any glyph that is not listed! */
       hb_codepoint_t g = HB_SET_VALUE_INVALID;
-      for (auto &range : rangeRecord)
+      hb_codepoint_t last = HB_SET_VALUE_INVALID;
+      auto it = hb_iter (rangeRecord);
+      for (auto &range : it)
       {
+        if (it->first == last + 1)
+        {
+          it++;
+          continue;
+        }
+
         if (!glyphs->next (&g))
           break;
         if (g < range.first)
           return true;
         g = range.last;
+        last = g;
       }
       if (g != HB_SET_VALUE_INVALID && glyphs->next (&g))
         return true;
@@ -1965,8 +1979,7 @@
     unsigned count = rangeRecord.len;
     if (count > glyphs->get_population () * hb_bit_storage (count) * 8)
     {
-      for (hb_codepoint_t g = HB_SET_VALUE_INVALID;
-           glyphs->next (&g);)
+      for (auto g : *glyphs)
       {
         unsigned i;
         if (rangeRecord.as_array ().bfind (g, &i) &&
@@ -2097,8 +2110,15 @@
 
 #ifndef HB_NO_BEYOND_64K
     if (glyph_max > 0xFFFFu)
-      format += 2;
+      u.format += 2;
+    if (unlikely (glyph_max > 0xFFFFFFu))
+#else
+    if (unlikely (glyph_max > 0xFFFFu))
 #endif
+    {
+      c->check_success (false, HB_SERIALIZE_ERROR_INT_OVERFLOW);
+      return_trace (false);
+    }
 
     u.format = format;
 
@@ -2268,6 +2288,158 @@
  * Item Variation Store
  */
 
+/* ported from fonttools (class _Encoding) */
+struct delta_row_encoding_t
+{
+  /* each byte represents a region, value is one of 0/1/2/4, which means bytes
+   * needed for this region */
+  hb_vector_t<uint8_t> chars;
+  unsigned width = 0;
+  hb_vector_t<uint8_t> columns;
+  unsigned overhead = 0;
+  hb_vector_t<const hb_vector_t<int>*> items;
+
+  delta_row_encoding_t () = default;
+  delta_row_encoding_t (hb_vector_t<uint8_t>&& chars_,
+                        const hb_vector_t<int>* row = nullptr) :
+                        delta_row_encoding_t ()
+
+  {
+    chars = std::move (chars_);
+    width = get_width ();
+    columns = get_columns ();
+    overhead = get_chars_overhead (columns);
+    if (row) items.push (row);
+  }
+
+  bool is_empty () const
+  { return !items; }
+
+  static hb_vector_t<uint8_t> get_row_chars (const hb_vector_t<int>& row)
+  {
+    hb_vector_t<uint8_t> ret;
+    if (!ret.alloc (row.length)) return ret;
+
+    bool long_words = false;
+
+    /* 0/1/2 byte encoding */
+    for (int i = row.length - 1; i >= 0; i--)
+    {
+      int v =  row.arrayZ[i];
+      if (v == 0)
+        ret.push (0);
+      else if (v > 32767 || v < -32768)
+      {
+        long_words = true;
+        break;
+      }
+      else if (v > 127 || v < -128)
+        ret.push (2);
+      else
+        ret.push (1);
+    }
+
+    if (!long_words)
+      return ret;
+
+    /* redo, 0/2/4 bytes encoding */
+    ret.reset ();
+    for (int i = row.length - 1; i >= 0; i--)
+    {
+      int v =  row.arrayZ[i];
+      if (v == 0)
+        ret.push (0);
+      else if (v > 32767 || v < -32768)
+        ret.push (4);
+      else
+        ret.push (2);
+    }
+    return ret;
+  }
+
+  inline unsigned get_width ()
+  {
+    unsigned ret = + hb_iter (chars)
+                   | hb_reduce (hb_add, 0u)
+                   ;
+    return ret;
+  }
+
+  hb_vector_t<uint8_t> get_columns ()
+  {
+    hb_vector_t<uint8_t> cols;
+    cols.alloc (chars.length);
+    for (auto v : chars)
+    {
+      uint8_t flag = v ? 1 : 0;
+      cols.push (flag);
+    }
+    return cols;
+  }
+
+  static inline unsigned get_chars_overhead (const hb_vector_t<uint8_t>& cols)
+  {
+    unsigned c = 4 + 6; // 4 bytes for LOffset, 6 bytes for VarData header
+    unsigned cols_bit_count = 0;
+    for (auto v : cols)
+      if (v) cols_bit_count++;
+    return c + cols_bit_count * 2;
+  }
+
+  unsigned get_gain () const
+  {
+    int count = items.length;
+    return hb_max (0, (int) overhead - count);
+  }
+
+  int gain_from_merging (const delta_row_encoding_t& other_encoding) const
+  {
+    int combined_width = 0;
+    for (unsigned i = 0; i < chars.length; i++)
+      combined_width += hb_max (chars.arrayZ[i], other_encoding.chars.arrayZ[i]);
+
+    hb_vector_t<uint8_t> combined_columns;
+    combined_columns.alloc (columns.length);
+    for (unsigned i = 0; i < columns.length; i++)
+      combined_columns.push (columns.arrayZ[i] | other_encoding.columns.arrayZ[i]);
+
+    int combined_overhead = get_chars_overhead (combined_columns);
+    int combined_gain = (int) overhead + (int) other_encoding.overhead - combined_overhead
+                        - (combined_width - (int) width) * items.length
+                        - (combined_width - (int) other_encoding.width) * other_encoding.items.length;
+
+    return combined_gain;
+  }
+
+  static int cmp (const void *pa, const void *pb)
+  {
+    const delta_row_encoding_t *a = (const delta_row_encoding_t *)pa;
+    const delta_row_encoding_t *b = (const delta_row_encoding_t *)pb;
+
+    int gain_a = a->get_gain ();
+    int gain_b = b->get_gain ();
+
+    if (gain_a != gain_b)
+      return gain_a - gain_b;
+
+    return (b->chars).as_array ().cmp ((a->chars).as_array ());
+  }
+
+  static int cmp_width (const void *pa, const void *pb)
+  {
+    const delta_row_encoding_t *a = (const delta_row_encoding_t *)pa;
+    const delta_row_encoding_t *b = (const delta_row_encoding_t *)pb;
+
+    if (a->width != b->width)
+      return (int) a->width - (int) b->width;
+
+    return (b->chars).as_array ().cmp ((a->chars).as_array ());
+  }
+
+  bool add_row (const hb_vector_t<int>* row)
+  { return items.push (row); }
+};
+
 struct VarRegionAxis
 {
   float evaluate (int coord) const
@@ -2302,6 +2474,12 @@
      * have to do that at runtime. */
   }
 
+  bool serialize (hb_serialize_context_t *c) const
+  {
+    TRACE_SERIALIZE (this);
+    return_trace (c->embed (this));
+  }
+
   public:
   F2DOT14       startCoord;
   F2DOT14       peakCoord;
@@ -2359,7 +2537,48 @@
     return_trace (c->check_struct (this) && axesZ.sanitize (c, axisCount * regionCount));
   }
 
-  bool serialize (hb_serialize_context_t *c, const VarRegionList *src, const hb_bimap_t &region_map)
+  bool serialize (hb_serialize_context_t *c,
+                  const hb_vector_t<hb_tag_t>& axis_tags,
+                  const hb_vector_t<const hb_hashmap_t<hb_tag_t, Triple>*>& regions)
+  {
+    TRACE_SERIALIZE (this);
+    unsigned axis_count = axis_tags.length;
+    unsigned region_count = regions.length;
+    if (!axis_count || !region_count) return_trace (false);
+    if (unlikely (hb_unsigned_mul_overflows (axis_count * region_count,
+                                             VarRegionAxis::static_size))) return_trace (false);
+    if (unlikely (!c->extend_min (this))) return_trace (false);
+    axisCount = axis_count;
+    regionCount = region_count;
+
+    for (unsigned r = 0; r < region_count; r++)
+    {
+      const auto& region = regions[r];
+      for (unsigned i = 0; i < axis_count; i++)
+      {
+        hb_tag_t tag = axis_tags.arrayZ[i];
+        VarRegionAxis var_region_rec;
+        Triple *coords;
+        if (region->has (tag, &coords))
+        {
+          var_region_rec.startCoord.set_float (coords->minimum);
+          var_region_rec.peakCoord.set_float (coords->middle);
+          var_region_rec.endCoord.set_float (coords->maximum);
+        }
+        else
+        {
+          var_region_rec.startCoord.set_int (0);
+          var_region_rec.peakCoord.set_int (0);
+          var_region_rec.endCoord.set_int (0);
+        }
+        if (!var_region_rec.serialize (c))
+          return_trace (false);
+      }
+    }
+    return_trace (true);
+  }
+
+  bool serialize (hb_serialize_context_t *c, const VarRegionList *src, const hb_inc_bimap_t &region_map)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (this))) return_trace (false);
@@ -2379,6 +2598,45 @@
     return_trace (true);
   }
 
+  bool get_var_region (unsigned region_index,
+                       const hb_map_t& axes_old_index_tag_map,
+                       hb_hashmap_t<hb_tag_t, Triple>& axis_tuples /* OUT */) const
+  {
+    if (region_index >= regionCount) return false;
+    const VarRegionAxis* axis_region = axesZ.arrayZ + (region_index * axisCount);
+    for (unsigned i = 0; i < axisCount; i++)
+    {
+      hb_tag_t *axis_tag;
+      if (!axes_old_index_tag_map.has (i, &axis_tag))
+        return false;
+
+      float min_val = axis_region->startCoord.to_float ();
+      float def_val = axis_region->peakCoord.to_float ();
+      float max_val = axis_region->endCoord.to_float ();
+
+      if (def_val != 0.f)
+        axis_tuples.set (*axis_tag, Triple (min_val, def_val, max_val));
+      axis_region++;
+    }
+    return !axis_tuples.in_error ();
+  }
+
+  bool get_var_regions (const hb_map_t& axes_old_index_tag_map,
+                        hb_vector_t<hb_hashmap_t<hb_tag_t, Triple>>& regions /* OUT */) const
+  {
+    if (!regions.alloc (regionCount))
+      return false;
+
+    for (unsigned i = 0; i < regionCount; i++)
+    {
+      hb_hashmap_t<hb_tag_t, Triple> axis_tuples;
+      if (!get_var_region (i, axes_old_index_tag_map, axis_tuples))
+        return false;
+      regions.push (std::move (axis_tuples));
+    }
+    return !regions.in_error ();
+  }
+
   unsigned int get_size () const { return min_size + VarRegionAxis::static_size * axisCount * regionCount; }
 
   public:
@@ -2399,6 +2657,9 @@
   unsigned int get_region_index_count () const
   { return regionIndices.len; }
 
+  unsigned get_region_index (unsigned i) const
+  { return i >= regionIndices.len ? -1 : regionIndices[i]; }
+
   unsigned int get_row_size () const
   { return (wordCount () + regionIndices.len) * (longWords () ? 2 : 1); }
 
@@ -2474,9 +2735,84 @@
   }
 
   bool serialize (hb_serialize_context_t *c,
+                  bool has_long,
+                  const hb_vector_t<const hb_vector_t<int>*>& rows)
+  {
+    TRACE_SERIALIZE (this);
+    if (unlikely (!c->extend_min (this))) return_trace (false);
+    unsigned row_count = rows.length;
+    itemCount = row_count;
+
+    int min_threshold = has_long ? -65536 : -128;
+    int max_threshold = has_long ? +65535 : +127;
+    enum delta_size_t { kZero=0, kNonWord, kWord };
+    hb_vector_t<delta_size_t> delta_sz;
+    unsigned num_regions = rows[0]->length;
+    if (!delta_sz.resize (num_regions))
+      return_trace (false);
+
+    unsigned word_count = 0;
+    for (unsigned r = 0; r < num_regions; r++)
+    {
+      for (unsigned i = 0; i < row_count; i++)
+      {
+        int delta = rows[i]->arrayZ[r];
+        if (delta < min_threshold || delta > max_threshold)
+        {
+          delta_sz[r] = kWord;
+          word_count++;
+          break;
+        }
+        else if (delta != 0)
+        {
+          delta_sz[r] = kNonWord;
+        }
+      }
+    }
+
+    /* reorder regions: words and then non-words*/
+    unsigned word_index = 0;
+    unsigned non_word_index = word_count;
+    hb_map_t ri_map;
+    for (unsigned r = 0; r < num_regions; r++)
+    {
+      if (!delta_sz[r]) continue;
+      unsigned new_r = (delta_sz[r] == kWord)? word_index++ : non_word_index++;
+      if (!ri_map.set (new_r, r))
+        return_trace (false);
+    }
+
+    wordSizeCount = word_count | (has_long ? 0x8000u /* LONG_WORDS */ : 0);
+
+    unsigned ri_count = ri_map.get_population ();
+    regionIndices.len = ri_count;
+    if (unlikely (!c->extend (this))) return_trace (false);
+
+    for (unsigned r = 0; r < ri_count; r++)
+    {
+      hb_codepoint_t *idx;
+      if (!ri_map.has (r, &idx))
+        return_trace (false);
+      regionIndices[r] = *idx;
+    }
+
+    HBUINT8 *delta_bytes = get_delta_bytes ();
+    unsigned row_size = get_row_size ();
+    for (unsigned int i = 0; i < row_count; i++)
+    {
+      for (unsigned int r = 0; r < ri_count; r++)
+      {
+        int delta = rows[i]->arrayZ[ri_map[r]];
+        set_item_delta_fast (i, r, delta, delta_bytes, row_size);
+      }
+    }
+    return_trace (true);
+  }
+
+  bool serialize (hb_serialize_context_t *c,
                   const VarData *src,
                   const hb_inc_bimap_t &inner_map,
-                  const hb_bimap_t &region_map)
+                  const hb_inc_bimap_t &region_map)
   {
     TRACE_SERIALIZE (this);
     if (unlikely (!c->extend_min (this))) return_trace (false);
@@ -2593,13 +2929,15 @@
     }
   }
 
-  protected:
+  public:
   const HBUINT8 *get_delta_bytes () const
   { return &StructAfter<HBUINT8> (regionIndices); }
 
+  protected:
   HBUINT8 *get_delta_bytes ()
   { return &StructAfter<HBUINT8> (regionIndices); }
 
+  public:
   int32_t get_item_delta_fast (unsigned int item, unsigned int region,
                                const HBUINT8 *delta_bytes, unsigned row_size) const
   {
@@ -2630,6 +2968,7 @@
                                  get_row_size ());
   }
 
+  protected:
   void set_item_delta_fast (unsigned int item, unsigned int region, int32_t delta,
                             HBUINT8 *delta_bytes, unsigned row_size)
   {
@@ -2672,6 +3011,7 @@
 
 struct VariationStore
 {
+  friend struct item_variations_t;
   using cache_t = VarRegionList::cache_t;
 
   cache_t *create_cache () const
@@ -2743,6 +3083,36 @@
   }
 
   bool serialize (hb_serialize_context_t *c,
+                  bool has_long,
+                  const hb_vector_t<hb_tag_t>& axis_tags,
+                  const hb_vector_t<const hb_hashmap_t<hb_tag_t, Triple>*>& region_list,
+                  const hb_vector_t<delta_row_encoding_t>& vardata_encodings)
+  {
+    TRACE_SERIALIZE (this);
+#ifdef HB_NO_VAR
+    return_trace (false);
+#endif
+    if (unlikely (!c->extend_min (this))) return_trace (false);
+
+    format = 1;
+    if (!regions.serialize_serialize (c, axis_tags, region_list))
+      return_trace (false);
+
+    unsigned num_var_data = vardata_encodings.length;
+    if (!num_var_data) return_trace (false);
+    if (unlikely (!c->check_assign (dataSets.len, num_var_data,
+                                    HB_SERIALIZE_ERROR_INT_OVERFLOW)))
+      return_trace (false);
+
+    if (unlikely (!c->extend (dataSets))) return_trace (false);
+    for (unsigned i = 0; i < num_var_data; i++)
+      if (!dataSets[i].serialize_serialize (c, has_long, vardata_encodings[i].items))
+        return_trace (false);
+
+    return_trace (true);
+  }
+
+  bool serialize (hb_serialize_context_t *c,
                   const VariationStore *src,
                   const hb_array_t <const hb_inc_bimap_t> &inner_maps)
   {
@@ -2871,6 +3241,22 @@
      return dataSets.len;
    }
 
+  const VarData& get_sub_table (unsigned i) const
+  {
+#ifdef HB_NO_VAR
+     return Null (VarData);
+#endif
+     return this+dataSets[i];
+  }
+
+  const VarRegionList& get_region_list () const
+  {
+#ifdef HB_NO_VAR
+     return Null (VarRegionList);
+#endif
+     return this+regions;
+  }
+
   protected:
   HBUINT16                              format;
   Offset32To<VarRegionList>             regions;
@@ -2887,9 +3273,9 @@
 enum Cond_with_Var_flag_t
 {
   KEEP_COND_WITH_VAR = 0,
-  DROP_COND_WITH_VAR = 1,
-  DROP_RECORD_WITH_VAR = 2,
-  MEM_ERR_WITH_VAR = 3,
+  KEEP_RECORD_WITH_VAR = 1,
+  DROP_COND_WITH_VAR = 2,
+  DROP_RECORD_WITH_VAR = 3,
 };
 
 struct ConditionFormat1
@@ -2905,9 +3291,29 @@
     const hb_map_t *index_map = &c->plan->axes_index_map;
     if (index_map->is_empty ()) return_trace (true);
 
-    if (!index_map->has (axisIndex))
+    const hb_map_t& axes_old_index_tag_map = c->plan->axes_old_index_tag_map;
+    hb_codepoint_t *axis_tag;
+    if (!axes_old_index_tag_map.has (axisIndex, &axis_tag) ||
+        !index_map->has (axisIndex))
       return_trace (false);
 
+    const hb_hashmap_t<hb_tag_t, Triple>& normalized_axes_location = c->plan->axes_location;
+    Triple axis_limit{-1.f, 0.f, 1.f};
+    Triple *normalized_limit;
+    if (normalized_axes_location.has (*axis_tag, &normalized_limit))
+      axis_limit = *normalized_limit;
+
+    const hb_hashmap_t<hb_tag_t, TripleDistances>& axes_triple_distances = c->plan->axes_triple_distances;
+    TripleDistances axis_triple_distances{1.f, 1.f};
+    TripleDistances *triple_dists;
+    if (axes_triple_distances.has (*axis_tag, &triple_dists))
+      axis_triple_distances = *triple_dists;
+
+    float normalized_min = renormalizeValue (filterRangeMinValue.to_float (), axis_limit, axis_triple_distances, false);
+    float normalized_max = renormalizeValue (filterRangeMaxValue.to_float (), axis_limit, axis_triple_distances, false);
+    out->filterRangeMinValue.set_float (normalized_min);
+    out->filterRangeMaxValue.set_float (normalized_max);
+
     return_trace (c->serializer->check_assign (out->axisIndex, index_map->get (axisIndex),
                                                HB_SERIALIZE_ERROR_INT_OVERFLOW));
   }
@@ -2922,29 +3328,45 @@
 
     hb_tag_t axis_tag = c->axes_index_tag_map->get (axisIndex);
 
-    //axis not pinned, keep the condition
-    if (!c->axes_location->has (axis_tag))
+    Triple axis_range (-1.f, 0.f, 1.f);
+    Triple *axis_limit;
+    if (c->axes_location->has (axis_tag, &axis_limit))
+      axis_range = *axis_limit;
+
+    float axis_min_val = axis_range.minimum;
+    float axis_default_val = axis_range.middle;
+    float axis_max_val = axis_range.maximum;
+
+    float filter_min_val = filterRangeMinValue.to_float ();
+    float filter_max_val = filterRangeMaxValue.to_float ();
+
+    if (axis_default_val < filter_min_val ||
+        axis_default_val > filter_max_val)
+      c->apply = false;
+
+    //condition not met, drop the entire record
+    if (axis_min_val > filter_max_val || axis_max_val < filter_min_val ||
+        filter_min_val > filter_max_val)
+      return DROP_RECORD_WITH_VAR;
+
+    //condition met and axis pinned, drop the condition
+    if (c->axes_location->has (axis_tag) &&
+        c->axes_location->get (axis_tag).is_point ())
+      return DROP_COND_WITH_VAR;
+
+    if (filter_max_val != axis_max_val || filter_min_val != axis_min_val)
     {
       // add axisIndex->value into the hashmap so we can check if the record is
       // unique with variations
-      int16_t min_val = filterRangeMinValue.to_int ();
-      int16_t max_val = filterRangeMaxValue.to_int ();
-      hb_codepoint_t val = (max_val << 16) + min_val;
+      int16_t int_filter_max_val = filterRangeMaxValue.to_int ();
+      int16_t int_filter_min_val = filterRangeMinValue.to_int ();
+      hb_codepoint_t val = (int_filter_max_val << 16) + int_filter_min_val;
 
       condition_map->set (axisIndex, val);
       return KEEP_COND_WITH_VAR;
     }
 
-    //axis pinned, check if condition is met
-    //TODO: add check for axis Ranges
-    int v = c->axes_location->get (axis_tag);
-
-    //condition not met, drop the entire record
-    if (v < filterRangeMinValue.to_int () || v > filterRangeMaxValue.to_int ())
-      return DROP_RECORD_WITH_VAR;
-
-    //axis pinned and condition met, drop the condition
-    return DROP_COND_WITH_VAR;
+    return KEEP_RECORD_WITH_VAR;
   }
 
   bool evaluate (const int *coords, unsigned int coord_len) const
@@ -2983,7 +3405,7 @@
   {
     switch (u.format) {
     case 1: return u.format1.keep_with_variations (c, condition_map);
-    default:return KEEP_COND_WITH_VAR;
+    default: c->apply = false; return KEEP_COND_WITH_VAR;
     }
   }
 
@@ -3028,45 +3450,50 @@
     return true;
   }
 
-  Cond_with_Var_flag_t keep_with_variations (hb_collect_feature_substitutes_with_var_context_t *c) const
+  void keep_with_variations (hb_collect_feature_substitutes_with_var_context_t *c) const
   {
     hb_map_t *condition_map = hb_map_create ();
-    if (unlikely (!condition_map)) return MEM_ERR_WITH_VAR;
+    if (unlikely (!condition_map)) return;
     hb::shared_ptr<hb_map_t> p {condition_map};
 
     hb_set_t *cond_set = hb_set_create ();
-    if (unlikely (!cond_set)) return MEM_ERR_WITH_VAR;
+    if (unlikely (!cond_set)) return;
     hb::shared_ptr<hb_set_t> s {cond_set};
 
+    c->apply = true;
+    bool should_keep = false;
     unsigned num_kept_cond = 0, cond_idx = 0;
     for (const auto& offset : conditions)
     {
       Cond_with_Var_flag_t ret = (this+offset).keep_with_variations (c, condition_map);
-      // one condition is not met, drop the entire record
+      // condition is not met or condition out of range, drop the entire record
       if (ret == DROP_RECORD_WITH_VAR)
-        return DROP_RECORD_WITH_VAR;
+        return;
 
-      // axis not pinned, keep this condition
       if (ret == KEEP_COND_WITH_VAR)
       {
+        should_keep = true;
         cond_set->add (cond_idx);
         num_kept_cond++;
       }
+
+      if (ret == KEEP_RECORD_WITH_VAR)
+        should_keep = true;
+
       cond_idx++;
     }
 
-    // all conditions met
-    if (num_kept_cond == 0) return DROP_COND_WITH_VAR;
+    if (!should_keep) return;
 
     //check if condition_set is unique with variations
     if (c->conditionset_map->has (p))
       //duplicate found, drop the entire record
-      return DROP_RECORD_WITH_VAR;
+      return;
 
     c->conditionset_map->set (p, 1);
     c->record_cond_idx_map->set (c->cur_record_idx, s);
-
-    return KEEP_COND_WITH_VAR;
+    if (should_keep && num_kept_cond == 0)
+      c->universal = true;
   }
 
   bool subset (hb_subset_context_t *c,
@@ -3142,8 +3569,7 @@
     if (unlikely (!out)) return_trace (false);
 
     out->featureIndex = c->feature_index_map->get (featureIndex);
-    bool ret = out->feature.serialize_subset (c->subset_context, feature, base, c);
-    return_trace (ret);
+    return_trace (out->feature.serialize_subset (c->subset_context, feature, base, c));
   }
 
   bool sanitize (hb_sanitize_context_t *c, const void *base) const
@@ -3271,12 +3697,11 @@
   void collect_feature_substitutes_with_variations (hb_collect_feature_substitutes_with_var_context_t *c,
                                                     const void *base) const
   {
-    // ret == 1, all conditions met
-    if ((base+conditions).keep_with_variations (c) == DROP_COND_WITH_VAR &&
-        c->apply)
+    (base+conditions).keep_with_variations (c);
+    if (c->apply && !c->variation_applied)
     {
       (base+substitutions).collect_feature_substitutes_with_variations (c);
-      c->apply = false; // set variations only once
+      c->variation_applied = true; // set variations only once
     }
   }
 
@@ -3343,7 +3768,12 @@
     {
       c->cur_record_idx = i;
       varRecords[i].collect_feature_substitutes_with_variations (c, this);
+      if (c->universal)
+        break;
     }
+    if (c->variation_applied && !c->universal &&
+        !c->record_cond_idx_map->is_empty ())
+      c->insert_catch_all_feature_variation_record = true;
   }
 
   FeatureVariations* copy (hb_serialize_context_t *c) const
@@ -3538,22 +3968,13 @@
     auto *out = c->embed (this);
     if (unlikely (!out)) return_trace (nullptr);
 
-    unsigned new_idx = hb_first (*v);
-    out->varIdx = new_idx;
+    if (!c->check_assign (out->varIdx, hb_first (*v), HB_SERIALIZE_ERROR_INT_OVERFLOW))
+      return_trace (nullptr);
     return_trace (out);
   }
 
   void collect_variation_index (hb_collect_variation_indices_context_t *c) const
-  {
-    c->layout_variation_indices->add (varIdx);
-    int delta = 0;
-    if (c->font && c->var_store)
-      delta = roundf (get_delta (c->font, *c->var_store, c->store_cache));
-
-    /* set new varidx to HB_OT_LAYOUT_NO_VARIATIONS_INDEX here, will remap
-     * varidx later*/
-    c->varidx_delta_map->set (varIdx, hb_pair_t<unsigned, int> (HB_OT_LAYOUT_NO_VARIATIONS_INDEX, delta));
-  }
+  { c->layout_variation_indices->add (varIdx); }
 
   bool sanitize (hb_sanitize_context_t *c) const
   {
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gsubgpos.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gsubgpos.hh
index 29efba4..d5b5a48 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gsubgpos.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout-gsubgpos.hh
@@ -143,9 +143,12 @@
     return active_glyphs_stack.tail ();
   }
 
-  hb_set_t& push_cur_active_glyphs ()
+  hb_set_t* push_cur_active_glyphs ()
   {
-    return *active_glyphs_stack.push ();
+    hb_set_t *s = active_glyphs_stack.push ();
+    if (unlikely (active_glyphs_stack.in_error ()))
+      return nullptr;
+    return s;
   }
 
   bool pop_cur_done_glyphs ()
@@ -399,16 +402,6 @@
 {
   struct matcher_t
   {
-    matcher_t () :
-             lookup_props (0),
-             mask (-1),
-             ignore_zwnj (false),
-             ignore_zwj (false),
-             per_syllable (false),
-             syllable {0},
-             match_func (nullptr),
-             match_data (nullptr) {}
-
     typedef bool (*match_func_t) (hb_glyph_info_t &info, unsigned value, const void *data);
 
     void set_ignore_zwnj (bool ignore_zwnj_) { ignore_zwnj = ignore_zwnj_; }
@@ -427,6 +420,9 @@
       MATCH_MAYBE
     };
 
+#ifndef HB_OPTIMIZE_SIZE
+    HB_ALWAYS_INLINE
+#endif
     may_match_t may_match (hb_glyph_info_t &info,
                            hb_codepoint_t glyph_data) const
     {
@@ -446,6 +442,9 @@
       SKIP_MAYBE
     };
 
+#ifndef HB_OPTIMIZE_SIZE
+    HB_ALWAYS_INLINE
+#endif
     may_skip_t may_skip (const hb_ot_apply_context_t *c,
                          const hb_glyph_info_t       &info) const
     {
@@ -461,14 +460,14 @@
     }
 
     protected:
-    unsigned int lookup_props;
-    hb_mask_t mask;
-    bool ignore_zwnj;
-    bool ignore_zwj;
-    bool per_syllable;
-    uint8_t syllable;
-    match_func_t match_func;
-    const void *match_data;
+    unsigned int lookup_props = 0;
+    hb_mask_t mask = -1;
+    bool ignore_zwnj = false;
+    bool ignore_zwj = false;
+    bool per_syllable = false;
+    uint8_t syllable = 0;
+    match_func_t match_func = nullptr;
+    const void *match_data = nullptr;
   };
 
   struct skipping_iterator_t
@@ -476,6 +475,7 @@
     void init (hb_ot_apply_context_t *c_, bool context_match = false)
     {
       c = c_;
+      end = c->buffer->len;
       match_glyph_data16 = nullptr;
 #ifndef HB_NO_BEYOND_64K
       match_glyph_data24 = nullptr;
@@ -489,6 +489,7 @@
       matcher.set_mask (context_match ? -1 : c->lookup_mask);
       /* Per syllable matching is only for GSUB. */
       matcher.set_per_syllable (c->table_index == 0 && c->per_syllable);
+      matcher.set_syllable (0);
     }
     void set_lookup_props (unsigned int lookup_props)
     {
@@ -514,22 +515,34 @@
     }
 #endif
 
-    void reset (unsigned int start_index_,
-                unsigned int num_items_)
+#ifndef HB_OPTIMIZE_SIZE
+    HB_ALWAYS_INLINE
+#endif
+    void reset (unsigned int start_index_)
     {
       idx = start_index_;
-      num_items = num_items_;
       end = c->buffer->len;
       matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0);
     }
 
+#ifndef HB_OPTIMIZE_SIZE
+    HB_ALWAYS_INLINE
+#endif
+    void reset_fast (unsigned int start_index_)
+    {
+      // Doesn't set end or syllable. Used by GPOS which doesn't care / change.
+      idx = start_index_;
+    }
+
     void reject ()
     {
-      num_items++;
       backup_glyph_data ();
     }
 
     matcher_t::may_skip_t
+#ifndef HB_OPTIMIZE_SIZE
+    HB_ALWAYS_INLINE
+#endif
     may_skip (const hb_glyph_info_t &info) const
     { return matcher.may_skip (c, info); }
 
@@ -539,6 +552,9 @@
       SKIP
     };
 
+#ifndef HB_OPTIMIZE_SIZE
+    HB_ALWAYS_INLINE
+#endif
     match_t match (hb_glyph_info_t &info)
     {
       matcher_t::may_skip_t skip = matcher.may_skip (c, info);
@@ -557,14 +573,12 @@
       return SKIP;
   }
 
+#ifndef HB_OPTIMIZE_SIZE
+    HB_ALWAYS_INLINE
+#endif
     bool next (unsigned *unsafe_to = nullptr)
     {
-      assert (num_items > 0);
-      /* The alternate condition below is faster at string boundaries,
-       * but produces subpar "unsafe-to-concat" values. */
-      signed stop = (signed) end - (signed) num_items;
-      if (c->buffer->flags & HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT)
-        stop = (signed) end - 1;
+      const signed stop = (signed) end - 1;
       while ((signed) idx < stop)
       {
         idx++;
@@ -572,7 +586,6 @@
         {
           case MATCH:
           {
-            num_items--;
             advance_glyph_data ();
             return true;
           }
@@ -590,14 +603,12 @@
         *unsafe_to = end;
       return false;
     }
+#ifndef HB_OPTIMIZE_SIZE
+    HB_ALWAYS_INLINE
+#endif
     bool prev (unsigned *unsafe_from = nullptr)
     {
-      assert (num_items > 0);
-      /* The alternate condition below is faster at string boundaries,
-       * but produces subpar "unsafe-to-concat" values. */
-      unsigned stop = num_items - 1;
-      if (c->buffer->flags & HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT)
-        stop = 1 - 1;
+      const unsigned stop = 0;
       while (idx > stop)
       {
         idx--;
@@ -605,7 +616,6 @@
         {
           case MATCH:
           {
-            num_items--;
             advance_glyph_data ();
             return true;
           }
@@ -624,6 +634,7 @@
       return false;
     }
 
+    HB_ALWAYS_INLINE
     hb_codepoint_t
     get_glyph_data ()
     {
@@ -634,6 +645,7 @@
 #endif
       return 0;
     }
+    HB_ALWAYS_INLINE
     void
     advance_glyph_data ()
     {
@@ -662,7 +674,6 @@
     const HBUINT24 *match_glyph_data24;
 #endif
 
-    unsigned int num_items;
     unsigned int end;
   };
 
@@ -693,8 +704,10 @@
   hb_font_t *font;
   hb_face_t *face;
   hb_buffer_t *buffer;
+  hb_sanitize_context_t sanitizer;
   recurse_func_t recurse_func = nullptr;
   const GDEF &gdef;
+  const GDEF::accelerator_t &gdef_accel;
   const VariationStore &var_store;
   VariationStore::cache_t *var_store_cache;
   hb_set_digest_t digest;
@@ -718,9 +731,11 @@
 
   hb_ot_apply_context_t (unsigned int table_index_,
                          hb_font_t *font_,
-                         hb_buffer_t *buffer_) :
+                         hb_buffer_t *buffer_,
+                         hb_blob_t *table_blob_) :
                         table_index (table_index_),
                         font (font_), face (font->face), buffer (buffer_),
+                        sanitizer (table_blob_),
                         gdef (
 #ifndef HB_NO_OT_LAYOUT
                               *face->table.GDEF->table
@@ -728,6 +743,13 @@
                               Null (GDEF)
 #endif
                              ),
+                        gdef_accel (
+#ifndef HB_NO_OT_LAYOUT
+                              *face->table.GDEF
+#else
+                              Null (GDEF::accelerator_t)
+#endif
+                             ),
                         var_store (gdef.get_var_store ()),
                         var_store_cache (
 #ifndef HB_NO_VAR
@@ -754,10 +776,10 @@
     iter_context.init (this, true);
   }
 
-  void set_lookup_mask (hb_mask_t mask) { lookup_mask = mask; last_base = -1; last_base_until = 0; init_iters (); }
-  void set_auto_zwj (bool auto_zwj_) { auto_zwj = auto_zwj_; init_iters (); }
-  void set_auto_zwnj (bool auto_zwnj_) { auto_zwnj = auto_zwnj_; init_iters (); }
-  void set_per_syllable (bool per_syllable_) { per_syllable = per_syllable_; init_iters (); }
+  void set_lookup_mask (hb_mask_t mask, bool init = true) { lookup_mask = mask; last_base = -1; last_base_until = 0; if (init) init_iters (); }
+  void set_auto_zwj (bool auto_zwj_, bool init = true) { auto_zwj = auto_zwj_; if (init) init_iters (); }
+  void set_auto_zwnj (bool auto_zwnj_, bool init = true) { auto_zwnj = auto_zwnj_; if (init) init_iters (); }
+  void set_per_syllable (bool per_syllable_, bool init = true) { per_syllable = per_syllable_; if (init) init_iters (); }
   void set_random (bool random_) { random = random_; }
   void set_recurse_func (recurse_func_t func) { recurse_func = func; }
   void set_lookup_index (unsigned int lookup_index_) { lookup_index = lookup_index_; }
@@ -778,7 +800,7 @@
      * match_props has the set index.
      */
     if (match_props & LookupFlag::UseMarkFilteringSet)
-      return gdef.mark_set_covers (match_props >> 16, glyph);
+      return gdef_accel.mark_set_covers (match_props >> 16, glyph);
 
     /* The second byte of match_props has the meaning
      * "ignore marks of attachment type different than
@@ -790,10 +812,12 @@
     return true;
   }
 
+#ifndef HB_OPTIMIZE_SIZE
+  HB_ALWAYS_INLINE
+#endif
   bool check_glyph_property (const hb_glyph_info_t *info,
                              unsigned int  match_props) const
   {
-    hb_codepoint_t glyph = info->codepoint;
     unsigned int glyph_props = _hb_glyph_info_get_glyph_props (info);
 
     /* Not covered, if, for example, glyph class is ligature and
@@ -803,7 +827,7 @@
       return false;
 
     if (unlikely (glyph_props & HB_OT_LAYOUT_GLYPH_PROPS_MARK))
-      return match_properties_mark (glyph, glyph_props, match_props);
+      return match_properties_mark (info->codepoint, glyph_props, match_props);
 
     return true;
   }
@@ -836,7 +860,7 @@
     if (likely (has_glyph_classes))
     {
       props &= HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE;
-      _hb_glyph_info_set_glyph_props (&buffer->cur(), props | gdef.get_glyph_props (glyph_index));
+      _hb_glyph_info_set_glyph_props (&buffer->cur(), props | gdef_accel.get_glyph_props (glyph_index));
     }
     else if (class_guess)
     {
@@ -884,7 +908,7 @@
 
 #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
   template <typename T>
-  static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, hb_priority<1>) HB_RETURN (bool, obj->apply (c, true) )
+  static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, hb_priority<1>) HB_RETURN (bool, obj->apply_cached (c) )
   template <typename T>
   static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, hb_priority<0>) HB_RETURN (bool, obj->apply (c) )
   template <typename Type>
@@ -1148,6 +1172,10 @@
 }
 
 
+static inline bool match_always (hb_glyph_info_t &info HB_UNUSED, unsigned value HB_UNUSED, const void *data HB_UNUSED)
+{
+  return true;
+}
 static inline bool match_glyph (hb_glyph_info_t &info, unsigned value, const void *data HB_UNUSED)
 {
   return info.codepoint == value;
@@ -1168,6 +1196,28 @@
     info.syllable() = klass;
   return klass == value;
 }
+static inline bool match_class_cached1 (hb_glyph_info_t &info, unsigned value, const void *data)
+{
+  unsigned klass = info.syllable() & 0x0F;
+  if (klass < 15)
+    return klass == value;
+  const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data);
+  klass = class_def.get_class (info.codepoint);
+  if (likely (klass < 15))
+    info.syllable() = (info.syllable() & 0xF0) | klass;
+  return klass == value;
+}
+static inline bool match_class_cached2 (hb_glyph_info_t &info, unsigned value, const void *data)
+{
+  unsigned klass = (info.syllable() & 0xF0) >> 4;
+  if (klass < 15)
+    return klass == value;
+  const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data);
+  klass = class_def.get_class (info.codepoint);
+  if (likely (klass < 15))
+    info.syllable() = (info.syllable() & 0x0F) | (klass << 4);
+  return klass == value;
+}
 static inline bool match_coverage (hb_glyph_info_t &info, unsigned value, const void *data)
 {
   Offset16To<Coverage> coverage;
@@ -1196,14 +1246,17 @@
   return true;
 }
 template <typename HBUINT>
-static inline bool match_input (hb_ot_apply_context_t *c,
-                                unsigned int count, /* Including the first glyph (not matched) */
-                                const HBUINT input[], /* Array of input values--start with second glyph */
-                                match_func_t match_func,
-                                const void *match_data,
-                                unsigned int *end_position,
-                                unsigned int match_positions[HB_MAX_CONTEXT_LENGTH],
-                                unsigned int *p_total_component_count = nullptr)
+#ifndef HB_OPTIMIZE_SIZE
+HB_ALWAYS_INLINE
+#endif
+static bool match_input (hb_ot_apply_context_t *c,
+                         unsigned int count, /* Including the first glyph (not matched) */
+                         const HBUINT input[], /* Array of input values--start with second glyph */
+                         match_func_t match_func,
+                         const void *match_data,
+                         unsigned int *end_position,
+                         unsigned int match_positions[HB_MAX_CONTEXT_LENGTH],
+                         unsigned int *p_total_component_count = nullptr)
 {
   TRACE_APPLY (nullptr);
 
@@ -1212,7 +1265,7 @@
   hb_buffer_t *buffer = c->buffer;
 
   hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
-  skippy_iter.reset (buffer->idx, count - 1);
+  skippy_iter.reset (buffer->idx);
   skippy_iter.set_match_func (match_func, match_data);
   skippy_iter.set_glyph_data (input);
 
@@ -1241,7 +1294,6 @@
    */
 
   unsigned int total_component_count = 0;
-  total_component_count += _hb_glyph_info_get_lig_num_comps (&buffer->cur());
 
   unsigned int first_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur());
   unsigned int first_lig_comp = _hb_glyph_info_get_lig_comp (&buffer->cur());
@@ -1252,7 +1304,6 @@
     LIGBASE_MAY_SKIP
   } ligbase = LIGBASE_NOT_CHECKED;
 
-  match_positions[0] = buffer->idx;
   for (unsigned int i = 1; i < count; i++)
   {
     unsigned unsafe_to;
@@ -1317,7 +1368,12 @@
   *end_position = skippy_iter.idx + 1;
 
   if (p_total_component_count)
+  {
+    total_component_count += _hb_glyph_info_get_lig_num_comps (&buffer->cur());
     *p_total_component_count = total_component_count;
+  }
+
+  match_positions[0] = buffer->idx;
 
   return_trace (true);
 }
@@ -1436,17 +1492,20 @@
 }
 
 template <typename HBUINT>
-static inline bool match_backtrack (hb_ot_apply_context_t *c,
-                                    unsigned int count,
-                                    const HBUINT backtrack[],
-                                    match_func_t match_func,
-                                    const void *match_data,
-                                    unsigned int *match_start)
+#ifndef HB_OPTIMIZE_SIZE
+HB_ALWAYS_INLINE
+#endif
+static bool match_backtrack (hb_ot_apply_context_t *c,
+                             unsigned int count,
+                             const HBUINT backtrack[],
+                             match_func_t match_func,
+                             const void *match_data,
+                             unsigned int *match_start)
 {
   TRACE_APPLY (nullptr);
 
   hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context;
-  skippy_iter.reset (c->buffer->backtrack_len (), count);
+  skippy_iter.reset (c->buffer->backtrack_len ());
   skippy_iter.set_match_func (match_func, match_data);
   skippy_iter.set_glyph_data (backtrack);
 
@@ -1465,18 +1524,21 @@
 }
 
 template <typename HBUINT>
-static inline bool match_lookahead (hb_ot_apply_context_t *c,
-                                    unsigned int count,
-                                    const HBUINT lookahead[],
-                                    match_func_t match_func,
-                                    const void *match_data,
-                                    unsigned int start_index,
-                                    unsigned int *end_index)
+#ifndef HB_OPTIMIZE_SIZE
+HB_ALWAYS_INLINE
+#endif
+static bool match_lookahead (hb_ot_apply_context_t *c,
+                             unsigned int count,
+                             const HBUINT lookahead[],
+                             match_func_t match_func,
+                             const void *match_data,
+                             unsigned int start_index,
+                             unsigned int *end_index)
 {
   TRACE_APPLY (nullptr);
 
   hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context;
-  skippy_iter.reset (start_index - 1, count);
+  skippy_iter.reset (start_index - 1);
   skippy_iter.set_match_func (match_func, match_data);
   skippy_iter.set_glyph_data (lookahead);
 
@@ -1595,10 +1657,13 @@
     }
 
     covered_seq_indicies.add (seqIndex);
+    hb_set_t *cur_active_glyphs = c->push_cur_active_glyphs ();
+    if (unlikely (!cur_active_glyphs))
+      return;
     if (has_pos_glyphs) {
-      c->push_cur_active_glyphs () = std::move (pos_glyphs);
+      *cur_active_glyphs = std::move (pos_glyphs);
     } else {
-      c->push_cur_active_glyphs ().set (*c->glyphs);
+      *cur_active_glyphs = *c->glyphs;
     }
 
     unsigned endIndex = inputCount;
@@ -1848,12 +1913,13 @@
 }
 
 template <typename HBUINT>
-static inline bool context_apply_lookup (hb_ot_apply_context_t *c,
-                                         unsigned int inputCount, /* Including the first glyph (not matched) */
-                                         const HBUINT input[], /* Array of input values--start with second glyph */
-                                         unsigned int lookupCount,
-                                         const LookupRecord lookupRecord[],
-                                         const ContextApplyLookupContext &lookup_context)
+HB_ALWAYS_INLINE
+static bool context_apply_lookup (hb_ot_apply_context_t *c,
+                                  unsigned int inputCount, /* Including the first glyph (not matched) */
+                                  const HBUINT input[], /* Array of input values--start with second glyph */
+                                  unsigned int lookupCount,
+                                  const LookupRecord lookupRecord[],
+                                  const ContextApplyLookupContext &lookup_context)
 {
   unsigned match_end = 0;
   unsigned match_positions[HB_MAX_CONTEXT_LENGTH];
@@ -1879,6 +1945,9 @@
 template <typename Types>
 struct Rule
 {
+  template <typename T>
+  friend struct RuleSet;
+
   bool intersects (const hb_set_t *glyphs, ContextClosureLookupContext &lookup_context) const
   {
     return context_intersects (glyphs,
@@ -1981,8 +2050,7 @@
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    return_trace (inputCount.sanitize (c) &&
-                  lookupCount.sanitize (c) &&
+    return_trace (c->check_struct (this) &&
                   c->check_range (inputZ.arrayZ,
                                   inputZ.item_size * (inputCount ? inputCount - 1 : 0) +
                                   LookupRecord::static_size * lookupCount));
@@ -2066,13 +2134,105 @@
               const ContextApplyLookupContext &lookup_context) const
   {
     TRACE_APPLY (this);
-    return_trace (
-    + hb_iter (rule)
-    | hb_map (hb_add (this))
-    | hb_map ([&] (const Rule &_) { return _.apply (c, lookup_context); })
-    | hb_any
-    )
-    ;
+
+    unsigned num_rules = rule.len;
+
+#ifndef HB_NO_OT_RULESETS_FAST_PATH
+    if (HB_OPTIMIZE_SIZE_VAL || num_rules <= 4)
+#endif
+    {
+    slow:
+      return_trace (
+      + hb_iter (rule)
+      | hb_map (hb_add (this))
+      | hb_map ([&] (const Rule &_) { return _.apply (c, lookup_context); })
+      | hb_any
+      )
+      ;
+    }
+
+    /* This version is optimized for speed by matching the first & second
+     * components of the rule here, instead of calling into the matching code.
+     *
+     * Replicated from LigatureSet::apply(). */
+
+    hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
+    skippy_iter.reset (c->buffer->idx);
+    skippy_iter.set_match_func (match_always, nullptr);
+    skippy_iter.set_glyph_data ((HBUINT16 *) nullptr);
+    unsigned unsafe_to = (unsigned) -1, unsafe_to1 = 0, unsafe_to2 = 0;
+    hb_glyph_info_t *first = nullptr, *second = nullptr;
+    bool matched = skippy_iter.next ();
+    if (likely (matched))
+    {
+      first = &c->buffer->info[skippy_iter.idx];
+      unsafe_to = skippy_iter.idx + 1;
+
+      if (skippy_iter.may_skip (c->buffer->info[skippy_iter.idx]))
+      {
+        /* Can't use the fast path if eg. the next char is a default-ignorable
+         * or other skippable. */
+        goto slow;
+      }
+    }
+    else
+    {
+      /* Failed to match a next glyph. Only try applying rules that have
+       * no further input. */
+      return_trace (
+      + hb_iter (rule)
+      | hb_map (hb_add (this))
+      | hb_filter ([&] (const Rule &_) { return _.inputCount <= 1; })
+      | hb_map ([&] (const Rule &_) { return _.apply (c, lookup_context); })
+      | hb_any
+      )
+      ;
+    }
+    matched = skippy_iter.next ();
+    if (likely (matched && !skippy_iter.may_skip (c->buffer->info[skippy_iter.idx])))
+    {
+      second = &c->buffer->info[skippy_iter.idx];
+      unsafe_to2 = skippy_iter.idx + 1;
+    }
+
+    auto match_input = lookup_context.funcs.match;
+    auto *input_data = lookup_context.match_data;
+    for (unsigned int i = 0; i < num_rules; i++)
+    {
+      const auto &r = this+rule.arrayZ[i];
+
+      const auto &input = r.inputZ;
+
+      if (r.inputCount <= 1 ||
+          (!match_input ||
+           match_input (*first, input.arrayZ[0], input_data)))
+      {
+        if (!second ||
+            (r.inputCount <= 2 ||
+             (!match_input ||
+              match_input (*second, input.arrayZ[1], input_data)))
+           )
+        {
+          if (r.apply (c, lookup_context))
+          {
+            if (unsafe_to != (unsigned) -1)
+              c->buffer->unsafe_to_concat (c->buffer->idx, unsafe_to);
+            return_trace (true);
+          }
+        }
+        else
+          unsafe_to = unsafe_to2;
+      }
+      else
+      {
+        if (unsafe_to == (unsigned) -1)
+          unsafe_to = unsafe_to1;
+      }
+    }
+    if (likely (unsafe_to != (unsigned) -1))
+      c->buffer->unsafe_to_concat (c->buffer->idx, unsafe_to);
+
+    return_trace (false);
   }
 
   bool subset (hb_subset_context_t *c,
@@ -2148,8 +2308,9 @@
 
   void closure (hb_closure_context_t *c) const
   {
-    hb_set_t& cur_active_glyphs = c->push_cur_active_glyphs ();
-    get_coverage ().intersect_set (c->previous_parent_active_glyphs (), cur_active_glyphs);
+    hb_set_t* cur_active_glyphs = c->push_cur_active_glyphs ();
+    if (unlikely (!cur_active_glyphs)) return;
+    get_coverage ().intersect_set (c->previous_parent_active_glyphs (), *cur_active_glyphs);
 
     struct ContextClosureLookupContext lookup_context = {
       {intersects_glyph, intersected_glyph},
@@ -2318,9 +2479,10 @@
     if (!(this+coverage).intersects (c->glyphs))
       return;
 
-    hb_set_t& cur_active_glyphs = c->push_cur_active_glyphs ();
+    hb_set_t* cur_active_glyphs = c->push_cur_active_glyphs ();
+    if (unlikely (!cur_active_glyphs)) return;
     get_coverage ().intersect_set (c->previous_parent_active_glyphs (),
-                                                 cur_active_glyphs);
+                                   *cur_active_glyphs);
 
     const ClassDef &class_def = this+classDef;
 
@@ -2431,7 +2593,9 @@
     }
   }
 
-  bool apply (hb_ot_apply_context_t *c, bool cached = false) const
+  bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); }
+  bool apply (hb_ot_apply_context_t *c) const { return _apply (c, false); }
+  bool _apply (hb_ot_apply_context_t *c, bool cached) const
   {
     TRACE_APPLY (this);
     unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
@@ -2447,11 +2611,7 @@
     if (cached && c->buffer->cur().syllable() < 255)
       index = c->buffer->cur().syllable ();
     else
-    {
       index = class_def.get_class (c->buffer->cur().codepoint);
-      if (cached && index < 255)
-        c->buffer->cur().syllable() = index;
-    }
     const RuleSet &rule_set = this+ruleSet[index];
     return_trace (rule_set.apply (c, lookup_context));
   }
@@ -2561,10 +2721,10 @@
     if (!(this+coverageZ[0]).intersects (c->glyphs))
       return;
 
-    hb_set_t& cur_active_glyphs = c->push_cur_active_glyphs ();
+    hb_set_t* cur_active_glyphs = c->push_cur_active_glyphs ();
+    if (unlikely (!cur_active_glyphs)) return;
     get_coverage ().intersect_set (c->previous_parent_active_glyphs (),
-                                                 cur_active_glyphs);
-
+                                   *cur_active_glyphs);
 
     const LookupRecord *lookupRecord = &StructAfter<LookupRecord> (coverageZ.as_array (glyphCount));
     struct ContextClosureLookupContext lookup_context = {
@@ -2665,14 +2825,14 @@
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    if (!c->check_struct (this)) return_trace (false);
+    if (unlikely (!c->check_struct (this))) return_trace (false);
     unsigned int count = glyphCount;
-    if (!count) return_trace (false); /* We want to access coverageZ[0] freely. */
-    if (!c->check_array (coverageZ.arrayZ, count)) return_trace (false);
+    if (unlikely (!count)) return_trace (false); /* We want to access coverageZ[0] freely. */
+    if (unlikely (!c->check_array (coverageZ.arrayZ, count))) return_trace (false);
     for (unsigned int i = 0; i < count; i++)
-      if (!coverageZ[i].sanitize (c, this)) return_trace (false);
+      if (unlikely (!coverageZ[i].sanitize (c, this))) return_trace (false);
     const LookupRecord *lookupRecord = &StructAfter<LookupRecord> (coverageZ.as_array (glyphCount));
-    return_trace (c->check_array (lookupRecord, lookupCount));
+    return_trace (likely (c->check_array (lookupRecord, lookupCount)));
   }
 
   protected:
@@ -2845,16 +3005,17 @@
 }
 
 template <typename HBUINT>
-static inline bool chain_context_apply_lookup (hb_ot_apply_context_t *c,
-                                               unsigned int backtrackCount,
-                                               const HBUINT backtrack[],
-                                               unsigned int inputCount, /* Including the first glyph (not matched) */
-                                               const HBUINT input[], /* Array of input values--start with second glyph */
-                                               unsigned int lookaheadCount,
-                                               const HBUINT lookahead[],
-                                               unsigned int lookupCount,
-                                               const LookupRecord lookupRecord[],
-                                               const ChainContextApplyLookupContext &lookup_context)
+HB_ALWAYS_INLINE
+static bool chain_context_apply_lookup (hb_ot_apply_context_t *c,
+                                        unsigned int backtrackCount,
+                                        const HBUINT backtrack[],
+                                        unsigned int inputCount, /* Including the first glyph (not matched) */
+                                        const HBUINT input[], /* Array of input values--start with second glyph */
+                                        unsigned int lookaheadCount,
+                                        const HBUINT lookahead[],
+                                        unsigned int lookupCount,
+                                        const LookupRecord lookupRecord[],
+                                        const ChainContextApplyLookupContext &lookup_context)
 {
   unsigned end_index = c->buffer->idx;
   unsigned match_end = 0;
@@ -2893,6 +3054,9 @@
 template <typename Types>
 struct ChainRule
 {
+  template <typename T>
+  friend struct ChainRuleSet;
+
   bool intersects (const hb_set_t *glyphs, ChainContextClosureLookupContext &lookup_context) const
   {
     const auto &input = StructAfter<decltype (inputX)> (backtrack);
@@ -2992,8 +3156,6 @@
                   const hb_map_t *lookahead_map = nullptr) const
   {
     TRACE_SERIALIZE (this);
-    auto *out = c->start_embed (this);
-    if (unlikely (!out)) return_trace (false);
 
     const hb_map_t *mapping = backtrack_map;
     serialize_array (c, backtrack.len, + backtrack.iter ()
@@ -3055,13 +3217,14 @@
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    if (!backtrack.sanitize (c)) return_trace (false);
+    /* Hyper-optimized sanitized because this is really hot. */
+    if (unlikely (!backtrack.len.sanitize (c))) return_trace (false);
     const auto &input = StructAfter<decltype (inputX)> (backtrack);
-    if (!input.sanitize (c)) return_trace (false);
+    if (unlikely (!input.lenP1.sanitize (c))) return_trace (false);
     const auto &lookahead = StructAfter<decltype (lookaheadX)> (input);
-    if (!lookahead.sanitize (c)) return_trace (false);
+    if (unlikely (!lookahead.len.sanitize (c))) return_trace (false);
     const auto &lookup = StructAfter<decltype (lookupX)> (lookahead);
-    return_trace (lookup.sanitize (c));
+    return_trace (likely (lookup.sanitize (c)));
   }
 
   protected:
@@ -3069,7 +3232,7 @@
                 backtrack;              /* Array of backtracking values
                                          * (to be matched before the input
                                          * sequence) */
-  HeadlessArrayOf<typename Types::HBUINT>
+  HeadlessArray16Of<typename Types::HBUINT>
                 inputX;                 /* Array of input values (start with
                                          * second glyph) */
   Array16Of<typename Types::HBUINT>
@@ -3142,13 +3305,119 @@
               const ChainContextApplyLookupContext &lookup_context) const
   {
     TRACE_APPLY (this);
-    return_trace (
-    + hb_iter (rule)
-    | hb_map (hb_add (this))
-    | hb_map ([&] (const ChainRule &_) { return _.apply (c, lookup_context); })
-    | hb_any
-    )
-    ;
+
+    unsigned num_rules = rule.len;
+
+#ifndef HB_NO_OT_RULESETS_FAST_PATH
+    if (HB_OPTIMIZE_SIZE_VAL || num_rules <= 4)
+#endif
+    {
+    slow:
+      return_trace (
+      + hb_iter (rule)
+      | hb_map (hb_add (this))
+      | hb_map ([&] (const ChainRule &_) { return _.apply (c, lookup_context); })
+      | hb_any
+      )
+      ;
+    }
+
+    /* This version is optimized for speed by matching the first & second
+     * components of the rule here, instead of calling into the matching code.
+     *
+     * Replicated from LigatureSet::apply(). */
+
+    hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
+    skippy_iter.reset (c->buffer->idx);
+    skippy_iter.set_match_func (match_always, nullptr);
+    skippy_iter.set_glyph_data ((HBUINT16 *) nullptr);
+    unsigned unsafe_to = (unsigned) -1, unsafe_to1 = 0, unsafe_to2 = 0;
+    hb_glyph_info_t *first = nullptr, *second = nullptr;
+    bool matched = skippy_iter.next ();
+    if (likely (matched))
+    {
+      first = &c->buffer->info[skippy_iter.idx];
+      unsafe_to1 = skippy_iter.idx + 1;
+
+      if (skippy_iter.may_skip (c->buffer->info[skippy_iter.idx]))
+      {
+        /* Can't use the fast path if eg. the next char is a default-ignorable
+         * or other skippable. */
+        goto slow;
+      }
+    }
+    else
+    {
+      /* Failed to match a next glyph. Only try applying rules that have
+       * no further input and lookahead. */
+      return_trace (
+      + hb_iter (rule)
+      | hb_map (hb_add (this))
+      | hb_filter ([&] (const ChainRule &_)
+                   {
+                     const auto &input = StructAfter<decltype (_.inputX)> (_.backtrack);
+                     const auto &lookahead = StructAfter<decltype (_.lookaheadX)> (input);
+                     return input.lenP1 <= 1 && lookahead.len == 0;
+                   })
+      | hb_map ([&] (const ChainRule &_) { return _.apply (c, lookup_context); })
+      | hb_any
+      )
+      ;
+    }
+    matched = skippy_iter.next ();
+    if (likely (matched && !skippy_iter.may_skip (c->buffer->info[skippy_iter.idx])))
+     {
+      second = &c->buffer->info[skippy_iter.idx];
+      unsafe_to2 = skippy_iter.idx + 1;
+     }
+
+    auto match_input = lookup_context.funcs.match[1];
+    auto match_lookahead = lookup_context.funcs.match[2];
+    auto *input_data = lookup_context.match_data[1];
+    auto *lookahead_data = lookup_context.match_data[2];
+    for (unsigned int i = 0; i < num_rules; i++)
+    {
+      const auto &r = this+rule.arrayZ[i];
+
+      const auto &input = StructAfter<decltype (r.inputX)> (r.backtrack);
+      const auto &lookahead = StructAfter<decltype (r.lookaheadX)> (input);
+
+      unsigned lenP1 = hb_max ((unsigned) input.lenP1, 1u);
+      if (lenP1 > 1 ?
+           (!match_input ||
+            match_input (*first, input.arrayZ[0], input_data))
+          :
+           (!lookahead.len || !match_lookahead ||
+            match_lookahead (*first, lookahead.arrayZ[0], lookahead_data)))
+      {
+        if (!second ||
+            (lenP1 > 2 ?
+             (!match_input ||
+              match_input (*second, input.arrayZ[1], input_data))
+             :
+             (lookahead.len <= 2 - lenP1 || !match_lookahead ||
+              match_lookahead (*second, lookahead.arrayZ[2 - lenP1], lookahead_data))))
+        {
+          if (r.apply (c, lookup_context))
+          {
+            if (unsafe_to != (unsigned) -1)
+              c->buffer->unsafe_to_concat (c->buffer->idx, unsafe_to);
+            return_trace (true);
+          }
+        }
+        else
+          unsafe_to = unsafe_to2;
+      }
+      else
+      {
+        if (unsafe_to == (unsigned) -1)
+          unsafe_to = unsafe_to1;
+      }
+    }
+    if (likely (unsafe_to != (unsigned) -1))
+      c->buffer->unsafe_to_concat (c->buffer->idx, unsafe_to);
+
+    return_trace (false);
   }
 
   bool subset (hb_subset_context_t *c,
@@ -3229,9 +3498,10 @@
 
   void closure (hb_closure_context_t *c) const
   {
-    hb_set_t& cur_active_glyphs = c->push_cur_active_glyphs ();
+    hb_set_t* cur_active_glyphs = c->push_cur_active_glyphs ();
+    if (unlikely (!cur_active_glyphs)) return;
     get_coverage ().intersect_set (c->previous_parent_active_glyphs (),
-                                                 cur_active_glyphs);
+                                   *cur_active_glyphs);
 
     struct ChainContextClosureLookupContext lookup_context = {
       {intersects_glyph, intersected_glyph},
@@ -3401,10 +3671,10 @@
     if (!(this+coverage).intersects (c->glyphs))
       return;
 
-    hb_set_t& cur_active_glyphs = c->push_cur_active_glyphs ();
+    hb_set_t* cur_active_glyphs = c->push_cur_active_glyphs ();
+    if (unlikely (!cur_active_glyphs)) return;
     get_coverage ().intersect_set (c->previous_parent_active_glyphs (),
-                                                 cur_active_glyphs);
-
+                                   *cur_active_glyphs);
 
     const ClassDef &backtrack_class_def = this+backtrackClassDef;
     const ClassDef &input_class_def = this+inputClassDef;
@@ -3534,7 +3804,9 @@
     }
   }
 
-  bool apply (hb_ot_apply_context_t *c, bool cached = false) const
+  bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); }
+  bool apply (hb_ot_apply_context_t *c) const { return _apply (c, false); }
+  bool _apply (hb_ot_apply_context_t *c, bool cached) const
   {
     TRACE_APPLY (this);
     unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
@@ -3544,26 +3816,22 @@
     const ClassDef &input_class_def = this+inputClassDef;
     const ClassDef &lookahead_class_def = this+lookaheadClassDef;
 
-    /* For ChainContextFormat2_5 we cache the LookaheadClassDef instead of InputClassDef.
-     * The reason is that most heavy fonts want to identify a glyph in context and apply
-     * a lookup to it. In this scenario, the length of the input sequence is one, whereas
-     * the lookahead / backtrack are typically longer.  The one glyph in input sequence is
-     * looked-up below and no input glyph is looked up in individual rules, whereas the
-     * lookahead and backtrack glyphs are tried.  Since we match lookahead before backtrack,
-     * we should cache lookahead.  This decisions showed a 20% improvement in shaping of
-     * the Gulzar font.
-     */
-
+    /* match_class_caches1 is slightly faster. Use it for lookahead,
+     * which is typically longer. */
     struct ChainContextApplyLookupContext lookup_context = {
-      {{cached && &backtrack_class_def == &lookahead_class_def ? match_class_cached : match_class,
-        cached && &input_class_def == &lookahead_class_def ? match_class_cached : match_class,
-        cached ? match_class_cached : match_class}},
+      {{cached && &backtrack_class_def == &lookahead_class_def ? match_class_cached1 : match_class,
+        cached ? match_class_cached2 : match_class,
+        cached ? match_class_cached1 : match_class}},
       {&backtrack_class_def,
        &input_class_def,
        &lookahead_class_def}
     };
 
-    index = input_class_def.get_class (c->buffer->cur().codepoint);
+    // Note: Corresponds to match_class_cached2
+    if (cached && ((c->buffer->cur().syllable() & 0xF0) >> 4) < 15)
+      index = (c->buffer->cur().syllable () & 0xF0) >> 4;
+    else
+      index = input_class_def.get_class (c->buffer->cur().codepoint);
     const ChainRuleSet &rule_set = this+ruleSet[index];
     return_trace (rule_set.apply (c, lookup_context));
   }
@@ -3703,10 +3971,11 @@
     if (!(this+input[0]).intersects (c->glyphs))
       return;
 
-    hb_set_t& cur_active_glyphs = c->push_cur_active_glyphs ();
+    hb_set_t* cur_active_glyphs = c->push_cur_active_glyphs ();
+    if (unlikely (!cur_active_glyphs))
+      return;
     get_coverage ().intersect_set (c->previous_parent_active_glyphs (),
-                                                 cur_active_glyphs);
-
+                                   *cur_active_glyphs);
 
     const auto &lookahead = StructAfter<decltype (lookaheadX)> (input);
     const auto &lookup = StructAfter<decltype (lookupX)> (lookahead);
@@ -3825,8 +4094,6 @@
   {
     TRACE_SUBSET (this);
 
-    auto *out = c->serializer->start_embed (this);
-    if (unlikely (!out)) return_trace (false);
     if (unlikely (!c->serializer->embed (this->format))) return_trace (false);
 
     if (!serialize_coverage_offsets (c, backtrack.iter (), this))
@@ -3853,14 +4120,14 @@
   bool sanitize (hb_sanitize_context_t *c) const
   {
     TRACE_SANITIZE (this);
-    if (!backtrack.sanitize (c, this)) return_trace (false);
+    if (unlikely (!backtrack.sanitize (c, this))) return_trace (false);
     const auto &input = StructAfter<decltype (inputX)> (backtrack);
-    if (!input.sanitize (c, this)) return_trace (false);
-    if (!input.len) return_trace (false); /* To be consistent with Context. */
+    if (unlikely (!input.sanitize (c, this))) return_trace (false);
+    if (unlikely (!input.len)) return_trace (false); /* To be consistent with Context. */
     const auto &lookahead = StructAfter<decltype (lookaheadX)> (input);
-    if (!lookahead.sanitize (c, this)) return_trace (false);
+    if (unlikely (!lookahead.sanitize (c, this))) return_trace (false);
     const auto &lookup = StructAfter<decltype (lookupX)> (lookahead);
-    return_trace (lookup.sanitize (c));
+    return_trace (likely (lookup.sanitize (c)));
   }
 
   protected:
@@ -3950,7 +4217,7 @@
     TRACE_SUBSET (this);
 
     auto *out = c->serializer->start_embed (this);
-    if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
 
     out->format = format;
     out->extensionLookupType = extensionLookupType;
@@ -4068,6 +4335,9 @@
   bool may_have (hb_codepoint_t g) const
   { return digest.may_have (g); }
 
+#ifndef HB_OPTIMIZE_SIZE
+  HB_ALWAYS_INLINE
+#endif
   bool apply (hb_ot_apply_context_t *c, unsigned subtables_count, bool use_cache) const
   {
 #ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
@@ -4479,7 +4749,10 @@
   {
     accelerator_t (hb_face_t *face)
     {
-      this->table = hb_sanitize_context_t ().reference_table<T> (face);
+      hb_sanitize_context_t sc;
+      sc.lazy_some_gpos = true;
+      this->table = sc.reference_table<T> (face);
+
       if (unlikely (this->table->is_blocklisted (this->table.get_blob (), face)))
       {
         hb_blob_destroy (this->table.get_blob ());
@@ -4504,6 +4777,8 @@
       this->table.destroy ();
     }
 
+    hb_blob_t *get_blob () const { return table.get_blob (); }
+
     hb_ot_layout_lookup_accelerator_t *get_accel (unsigned lookup_index) const
     {
       if (unlikely (lookup_index >= lookup_count)) return nullptr;
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.cc
index 39431fd..49465ac 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.cc
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.cc
@@ -64,8 +64,8 @@
  * @include: hb-ot.h
  *
  * Functions for querying OpenType Layout features in the font face.
- * See the <ulink url="http://www.microsoft.com/typography/otspec/">OpenType
- * specification</ulink> for details.
+ * See the [OpenType specification](http://www.microsoft.com/typography/otspec/)
+ * for details.
  **/
 
 
@@ -257,12 +257,13 @@
 {
   _hb_buffer_assert_gsubgpos_vars (buffer);
 
-  const OT::GDEF &gdef = *font->face->table.GDEF->table;
+  const auto &gdef = *font->face->table.GDEF;
   unsigned int count = buffer->len;
+  hb_glyph_info_t *info = buffer->info;
   for (unsigned int i = 0; i < count; i++)
   {
-    _hb_glyph_info_set_glyph_props (&buffer->info[i], gdef.get_glyph_props (buffer->info[i].codepoint));
-    _hb_glyph_info_clear_lig_props (&buffer->info[i]);
+    _hb_glyph_info_set_glyph_props (&info[i], gdef.get_glyph_props (info[i].codepoint));
+    _hb_glyph_info_clear_lig_props (&info[i]);
   }
 }
 
@@ -1240,7 +1241,7 @@
  *   terminated by %HB_TAG_NONE
  * @features: (nullable) (array zero-terminated=1): The array of features to collect,
  *   terminated by %HB_TAG_NONE
- * @feature_indexes: (out): The array of feature indexes found for the query
+ * @feature_indexes: (out): The set of feature indexes found for the query
  *
  * Fetches a list of all feature indexes in the specified face's GSUB table
  * or GPOS table, underneath the specified scripts, languages, and features.
@@ -1281,6 +1282,49 @@
   }
 }
 
+/**
+ * hb_ot_layout_collect_features_map:
+ * @face: #hb_face_t to work upon
+ * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
+ * @script_index: The index of the requested script tag
+ * @language_index: The index of the requested language tag
+ * @feature_map: (out): The map of feature tag to feature index.
+ *
+ * Fetches the mapping from feature tags to feature indexes for
+ * the specified script and language.
+ *
+ * Since: 8.1.0
+ **/
+void
+hb_ot_layout_collect_features_map (hb_face_t      *face,
+                                   hb_tag_t        table_tag,
+                                   unsigned        script_index,
+                                   unsigned        language_index,
+                                   hb_map_t       *feature_map /* OUT */)
+{
+  const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
+  const OT::LangSys &l = g.get_script (script_index).get_lang_sys (language_index);
+
+  unsigned int count = l.get_feature_indexes (0, nullptr, nullptr);
+  feature_map->alloc (count);
+
+  /* Loop in reverse, such that earlier entries win. That emulates
+   * a linear search, which seems to be what other implementations do.
+   * We found that with arialuni_t.ttf, the "ur" language system has
+   * duplicate features, and the earlier ones work but not later ones.
+   */
+  for (unsigned int i = count; i; i--)
+  {
+    unsigned feature_index = 0;
+    unsigned feature_count = 1;
+    l.get_feature_indexes (i - 1, &feature_count, &feature_index);
+    if (!feature_count)
+      break;
+    hb_tag_t feature_tag = g.get_feature_tag (feature_index);
+    feature_map->set (feature_tag, feature_index);
+  }
+}
+
 
 /**
  * hb_ot_layout_collect_lookups:
@@ -1315,8 +1359,7 @@
   hb_set_t feature_indexes;
   hb_ot_layout_collect_features (face, table_tag, scripts, languages, features, &feature_indexes);
 
-  for (hb_codepoint_t feature_index = HB_SET_VALUE_INVALID;
-       hb_set_next (&feature_indexes, &feature_index);)
+  for (auto feature_index : feature_indexes)
     g.get_feature (feature_index).add_lookup_indexes_to (lookup_indexes);
 
   g.feature_variation_collect_lookups (&feature_indexes, nullptr, lookup_indexes);
@@ -1569,7 +1612,7 @@
     glyphs_length = glyphs->get_population ();
     if (lookups)
     {
-      for (hb_codepoint_t lookup_index = HB_SET_VALUE_INVALID; hb_set_next (lookups, &lookup_index);)
+      for (auto lookup_index : *lookups)
         gsub.get_lookup (lookup_index).closure (&c, lookup_index);
     }
     else
@@ -1895,7 +1938,7 @@
     if (accel.digest.may_have (buffer->cur().codepoint) &&
         (buffer->cur().mask & c->lookup_mask) &&
         c->check_glyph_property (&buffer->cur(), c->lookup_props))
-     ret |= accel.apply (c, subtable_count, false);
+      ret |= accel.apply (c, subtable_count, false);
 
     /* The reverse lookup doesn't "advance" cursor (for good reason). */
     buffer->idx--;
@@ -1952,7 +1995,7 @@
 {
   const unsigned int table_index = proxy.table_index;
   unsigned int i = 0;
-  OT::hb_ot_apply_context_t c (table_index, font, buffer);
+  OT::hb_ot_apply_context_t c (table_index, font, buffer, proxy.accel.get_blob ());
   c.set_recurse_func (Proxy::Lookup::template dispatch_recurse_func<OT::hb_ot_apply_context_t>);
 
   for (unsigned int stage_index = 0; stage_index < stages[table_index].length; stage_index++)
@@ -1977,11 +2020,12 @@
       if (accel->digest.may_have (c.digest))
       {
         c.set_lookup_index (lookup_index);
-        c.set_lookup_mask (lookup.mask);
-        c.set_auto_zwj (lookup.auto_zwj);
-        c.set_auto_zwnj (lookup.auto_zwnj);
+        c.set_lookup_mask (lookup.mask, false);
+        c.set_auto_zwj (lookup.auto_zwj, false);
+        c.set_auto_zwnj (lookup.auto_zwnj, false);
         c.set_random (lookup.random);
-        c.set_per_syllable (lookup.per_syllable);
+        c.set_per_syllable (lookup.per_syllable, false);
+        /* apply_string's set_lookup_props initializes the iterators. */
 
         apply_string<Proxy> (&c,
                              proxy.accel.table->get_lookup (lookup_index),
@@ -2009,20 +2053,20 @@
 {
   GSUBProxy proxy (font->face);
   if (buffer->messaging () &&
-      !buffer->message (font, "start table GSUB")) return;
+      !buffer->message (font, "start table GSUB script tag '%c%c%c%c'", HB_UNTAG (chosen_script[0]))) return;
   apply (proxy, plan, font, buffer);
   if (buffer->messaging ())
-    (void) buffer->message (font, "end table GSUB");
+    (void) buffer->message (font, "end table GSUB script tag '%c%c%c%c'", HB_UNTAG (chosen_script[0]));
 }
 
 void hb_ot_map_t::position (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer) const
 {
   GPOSProxy proxy (font->face);
   if (buffer->messaging () &&
-      !buffer->message (font, "start table GPOS")) return;
+      !buffer->message (font, "start table GPOS script tag '%c%c%c%c'", HB_UNTAG (chosen_script[1]))) return;
   apply (proxy, plan, font, buffer);
   if (buffer->messaging ())
-    (void) buffer->message (font, "end table GPOS");
+    (void) buffer->message (font, "end table GPOS script tag '%c%c%c%c'", HB_UNTAG (chosen_script[1]));
 }
 
 void
@@ -2034,6 +2078,112 @@
 }
 
 #ifndef HB_NO_BASE
+
+static void
+choose_base_tags (hb_script_t    script,
+                  hb_language_t  language,
+                  hb_tag_t      *script_tag,
+                  hb_tag_t      *language_tag)
+{
+  hb_tag_t script_tags[HB_OT_MAX_TAGS_PER_SCRIPT];
+  unsigned script_count = ARRAY_LENGTH (script_tags);
+
+  hb_tag_t language_tags[HB_OT_MAX_TAGS_PER_LANGUAGE];
+  unsigned language_count = ARRAY_LENGTH (language_tags);
+
+  hb_ot_tags_from_script_and_language (script, language,
+                                       &script_count, script_tags,
+                                       &language_count, language_tags);
+
+  *script_tag = script_count ? script_tags[script_count - 1] : HB_OT_TAG_DEFAULT_SCRIPT;
+  *language_tag = language_count ? language_tags[language_count - 1] : HB_OT_TAG_DEFAULT_LANGUAGE;
+}
+
+/**
+ * hb_ot_layout_get_font_extents:
+ * @font: a font
+ * @direction: text direction.
+ * @script_tag:  script tag.
+ * @language_tag: language tag.
+ * @extents: (out) (nullable): font extents if found.
+ *
+ * Fetches script/language-specific font extents.  These values are
+ * looked up in the `BASE` table's `MinMax` records.
+ *
+ * If no such extents are found, the default extents for the font are
+ * fetched. As such, the return value of this function can for the
+ * most part be ignored.  Note that the per-script/language extents
+ * do not have a line-gap value, and the line-gap is set to zero in
+ * that case.
+ *
+ * Return value: `true` if found script/language-specific font extents.
+ *
+ * Since: 8.0.0
+ **/
+hb_bool_t
+hb_ot_layout_get_font_extents (hb_font_t         *font,
+                               hb_direction_t     direction,
+                               hb_tag_t           script_tag,
+                               hb_tag_t           language_tag,
+                               hb_font_extents_t *extents)
+{
+  hb_position_t min, max;
+  if (font->face->table.BASE->get_min_max (font, direction, script_tag, language_tag, HB_TAG_NONE,
+                                           &min, &max))
+  {
+    if (extents)
+    {
+      extents->ascender  = max;
+      extents->descender = min;
+      extents->line_gap  = 0;
+    }
+    return true;
+  }
+
+  hb_font_get_extents_for_direction (font, direction, extents);
+  return false;
+}
+
+/**
+ * hb_ot_layout_get_font_extents2:
+ * @font: a font
+ * @direction: text direction.
+ * @script:  script.
+ * @language: (nullable): language.
+ * @extents: (out) (nullable): font extents if found.
+ *
+ * Fetches script/language-specific font extents.  These values are
+ * looked up in the `BASE` table's `MinMax` records.
+ *
+ * If no such extents are found, the default extents for the font are
+ * fetched. As such, the return value of this function can for the
+ * most part be ignored.  Note that the per-script/language extents
+ * do not have a line-gap value, and the line-gap is set to zero in
+ * that case.
+ *
+ * This function is like hb_ot_layout_get_font_extents() but takes
+ * #hb_script_t and #hb_language_t instead of OpenType #hb_tag_t.
+ *
+ * Return value: `true` if found script/language-specific font extents.
+ *
+ * Since: 8.0.0
+ **/
+hb_bool_t
+hb_ot_layout_get_font_extents2 (hb_font_t         *font,
+                                hb_direction_t     direction,
+                                hb_script_t        script,
+                                hb_language_t      language,
+                                hb_font_extents_t *extents)
+{
+  hb_tag_t script_tag, language_tag;
+  choose_base_tags (script, language, &script_tag, &language_tag);
+  return hb_ot_layout_get_font_extents (font,
+                                        direction,
+                                        script_tag,
+                                        language_tag,
+                                        extents);
+}
+
 /**
  * hb_ot_layout_get_horizontal_baseline_tag_for_script:
  * @script: a script tag.
@@ -2132,6 +2282,42 @@
 }
 
 /**
+ * hb_ot_layout_get_baseline2:
+ * @font: a font
+ * @baseline_tag: a baseline tag
+ * @direction: text direction.
+ * @script:  script.
+ * @language: (nullable): language, currently unused.
+ * @coord: (out) (nullable): baseline value if found.
+ *
+ * Fetches a baseline value from the face.
+ *
+ * This function is like hb_ot_layout_get_baseline() but takes
+ * #hb_script_t and #hb_language_t instead of OpenType #hb_tag_t.
+ *
+ * Return value: `true` if found baseline value in the font.
+ *
+ * Since: 8.0.0
+ **/
+hb_bool_t
+hb_ot_layout_get_baseline2 (hb_font_t                   *font,
+                            hb_ot_layout_baseline_tag_t  baseline_tag,
+                            hb_direction_t               direction,
+                            hb_script_t                  script,
+                            hb_language_t                language,
+                            hb_position_t               *coord        /* OUT.  May be NULL. */)
+{
+  hb_tag_t script_tag, language_tag;
+  choose_base_tags (script, language, &script_tag, &language_tag);
+  return hb_ot_layout_get_baseline (font,
+                                    baseline_tag,
+                                    direction,
+                                    script_tag,
+                                    language_tag,
+                                    coord);
+}
+
+/**
  * hb_ot_layout_get_baseline_with_fallback:
  * @font: a font
  * @baseline_tag: a baseline tag
@@ -2353,6 +2539,41 @@
   }
 }
 
+/**
+ * hb_ot_layout_get_baseline_with_fallback2:
+ * @font: a font
+ * @baseline_tag: a baseline tag
+ * @direction: text direction.
+ * @script:  script.
+ * @language: (nullable): language, currently unused.
+ * @coord: (out): baseline value if found.
+ *
+ * Fetches a baseline value from the face, and synthesizes
+ * it if the font does not have it.
+ *
+ * This function is like hb_ot_layout_get_baseline_with_fallback() but takes
+ * #hb_script_t and #hb_language_t instead of OpenType #hb_tag_t.
+ *
+ * Since: 8.0.0
+ **/
+void
+hb_ot_layout_get_baseline_with_fallback2 (hb_font_t                   *font,
+                                          hb_ot_layout_baseline_tag_t  baseline_tag,
+                                          hb_direction_t               direction,
+                                          hb_script_t                  script,
+                                          hb_language_t                language,
+                                          hb_position_t               *coord        /* OUT */)
+{
+  hb_tag_t script_tag, language_tag;
+  choose_base_tags (script, language, &script_tag, &language_tag);
+  hb_ot_layout_get_baseline_with_fallback (font,
+                                           baseline_tag,
+                                           direction,
+                                           script_tag,
+                                           language_tag,
+                                           coord);
+}
+
 #endif
 
 
@@ -2449,9 +2670,10 @@
                                        hb_codepoint_t  glyph)
 {
   const OT::PosLookup &lookup = font->face->table.GPOS->table->get_lookup (lookup_index);
+  hb_blob_t *blob = font->face->table.GPOS->get_blob ();
   hb_glyph_position_t pos = {0};
   hb_position_single_dispatch_t c;
-  lookup.dispatch (&c, font, direction, glyph, pos);
+  lookup.dispatch (&c, font, blob, direction, glyph, pos);
   hb_position_t ret = 0;
   switch (direction)
   {
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.h b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.h
index 9b0dcc7..1d9db11 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.h
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.h
@@ -325,6 +325,13 @@
                                hb_set_t       *feature_indexes /* OUT */);
 
 HB_EXTERN void
+hb_ot_layout_collect_features_map (hb_face_t      *face,
+                                   hb_tag_t        table_tag,
+                                   unsigned        script_index,
+                                   unsigned        language_index,
+                                   hb_map_t       *feature_map /* OUT */);
+
+HB_EXTERN void
 hb_ot_layout_collect_lookups (hb_face_t      *face,
                               hb_tag_t        table_tag,
                               const hb_tag_t *scripts,
@@ -447,6 +454,20 @@
  * BASE
  */
 
+HB_EXTERN hb_bool_t
+hb_ot_layout_get_font_extents (hb_font_t         *font,
+                               hb_direction_t     direction,
+                               hb_tag_t           script_tag,
+                               hb_tag_t           language_tag,
+                               hb_font_extents_t *extents);
+
+HB_EXTERN hb_bool_t
+hb_ot_layout_get_font_extents2 (hb_font_t         *font,
+                                hb_direction_t     direction,
+                                hb_script_t        script,
+                                hb_language_t      language,
+                                hb_font_extents_t *extents);
+
 /**
  * hb_ot_layout_baseline_tag_t:
  * @HB_OT_LAYOUT_BASELINE_TAG_ROMAN: The baseline used by alphabetic scripts such as Latin, Cyrillic and Greek.
@@ -499,6 +520,14 @@
                            hb_tag_t                     language_tag,
                            hb_position_t               *coord        /* OUT.  May be NULL. */);
 
+HB_EXTERN hb_bool_t
+hb_ot_layout_get_baseline2 (hb_font_t                   *font,
+                            hb_ot_layout_baseline_tag_t  baseline_tag,
+                            hb_direction_t               direction,
+                            hb_script_t                  script,
+                            hb_language_t                language,
+                            hb_position_t               *coord        /* OUT.  May be NULL. */);
+
 HB_EXTERN void
 hb_ot_layout_get_baseline_with_fallback (hb_font_t                   *font,
                                          hb_ot_layout_baseline_tag_t  baseline_tag,
@@ -507,6 +536,14 @@
                                          hb_tag_t                     language_tag,
                                          hb_position_t               *coord        /* OUT */);
 
+HB_EXTERN void
+hb_ot_layout_get_baseline_with_fallback2 (hb_font_t                   *font,
+                                          hb_ot_layout_baseline_tag_t  baseline_tag,
+                                          hb_direction_t               direction,
+                                          hb_script_t                  script,
+                                          hb_language_t                language,
+                                          hb_position_t               *coord        /* OUT */);
+
 HB_END_DECLS
 
 #endif /* HB_OT_LAYOUT_H */
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.hh
index bcebb64..2d9a184 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-layout.hh
@@ -448,7 +448,7 @@
 static inline bool
 _hb_glyph_info_ligated_internal (const hb_glyph_info_t *info)
 {
-  return !!(info->lig_props() & IS_LIG_BASE);
+  return info->lig_props() & IS_LIG_BASE;
 }
 
 static inline unsigned int
@@ -496,37 +496,37 @@
 static inline bool
 _hb_glyph_info_is_base_glyph (const hb_glyph_info_t *info)
 {
-  return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH);
+  return info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH;
 }
 
 static inline bool
 _hb_glyph_info_is_ligature (const hb_glyph_info_t *info)
 {
-  return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE);
+  return info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE;
 }
 
 static inline bool
 _hb_glyph_info_is_mark (const hb_glyph_info_t *info)
 {
-  return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK);
+  return info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MARK;
 }
 
 static inline bool
 _hb_glyph_info_substituted (const hb_glyph_info_t *info)
 {
-  return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED);
+  return info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED;
 }
 
 static inline bool
 _hb_glyph_info_ligated (const hb_glyph_info_t *info)
 {
-  return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATED);
+  return info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_LIGATED;
 }
 
 static inline bool
 _hb_glyph_info_multiplied (const hb_glyph_info_t *info)
 {
-  return !!(info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED);
+  return info->glyph_props() & HB_OT_LAYOUT_GLYPH_PROPS_MULTIPLIED;
 }
 
 static inline bool
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-map.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-map.cc
index f07f692..261ce43 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-map.cc
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-map.cc
@@ -213,7 +213,8 @@
   /* Sort features and merge duplicates */
   if (feature_infos.length)
   {
-    feature_infos.qsort ();
+    if (!is_simple)
+      feature_infos.qsort ();
     auto *f = feature_infos.arrayZ;
     unsigned int j = 0;
     unsigned count = feature_infos.length;
@@ -238,6 +239,13 @@
     feature_infos.shrink (j + 1);
   }
 
+  hb_map_t feature_indices[2];
+  for (unsigned int table_index = 0; table_index < 2; table_index++)
+    hb_ot_layout_collect_features_map (face,
+                                       table_tags[table_index],
+                                       script_index[table_index],
+                                       language_index[table_index],
+                                       &feature_indices[table_index]);
 
   /* Allocate bits now */
   static_assert ((!(HB_GLYPH_FLAG_DEFINED & (HB_GLYPH_FLAG_DEFINED + 1))), "");
@@ -260,7 +268,6 @@
     if (!info->max_value || next_bit + bits_needed >= global_bit_shift)
       continue; /* Feature disabled, or not enough bits. */
 
-
     bool found = false;
     unsigned int feature_index[2];
     for (unsigned int table_index = 0; table_index < 2; table_index++)
@@ -268,12 +275,14 @@
       if (required_feature_tag[table_index] == info->tag)
         required_feature_stage[table_index] = info->stage[table_index];
 
-      found |= (bool) hb_ot_layout_language_find_feature (face,
-                                                          table_tags[table_index],
-                                                          script_index[table_index],
-                                                          language_index[table_index],
-                                                          info->tag,
-                                                          &feature_index[table_index]);
+      hb_codepoint_t *index;
+      if (feature_indices[table_index].has (info->tag, &index))
+      {
+        feature_index[table_index] = *index;
+        found = true;
+      }
+      else
+        feature_index[table_index] = HB_OT_LAYOUT_NO_FEATURE_INDEX;
     }
     if (!found && (info->flags & F_GLOBAL_SEARCH))
     {
@@ -314,7 +323,8 @@
     map->needs_fallback = !found;
   }
   //feature_infos.shrink (0); /* Done with these */
-
+  if (is_simple)
+    m.features.qsort ();
 
   add_gsub_pause (nullptr);
   add_gpos_pause (nullptr);
@@ -350,7 +360,7 @@
       }
 
       /* Sort lookups and merge duplicates */
-      if (last_num_lookups < lookups.length)
+      if (last_num_lookups + 1 < lookups.length)
       {
         lookups.as_array ().sub_array (last_num_lookups, lookups.length - last_num_lookups).qsort ();
 
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-map.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-map.hh
index e2e83bf..1103615 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-map.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-map.hh
@@ -60,6 +60,13 @@
 
     int cmp (const hb_tag_t tag_) const
     { return tag_ < tag ? -1 : tag_ > tag ? 1 : 0; }
+
+    HB_INTERNAL static int cmp (const void *pa, const void *pb)
+    {
+      const feature_map_t *a = (const feature_map_t *) pa;
+      const feature_map_t *b = (const feature_map_t *) pb;
+      return a->tag < b->tag ? -1 : a->tag > b->tag ? 1 : 0;
+    }
   };
 
   struct lookup_map_t {
@@ -273,6 +280,7 @@
 
   hb_face_t *face;
   hb_segment_properties_t props;
+  bool is_simple;
 
   hb_tag_t chosen_script[2];
   bool found_script[2];
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-math-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-math-table.hh
index 4b545ff..63bcd13 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-math-table.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-math-table.hh
@@ -73,7 +73,6 @@
   {
     TRACE_SERIALIZE (this);
     auto *out = c->start_embed (this);
-    if (unlikely (!out)) return_trace (nullptr);
 
     HBINT16 *p = c->allocate_size<HBINT16> (HBINT16::static_size * 2);
     if (unlikely (!p)) return_trace (nullptr);
@@ -310,7 +309,6 @@
   {
     TRACE_SERIALIZE (this);
     auto *out = c->start_embed (this);
-    if (unlikely (!out)) return_trace (nullptr);
 
     if (unlikely (!c->embed (heightCount))) return_trace (nullptr);
 
@@ -572,6 +570,7 @@
 
     auto it =
     + hb_iter (this+extendedShapeCoverage)
+    | hb_take (c->plan->source->get_num_glyphs ())
     | hb_filter (glyphset)
     | hb_map_retains_sorting (glyph_map)
     ;
@@ -757,8 +756,6 @@
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    auto *out = c->serializer->start_embed (*this);
-    if (unlikely (!out)) return_trace (false);
 
     if (!c->serializer->copy (italicsCorrection, this)) return_trace (false);
     if (!c->serializer->copy<HBUINT16> (partRecords.len)) return_trace (false);
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-math.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-math.cc
index 701562f..1911499 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-math.cc
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-math.cc
@@ -76,7 +76,7 @@
  *
  * However, if the requested constant is #HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN,
  * #HB_OT_MATH_CONSTANT_SCRIPT_SCRIPT_PERCENT_SCALE_DOWN or
- * #HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN, then the return value is
+ * #HB_OT_MATH_CONSTANT_RADICAL_DEGREE_BOTTOM_RAISE_PERCENT, then the return value is
  * an integer between 0 and 100 representing that percentage.
  *
  * Return value: the requested constant or zero
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-metrics.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-metrics.cc
index 7804920..4253d5b 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-metrics.cc
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-metrics.cc
@@ -196,7 +196,7 @@
         *position *= mult;
 
         if (font->slant)
-          *position += _hb_roundf (mult * font->slant_xy * rise);
+          *position += roundf (mult * font->slant_xy * rise);
       }
 
       return ret;
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-os2-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-os2-table.hh
index e685d23..30ae335 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-os2-table.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-os2-table.hh
@@ -246,24 +246,19 @@
     }
 #endif
 
-    if (c->plan->user_axes_location.has (HB_TAG ('w','g','h','t')) &&
-        !c->plan->pinned_at_default)
+    Triple *axis_range;
+    if (c->plan->user_axes_location.has (HB_TAG ('w','g','h','t'), &axis_range))
     {
-      float weight_class = c->plan->user_axes_location.get (HB_TAG ('w','g','h','t'));
-      if (!c->serializer->check_assign (os2_prime->usWeightClass,
-                                        roundf (hb_clamp (weight_class, 1.0f, 1000.0f)),
-                                        HB_SERIALIZE_ERROR_INT_OVERFLOW))
-        return_trace (false);
+      unsigned weight_class = static_cast<unsigned> (roundf (hb_clamp (axis_range->middle, 1.0f, 1000.0f)));
+      if (os2_prime->usWeightClass != weight_class)
+        os2_prime->usWeightClass = weight_class;
     }
 
-    if (c->plan->user_axes_location.has (HB_TAG ('w','d','t','h')) &&
-        !c->plan->pinned_at_default)
+    if (c->plan->user_axes_location.has (HB_TAG ('w','d','t','h'), &axis_range))
     {
-      float width = c->plan->user_axes_location.get (HB_TAG ('w','d','t','h'));
-      if (!c->serializer->check_assign (os2_prime->usWidthClass,
-                                        roundf (map_wdth_to_widthclass (width)),
-                                        HB_SERIALIZE_ERROR_INT_OVERFLOW))
-        return_trace (false);
+      unsigned width_class = static_cast<unsigned> (roundf (map_wdth_to_widthclass (axis_range->middle)));
+      if (os2_prime->usWidthClass != width_class)
+        os2_prime->usWidthClass = width_class;
     }
 
     if (c->plan->flags & HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES)
@@ -287,8 +282,7 @@
     /* This block doesn't show up in profiles. If it ever did,
      * we can rewrite it to iterate over OS/2 ranges and use
      * set iteration to check if the range matches. */
-    for (hb_codepoint_t cp = HB_SET_VALUE_INVALID;
-         codepoints->next (&cp);)
+    for (auto cp : *codepoints)
     {
       unsigned int bit = _hb_ot_os2_get_unicode_range_bit (cp);
       if (bit < 128)
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-post-table-v2subset.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-post-table-v2subset.hh
index 951e639..d442336 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-post-table-v2subset.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-post-table-v2subset.hh
@@ -79,6 +79,11 @@
   post::accelerator_t _post (c->plan->source);
 
   hb_hashmap_t<hb_bytes_t, uint32_t, true> glyph_name_to_new_index;
+
+  old_new_index_map.alloc (num_glyphs);
+  old_gid_new_index_map.alloc (num_glyphs);
+  glyph_name_to_new_index.alloc (num_glyphs);
+
   for (hb_codepoint_t new_gid = 0; new_gid < num_glyphs; new_gid++)
   {
     hb_codepoint_t old_gid = reverse_glyph_map.get (new_gid);
@@ -86,11 +91,12 @@
 
     unsigned new_index;
     const uint32_t *new_index2;
-    if (old_index <= 257) new_index = old_index;
+    if (old_index <= 257)
+      new_index = old_index;
     else if (old_new_index_map.has (old_index, &new_index2))
-    {
       new_index = *new_index2;
-    } else {
+    else
+    {
       hb_bytes_t s = _post.find_glyph_name (old_gid);
       new_index = glyph_name_to_new_index.get (s);
       if (new_index == (unsigned)-1)
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-post-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-post-table.hh
index 4426ede..d41c86f 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-post-table.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-post-table.hh
@@ -96,8 +96,7 @@
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    post *post_prime = c->serializer->start_embed<post> ();
-    if (unlikely (!post_prime)) return_trace (false);
+    auto *post_prime = c->serializer->start_embed<post> ();
 
     bool glyph_names = c->plan->flags & HB_SUBSET_FLAGS_GLYPH_NAMES;
     if (!serialize (c->serializer, glyph_names))
@@ -114,12 +113,12 @@
     }
 #endif
 
-    if (c->plan->user_axes_location.has (HB_TAG ('s','l','n','t')) &&
-        !c->plan->pinned_at_default)
+    Triple *axis_range;
+    if (c->plan->user_axes_location.has (HB_TAG ('s','l','n','t'), &axis_range))
     {
-      float italic_angle = c->plan->user_axes_location.get (HB_TAG ('s','l','n','t'));
-      italic_angle = hb_max (-90.f, hb_min (italic_angle, 90.f));
-      post_prime->italicAngle.set_float (italic_angle);
+      float italic_angle = hb_max (-90.f, hb_min (axis_range->middle, 90.f));
+      if (post_prime->italicAngle.to_float () != italic_angle)
+        post_prime->italicAngle.set_float (italic_angle);
     }
 
     if (glyph_names && version.major == 2)
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-normalize.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-normalize.cc
index fc85f04..b1acc7e 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-normalize.cc
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape-normalize.cc
@@ -383,14 +383,15 @@
   if (!all_simple && buffer->message(font, "start reorder"))
   {
     count = buffer->len;
+    hb_glyph_info_t *info = buffer->info;
     for (unsigned int i = 0; i < count; i++)
     {
-      if (_hb_glyph_info_get_modified_combining_class (&buffer->info[i]) == 0)
+      if (_hb_glyph_info_get_modified_combining_class (&info[i]) == 0)
         continue;
 
       unsigned int end;
       for (end = i + 1; end < count; end++)
-        if (_hb_glyph_info_get_modified_combining_class (&buffer->info[end]) == 0)
+        if (_hb_glyph_info_get_modified_combining_class (&info[end]) == 0)
           break;
 
       /* We are going to do a O(n^2).  Only do this if the sequence is short. */
@@ -414,11 +415,13 @@
      * If it did NOT, then make it skippable.
      * https://github.com/harfbuzz/harfbuzz/issues/554
      */
-    for (unsigned int i = 1; i + 1 < buffer->len; i++)
-      if (buffer->info[i].codepoint == 0x034Fu/*CGJ*/ &&
-          (info_cc(buffer->info[i+1]) == 0 || info_cc(buffer->info[i-1]) <= info_cc(buffer->info[i+1])))
+    unsigned count = buffer->len;
+    hb_glyph_info_t *info = buffer->info;
+    for (unsigned int i = 1; i + 1 < count; i++)
+      if (info[i].codepoint == 0x034Fu/*CGJ*/ &&
+          (info_cc(info[i+1]) == 0 || info_cc(info[i-1]) <= info_cc(info[i+1])))
       {
-        _hb_glyph_info_unhide (&buffer->info[i]);
+        _hb_glyph_info_unhide (&info[i]);
       }
   }
 
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.cc
index b5600d7..f936ac4 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.cc
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shape.cc
@@ -313,6 +313,8 @@
 {
   hb_ot_map_builder_t *map = &planner->map;
 
+  map->is_simple = true;
+
   map->enable_feature (HB_TAG('r','v','r','n'));
   map->add_gsub_pause (nullptr);
 
@@ -354,7 +356,10 @@
   map->enable_feature (HB_TAG ('H','A','R','F')); /* Considered discretionary. */
 
   if (planner->shaper->collect_features)
+  {
+    map->is_simple = false;
     planner->shaper->collect_features (planner);
+  }
 
   map->enable_feature (HB_TAG ('B','u','z','z')); /* Considered required. */
   map->enable_feature (HB_TAG ('B','U','Z','Z')); /* Considered discretionary. */
@@ -378,6 +383,8 @@
     map->enable_feature (HB_TAG ('v','e','r','t'), F_GLOBAL_SEARCH);
   }
 
+  if (num_user_features)
+    map->is_simple = false;
   for (unsigned int i = 0; i < num_user_features; i++)
   {
     const hb_feature_t *feature = &user_features[i];
@@ -469,9 +476,18 @@
   {
     _hb_glyph_info_set_unicode_props (&info[i], buffer);
 
+    unsigned gen_cat = _hb_glyph_info_get_general_category (&info[i]);
+    if (FLAG_UNSAFE (gen_cat) &
+        (FLAG (HB_UNICODE_GENERAL_CATEGORY_LOWERCASE_LETTER) |
+         FLAG (HB_UNICODE_GENERAL_CATEGORY_UPPERCASE_LETTER) |
+         FLAG (HB_UNICODE_GENERAL_CATEGORY_TITLECASE_LETTER) |
+         FLAG (HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER) |
+         FLAG (HB_UNICODE_GENERAL_CATEGORY_SPACE_SEPARATOR)))
+      continue;
+
     /* Marks are already set as continuation by the above line.
      * Handle Emoji_Modifier and ZWJ-continuation. */
-    if (unlikely (_hb_glyph_info_get_general_category (&info[i]) == HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL &&
+    if (unlikely (gen_cat == HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL &&
                   hb_in_range<hb_codepoint_t> (info[i].codepoint, 0x1F3FBu, 0x1F3FFu)))
     {
       _hb_glyph_info_set_continuation (&info[i]);
@@ -749,6 +765,14 @@
              _hb_glyph_info_get_general_category (&info[end]) ==
              HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER)
         end++;
+      if (start == i || end == i + 1)
+      {
+        if (start == i)
+          buffer->unsafe_to_concat (start, start + 1);
+        if (end == i + 1)
+          buffer->unsafe_to_concat (end - 1, end);
+        continue;
+      }
 
       buffer->unsafe_to_break (start, end);
 
@@ -1030,7 +1054,7 @@
    * direction is backward we don't shift and it will end up
    * hanging over the next glyph after the final reordering.
    *
-   * Note: If fallback positinoing happens, we don't care about
+   * Note: If fallback positioning happens, we don't care about
    * this as it will be overridden.
    */
   bool adjust_offsets_when_zeroing = c->plan->adjust_mark_positioning_when_zeroing &&
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-fallback.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-fallback.hh
index 6025ac0..858a987 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-fallback.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-fallback.hh
@@ -368,7 +368,7 @@
                             hb_font_t *font,
                             hb_buffer_t *buffer)
 {
-  OT::hb_ot_apply_context_t c (0, font, buffer);
+  OT::hb_ot_apply_context_t c (0, font, buffer, hb_blob_get_empty ());
   for (unsigned int i = 0; i < fallback_plan->num_lookups; i++)
     if (fallback_plan->lookup_array[i]) {
       c.set_lookup_mask (fallback_plan->mask_array[i]);
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-joining-list.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-joining-list.hh
index c7b5782..a5a7b84 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-joining-list.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-joining-list.hh
@@ -6,10 +6,10 @@
  *
  * on files with these headers:
  *
- * # ArabicShaping-15.0.0.txt
- * # Date: 2022-02-14, 18:50:00 GMT [KW, RP]
- * # Scripts-15.0.0.txt
- * # Date: 2022-04-26, 23:15:02 GMT
+ * # ArabicShaping-15.1.0.txt
+ * # Date: 2023-01-05
+ * # Scripts-15.1.0.txt
+ * # Date: 2023-07-28, 16:01:07 GMT
  */
 
 #ifndef HB_OT_SHAPER_ARABIC_JOINING_LIST_HH
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-table.hh
index edc0c41..8c25044 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-table.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic-table.hh
@@ -6,10 +6,10 @@
  *
  * on files with these headers:
  *
- * # ArabicShaping-15.0.0.txt
- * # Date: 2022-02-14, 18:50:00 GMT [KW, RP]
- * # Blocks-15.0.0.txt
- * # Date: 2022-01-28, 20:58:00 GMT [KW]
+ * # ArabicShaping-15.1.0.txt
+ * # Date: 2023-01-05
+ * # Blocks-15.1.0.txt
+ * # Date: 2023-07-28, 15:47:20 GMT
  * UnicodeData.txt does not have a header.
  */
 
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic.cc
index ac15203..87d76e1 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic.cc
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-arabic.cc
@@ -486,8 +486,10 @@
   if (likely (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_ARABIC_HAS_STCH)))
     return;
 
-  /* The Arabic shaper currently always processes in RTL mode, so we should
-   * stretch / position the stretched pieces to the left / preceding glyphs. */
+  bool rtl = buffer->props.direction == HB_DIRECTION_RTL;
+
+  if (!rtl)
+    buffer->reverse ();
 
   /* We do a two pass implementation:
    * First pass calculates the exact number of extra glyphs we need,
@@ -577,7 +579,10 @@
         ++n_copies;
         hb_position_t excess = (n_copies + 1) * sign * w_repeating - sign * w_remaining;
         if (excess > 0)
+        {
           extra_repeat_overlap = excess / (n_copies * n_repeating);
+          w_remaining = 0;
+        }
       }
 
       if (step == MEASURE)
@@ -588,7 +593,7 @@
       else
       {
         buffer->unsafe_to_break (context, end);
-        hb_position_t x_offset = 0;
+        hb_position_t x_offset = w_remaining / 2;
         for (unsigned int k = end; k > start; k--)
         {
           hb_position_t width = font->get_glyph_h_advance (info[k - 1].codepoint);
@@ -599,16 +604,27 @@
 
           DEBUG_MSG (ARABIC, nullptr, "appending %u copies of glyph %u; j=%u",
                      repeat, info[k - 1].codepoint, j);
+          pos[k - 1].x_advance = 0;
           for (unsigned int n = 0; n < repeat; n++)
           {
-            x_offset -= width;
-            if (n > 0)
-              x_offset += extra_repeat_overlap;
+            if (rtl)
+            {
+              x_offset -= width;
+              if (n > 0)
+                x_offset += extra_repeat_overlap;
+            }
             pos[k - 1].x_offset = x_offset;
             /* Append copy. */
             --j;
             info[j] = info[k - 1];
             pos[j] = pos[k - 1];
+
+            if (!rtl)
+            {
+              x_offset += width;
+              if (n > 0)
+                x_offset -= extra_repeat_overlap;
+            }
           }
         }
       }
@@ -625,6 +641,9 @@
       buffer->len = new_len;
     }
   }
+
+  if (!rtl)
+    buffer->reverse ();
 }
 
 
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-machine.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-machine.hh
index bef9d2a..6a6db44 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-machine.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-machine.hh
@@ -53,7 +53,7 @@
 };
 
 
-#line 54 "hb-ot-shaper-indic-machine.hh"
+#line 57 "hb-ot-shaper-indic-machine.hh"
 #define indic_syllable_machine_ex_A 9u
 #define indic_syllable_machine_ex_C 1u
 #define indic_syllable_machine_ex_CM 16u
@@ -76,7 +76,7 @@
 #define indic_syllable_machine_ex_ZWNJ 5u
 
 
-#line 75 "hb-ot-shaper-indic-machine.hh"
+#line 80 "hb-ot-shaper-indic-machine.hh"
 static const unsigned char _indic_syllable_machine_trans_keys[] = {
         8u, 8u, 4u, 13u, 5u, 13u, 5u, 13u, 13u, 13u, 4u, 13u, 4u, 13u, 4u, 13u,
         8u, 8u, 5u, 13u, 5u, 13u, 13u, 13u, 4u, 13u, 4u, 13u, 4u, 13u, 4u, 13u,
@@ -460,7 +460,7 @@
   int cs;
   hb_glyph_info_t *info = buffer->info;
 
-#line 453 "hb-ot-shaper-indic-machine.hh"
+#line 464 "hb-ot-shaper-indic-machine.hh"
         {
         cs = indic_syllable_machine_start;
         ts = 0;
@@ -476,7 +476,7 @@
 
   unsigned int syllable_serial = 1;
 
-#line 465 "hb-ot-shaper-indic-machine.hh"
+#line 480 "hb-ot-shaper-indic-machine.hh"
         {
         int _slen;
         int _trans;
@@ -490,7 +490,7 @@
 #line 1 "NONE"
         {ts = p;}
         break;
-#line 477 "hb-ot-shaper-indic-machine.hh"
+#line 494 "hb-ot-shaper-indic-machine.hh"
         }
 
         _keys = _indic_syllable_machine_trans_keys + (cs<<1);
@@ -593,7 +593,7 @@
 #line 114 "hb-ot-shaper-indic-machine.rl"
         {act = 6;}
         break;
-#line 559 "hb-ot-shaper-indic-machine.hh"
+#line 597 "hb-ot-shaper-indic-machine.hh"
         }
 
 _again:
@@ -602,7 +602,7 @@
 #line 1 "NONE"
         {ts = 0;}
         break;
-#line 566 "hb-ot-shaper-indic-machine.hh"
+#line 606 "hb-ot-shaper-indic-machine.hh"
         }
 
         if ( ++p != pe )
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-table.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-table.cc
index d9fb051..d9899a6 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-table.cc
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-indic-table.cc
@@ -6,12 +6,12 @@
  *
  * on files with these headers:
  *
- * # IndicSyllabicCategory-15.0.0.txt
- * # Date: 2022-05-26, 02:18:00 GMT [KW, RP]
- * # IndicPositionalCategory-15.0.0.txt
- * # Date: 2022-05-26, 02:18:00 GMT [KW, RP]
- * # Blocks-15.0.0.txt
- * # Date: 2022-01-28, 20:58:00 GMT [KW]
+ * # IndicSyllabicCategory-15.1.0.txt
+ * # Date: 2023-01-05
+ * # IndicPositionalCategory-15.1.0.txt
+ * # Date: 2023-01-05
+ * # Blocks-15.1.0.txt
+ * # Date: 2023-07-28, 15:47:20 GMT
  */
 
 #include "hb.hh"
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-khmer-machine.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-khmer-machine.hh
index 2442f03..e1f657c 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-khmer-machine.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-khmer-machine.hh
@@ -48,7 +48,7 @@
 };
 
 
-#line 49 "hb-ot-shaper-khmer-machine.hh"
+#line 52 "hb-ot-shaper-khmer-machine.hh"
 #define khmer_syllable_machine_ex_C 1u
 #define khmer_syllable_machine_ex_DOTTEDCIRCLE 11u
 #define khmer_syllable_machine_ex_H 4u
@@ -66,7 +66,7 @@
 #define khmer_syllable_machine_ex_ZWNJ 5u
 
 
-#line 65 "hb-ot-shaper-khmer-machine.hh"
+#line 70 "hb-ot-shaper-khmer-machine.hh"
 static const unsigned char _khmer_syllable_machine_trans_keys[] = {
         5u, 26u, 5u, 26u, 1u, 15u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u,
         5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 1u, 15u, 5u, 26u, 5u, 26u,
@@ -294,7 +294,7 @@
   int cs;
   hb_glyph_info_t *info = buffer->info;
 
-#line 287 "hb-ot-shaper-khmer-machine.hh"
+#line 298 "hb-ot-shaper-khmer-machine.hh"
         {
         cs = khmer_syllable_machine_start;
         ts = 0;
@@ -310,7 +310,7 @@
 
   unsigned int syllable_serial = 1;
 
-#line 299 "hb-ot-shaper-khmer-machine.hh"
+#line 314 "hb-ot-shaper-khmer-machine.hh"
         {
         int _slen;
         int _trans;
@@ -324,7 +324,7 @@
 #line 1 "NONE"
         {ts = p;}
         break;
-#line 311 "hb-ot-shaper-khmer-machine.hh"
+#line 328 "hb-ot-shaper-khmer-machine.hh"
         }
 
         _keys = _khmer_syllable_machine_trans_keys + (cs<<1);
@@ -394,7 +394,7 @@
 #line 98 "hb-ot-shaper-khmer-machine.rl"
         {act = 3;}
         break;
-#line 368 "hb-ot-shaper-khmer-machine.hh"
+#line 398 "hb-ot-shaper-khmer-machine.hh"
         }
 
 _again:
@@ -403,7 +403,7 @@
 #line 1 "NONE"
         {ts = 0;}
         break;
-#line 375 "hb-ot-shaper-khmer-machine.hh"
+#line 407 "hb-ot-shaper-khmer-machine.hh"
         }
 
         if ( ++p != pe )
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-myanmar-machine.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-myanmar-machine.hh
index 1fad047..3dcf61b 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-myanmar-machine.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-myanmar-machine.hh
@@ -50,7 +50,7 @@
 };
 
 
-#line 51 "hb-ot-shaper-myanmar-machine.hh"
+#line 54 "hb-ot-shaper-myanmar-machine.hh"
 #define myanmar_syllable_machine_ex_A 9u
 #define myanmar_syllable_machine_ex_As 32u
 #define myanmar_syllable_machine_ex_C 1u
@@ -77,7 +77,7 @@
 #define myanmar_syllable_machine_ex_ZWNJ 5u
 
 
-#line 76 "hb-ot-shaper-myanmar-machine.hh"
+#line 81 "hb-ot-shaper-myanmar-machine.hh"
 static const unsigned char _myanmar_syllable_machine_trans_keys[] = {
         1u, 41u, 3u, 41u, 5u, 39u, 5u, 8u, 3u, 41u, 3u, 39u, 3u, 39u, 5u, 39u,
         5u, 39u, 3u, 39u, 3u, 39u, 3u, 41u, 5u, 39u, 1u, 15u, 3u, 39u, 3u, 39u,
@@ -443,7 +443,7 @@
   int cs;
   hb_glyph_info_t *info = buffer->info;
 
-#line 436 "hb-ot-shaper-myanmar-machine.hh"
+#line 447 "hb-ot-shaper-myanmar-machine.hh"
         {
         cs = myanmar_syllable_machine_start;
         ts = 0;
@@ -459,7 +459,7 @@
 
   unsigned int syllable_serial = 1;
 
-#line 448 "hb-ot-shaper-myanmar-machine.hh"
+#line 463 "hb-ot-shaper-myanmar-machine.hh"
         {
         int _slen;
         int _trans;
@@ -473,7 +473,7 @@
 #line 1 "NONE"
         {ts = p;}
         break;
-#line 460 "hb-ot-shaper-myanmar-machine.hh"
+#line 477 "hb-ot-shaper-myanmar-machine.hh"
         }
 
         _keys = _myanmar_syllable_machine_trans_keys + (cs<<1);
@@ -519,7 +519,7 @@
 #line 113 "hb-ot-shaper-myanmar-machine.rl"
         {te = p;p--;{ found_syllable (myanmar_non_myanmar_cluster); }}
         break;
-#line 498 "hb-ot-shaper-myanmar-machine.hh"
+#line 523 "hb-ot-shaper-myanmar-machine.hh"
         }
 
 _again:
@@ -528,7 +528,7 @@
 #line 1 "NONE"
         {ts = 0;}
         break;
-#line 505 "hb-ot-shaper-myanmar-machine.hh"
+#line 532 "hb-ot-shaper-myanmar-machine.hh"
         }
 
         if ( ++p != pe )
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-syllabic.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-syllabic.cc
index 82272cb..81ab8b53 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-syllabic.cc
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-syllabic.cc
@@ -40,6 +40,14 @@
   if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE))
     return false;
   if (likely (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE)))
+  {
+    if (buffer->messaging ())
+      (void) buffer->message (font, "skipped inserting dotted-circles because there is no broken syllables");
+    return false;
+  }
+
+  if (buffer->messaging () &&
+      !buffer->message (font, "start inserting dotted-circles"))
     return false;
 
   hb_codepoint_t dottedcircle_glyph;
@@ -84,6 +92,10 @@
       (void) buffer->next_glyph ();
   }
   buffer->sync ();
+
+  if (buffer->messaging ())
+    (void) buffer->message (font, "end inserting dotted-circles");
+
   return true;
 }
 
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-machine.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-machine.hh
index 14ea666..47b0e6b 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-machine.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-machine.hh
@@ -53,7 +53,7 @@
 };
 
 
-#line 54 "hb-ot-shaper-use-machine.hh"
+#line 57 "hb-ot-shaper-use-machine.hh"
 #define use_syllable_machine_ex_B 1u
 #define use_syllable_machine_ex_CGJ 6u
 #define use_syllable_machine_ex_CMAbv 31u
@@ -68,7 +68,9 @@
 #define use_syllable_machine_ex_G 49u
 #define use_syllable_machine_ex_GB 5u
 #define use_syllable_machine_ex_H 12u
+#define use_syllable_machine_ex_HM 54u
 #define use_syllable_machine_ex_HN 13u
+#define use_syllable_machine_ex_HR 55u
 #define use_syllable_machine_ex_HVM 53u
 #define use_syllable_machine_ex_IS 44u
 #define use_syllable_machine_ex_J 50u
@@ -97,673 +99,662 @@
 #define use_syllable_machine_ex_ZWNJ 14u
 
 
-#line 96 "hb-ot-shaper-use-machine.hh"
+#line 103 "hb-ot-shaper-use-machine.hh"
 static const unsigned char _use_syllable_machine_trans_keys[] = {
-        0u, 53u, 11u, 53u, 11u, 53u, 1u, 53u, 14u, 48u, 14u, 47u, 14u, 47u, 14u, 47u,
-        14u, 46u, 14u, 46u, 14u, 14u, 14u, 48u, 14u, 48u, 14u, 48u, 1u, 14u, 14u, 48u,
-        14u, 53u, 14u, 53u, 14u, 53u, 14u, 53u, 12u, 53u, 14u, 53u, 12u, 53u, 12u, 53u,
-        12u, 53u, 11u, 53u, 1u, 14u, 1u, 48u, 11u, 53u, 14u, 42u, 14u, 42u, 11u, 53u,
+        49u, 51u, 0u, 53u, 11u, 53u, 11u, 53u, 1u, 53u, 14u, 48u, 14u, 47u, 14u, 47u,
+        14u, 47u, 14u, 46u, 14u, 46u, 14u, 14u, 14u, 48u, 14u, 48u, 14u, 48u, 1u, 14u,
+        14u, 48u, 14u, 53u, 14u, 53u, 14u, 53u, 14u, 53u, 12u, 53u, 14u, 53u, 12u, 53u,
+        12u, 53u, 12u, 53u, 11u, 53u, 1u, 14u, 1u, 48u, 14u, 42u, 14u, 42u, 11u, 53u,
+        1u, 53u, 14u, 48u, 14u, 47u, 14u, 47u, 14u, 47u, 14u, 46u, 14u, 46u, 14u, 14u,
+        14u, 48u, 14u, 48u, 14u, 48u, 1u, 14u, 14u, 48u, 14u, 53u, 14u, 53u, 14u, 53u,
+        14u, 53u, 12u, 53u, 14u, 53u, 12u, 53u, 12u, 53u, 12u, 53u, 11u, 53u, 1u, 14u,
+        1u, 14u, 1u, 48u, 13u, 14u, 4u, 14u, 11u, 53u, 11u, 53u, 1u, 53u, 14u, 48u,
+        14u, 47u, 14u, 47u, 14u, 47u, 14u, 46u, 14u, 46u, 14u, 14u, 14u, 48u, 14u, 48u,
+        14u, 48u, 1u, 14u, 14u, 48u, 14u, 53u, 14u, 53u, 14u, 53u, 14u, 53u, 12u, 53u,
+        14u, 53u, 12u, 53u, 12u, 53u, 12u, 53u, 11u, 53u, 1u, 14u, 1u, 14u, 1u, 48u,
         11u, 53u, 1u, 53u, 14u, 48u, 14u, 47u, 14u, 47u, 14u, 47u, 14u, 46u, 14u, 46u,
         14u, 14u, 14u, 48u, 14u, 48u, 14u, 48u, 1u, 14u, 14u, 48u, 14u, 53u, 14u, 53u,
         14u, 53u, 14u, 53u, 12u, 53u, 14u, 53u, 12u, 53u, 12u, 53u, 12u, 53u, 11u, 53u,
-        1u, 14u, 1u, 14u, 1u, 48u, 13u, 14u, 4u, 14u, 11u, 53u, 11u, 53u, 1u, 53u,
-        14u, 48u, 14u, 47u, 14u, 47u, 14u, 47u, 14u, 46u, 14u, 46u, 14u, 14u, 14u, 48u,
-        14u, 48u, 14u, 48u, 1u, 14u, 14u, 48u, 14u, 53u, 14u, 53u, 14u, 53u, 14u, 53u,
-        12u, 53u, 14u, 53u, 12u, 53u, 12u, 53u, 12u, 53u, 11u, 53u, 1u, 14u, 1u, 14u,
-        1u, 48u, 11u, 53u, 11u, 53u, 1u, 53u, 14u, 48u, 14u, 47u, 14u, 47u, 14u, 47u,
-        14u, 46u, 14u, 46u, 14u, 14u, 14u, 48u, 14u, 48u, 14u, 48u, 1u, 14u, 14u, 48u,
-        14u, 53u, 14u, 53u, 14u, 53u, 14u, 53u, 12u, 53u, 14u, 53u, 12u, 53u, 12u, 53u,
-        12u, 53u, 11u, 53u, 1u, 14u, 1u, 48u, 4u, 14u, 13u, 14u, 1u, 53u, 11u, 53u,
-        14u, 42u, 14u, 42u, 1u, 5u, 14u, 52u, 14u, 52u, 14u, 51u, 0
+        1u, 14u, 1u, 48u, 4u, 14u, 13u, 14u, 1u, 53u, 14u, 42u, 14u, 42u, 1u, 5u,
+        14u, 55u, 14u, 51u, 14u, 52u, 14u, 54u, 11u, 53u, 0
 };
 
 static const char _use_syllable_machine_key_spans[] = {
-        54, 43, 43, 53, 35, 34, 34, 34,
-        33, 33, 1, 35, 35, 35, 14, 35,
-        40, 40, 40, 40, 42, 40, 42, 42,
-        42, 43, 14, 48, 43, 29, 29, 43,
+        3, 54, 43, 43, 53, 35, 34, 34,
+        34, 33, 33, 1, 35, 35, 35, 14,
+        35, 40, 40, 40, 40, 42, 40, 42,
+        42, 42, 43, 14, 48, 29, 29, 43,
+        53, 35, 34, 34, 34, 33, 33, 1,
+        35, 35, 35, 14, 35, 40, 40, 40,
+        40, 42, 40, 42, 42, 42, 43, 14,
+        14, 48, 2, 11, 43, 43, 53, 35,
+        34, 34, 34, 33, 33, 1, 35, 35,
+        35, 14, 35, 40, 40, 40, 40, 42,
+        40, 42, 42, 42, 43, 14, 14, 48,
         43, 53, 35, 34, 34, 34, 33, 33,
         1, 35, 35, 35, 14, 35, 40, 40,
         40, 40, 42, 40, 42, 42, 42, 43,
-        14, 14, 48, 2, 11, 43, 43, 53,
-        35, 34, 34, 34, 33, 33, 1, 35,
-        35, 35, 14, 35, 40, 40, 40, 40,
-        42, 40, 42, 42, 42, 43, 14, 14,
-        48, 43, 43, 53, 35, 34, 34, 34,
-        33, 33, 1, 35, 35, 35, 14, 35,
-        40, 40, 40, 40, 42, 40, 42, 42,
-        42, 43, 14, 48, 11, 2, 53, 43,
-        29, 29, 5, 39, 39, 38
+        14, 48, 11, 2, 53, 29, 29, 5,
+        42, 38, 39, 41, 43
 };
 
 static const short _use_syllable_machine_index_offsets[] = {
-        0, 55, 99, 143, 197, 233, 268, 303,
-        338, 372, 406, 408, 444, 480, 516, 531,
-        567, 608, 649, 690, 731, 774, 815, 858,
-        901, 944, 988, 1003, 1052, 1096, 1126, 1156,
-        1200, 1244, 1298, 1334, 1369, 1404, 1439, 1473,
-        1507, 1509, 1545, 1581, 1617, 1632, 1668, 1709,
-        1750, 1791, 1832, 1875, 1916, 1959, 2002, 2045,
-        2089, 2104, 2119, 2168, 2171, 2183, 2227, 2271,
-        2325, 2361, 2396, 2431, 2466, 2500, 2534, 2536,
-        2572, 2608, 2644, 2659, 2695, 2736, 2777, 2818,
-        2859, 2902, 2943, 2986, 3029, 3072, 3116, 3131,
-        3146, 3195, 3239, 3283, 3337, 3373, 3408, 3443,
-        3478, 3512, 3546, 3548, 3584, 3620, 3656, 3671,
-        3707, 3748, 3789, 3830, 3871, 3914, 3955, 3998,
-        4041, 4084, 4128, 4143, 4192, 4204, 4207, 4261,
-        4305, 4335, 4365, 4371, 4411, 4451
+        0, 4, 59, 103, 147, 201, 237, 272,
+        307, 342, 376, 410, 412, 448, 484, 520,
+        535, 571, 612, 653, 694, 735, 778, 819,
+        862, 905, 948, 992, 1007, 1056, 1086, 1116,
+        1160, 1214, 1250, 1285, 1320, 1355, 1389, 1423,
+        1425, 1461, 1497, 1533, 1548, 1584, 1625, 1666,
+        1707, 1748, 1791, 1832, 1875, 1918, 1961, 2005,
+        2020, 2035, 2084, 2087, 2099, 2143, 2187, 2241,
+        2277, 2312, 2347, 2382, 2416, 2450, 2452, 2488,
+        2524, 2560, 2575, 2611, 2652, 2693, 2734, 2775,
+        2818, 2859, 2902, 2945, 2988, 3032, 3047, 3062,
+        3111, 3155, 3209, 3245, 3280, 3315, 3350, 3384,
+        3418, 3420, 3456, 3492, 3528, 3543, 3579, 3620,
+        3661, 3702, 3743, 3786, 3827, 3870, 3913, 3956,
+        4000, 4015, 4064, 4076, 4079, 4133, 4163, 4193,
+        4199, 4242, 4281, 4321, 4363
 };
 
 static const unsigned char _use_syllable_machine_indicies[] = {
-        0, 1, 2, 2, 3, 4, 2, 2,
-        2, 2, 2, 5, 6, 7, 8, 2,
-        2, 2, 9, 2, 2, 2, 10, 11,
-        12, 13, 14, 15, 16, 17, 18, 19,
-        20, 21, 22, 23, 2, 24, 25, 26,
-        2, 27, 28, 29, 30, 31, 32, 33,
-        30, 34, 2, 35, 2, 36, 2, 38,
-        39, 37, 40, 37, 37, 37, 37, 37,
-        37, 37, 41, 42, 43, 44, 45, 46,
-        47, 48, 49, 50, 51, 52, 53, 54,
-        37, 55, 56, 57, 37, 58, 59, 37,
-        60, 61, 62, 63, 60, 37, 37, 37,
-        37, 64, 37, 38, 39, 37, 40, 37,
-        37, 37, 37, 37, 37, 37, 41, 42,
-        43, 44, 45, 46, 47, 48, 49, 51,
-        51, 52, 53, 54, 37, 55, 56, 57,
-        37, 37, 37, 37, 60, 61, 62, 63,
-        60, 37, 37, 37, 37, 64, 37, 38,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 37, 37, 40, 37, 37, 37,
-        37, 37, 37, 37, 37, 42, 43, 44,
-        45, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 37, 55, 56, 57, 37, 37,
-        37, 37, 37, 61, 62, 63, 65, 37,
-        37, 37, 37, 42, 37, 40, 37, 37,
-        37, 37, 37, 37, 37, 37, 42, 43,
-        44, 45, 37, 37, 37, 37, 37, 37,
-        37, 37, 37, 37, 55, 56, 57, 37,
-        37, 37, 37, 37, 61, 62, 63, 65,
-        37, 40, 37, 37, 37, 37, 37, 37,
-        37, 37, 37, 43, 44, 45, 37, 37,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        61, 62, 63, 37, 40, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 37, 44,
-        45, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 37, 61, 62, 63, 37, 40,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 37, 45, 37, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 61, 62,
-        63, 37, 40, 37, 37, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        37, 61, 62, 37, 40, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 37, 37, 62, 37, 40, 37,
-        40, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 43, 44, 45, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 37, 55,
-        56, 57, 37, 37, 37, 37, 37, 61,
-        62, 63, 65, 37, 40, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 43, 44,
-        45, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 37, 37, 56, 57, 37, 37,
-        37, 37, 37, 61, 62, 63, 65, 37,
-        40, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 43, 44, 45, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        37, 57, 37, 37, 37, 37, 37, 61,
-        62, 63, 65, 37, 66, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        37, 40, 37, 40, 37, 37, 37, 37,
-        37, 37, 37, 37, 37, 43, 44, 45,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 61, 62, 63, 65, 37, 40,
-        37, 37, 37, 37, 37, 37, 37, 41,
-        42, 43, 44, 45, 37, 37, 37, 37,
-        37, 37, 52, 53, 54, 37, 55, 56,
-        57, 37, 37, 37, 37, 37, 61, 62,
-        63, 65, 37, 37, 37, 37, 42, 37,
-        40, 37, 37, 37, 37, 37, 37, 37,
-        37, 42, 43, 44, 45, 37, 37, 37,
-        37, 37, 37, 52, 53, 54, 37, 55,
-        56, 57, 37, 37, 37, 37, 37, 61,
-        62, 63, 65, 37, 37, 37, 37, 42,
-        37, 40, 37, 37, 37, 37, 37, 37,
-        37, 37, 42, 43, 44, 45, 37, 37,
-        37, 37, 37, 37, 37, 53, 54, 37,
-        55, 56, 57, 37, 37, 37, 37, 37,
-        61, 62, 63, 65, 37, 37, 37, 37,
-        42, 37, 40, 37, 37, 37, 37, 37,
-        37, 37, 37, 42, 43, 44, 45, 37,
-        37, 37, 37, 37, 37, 37, 37, 54,
-        37, 55, 56, 57, 37, 37, 37, 37,
-        37, 61, 62, 63, 65, 37, 37, 37,
-        37, 42, 37, 67, 37, 40, 37, 37,
-        37, 37, 37, 37, 37, 41, 42, 43,
-        44, 45, 37, 47, 48, 37, 37, 37,
-        52, 53, 54, 37, 55, 56, 57, 37,
-        37, 37, 37, 37, 61, 62, 63, 65,
-        37, 37, 37, 37, 42, 37, 40, 37,
-        37, 37, 37, 37, 37, 37, 37, 42,
-        43, 44, 45, 37, 37, 37, 37, 37,
-        37, 37, 37, 37, 37, 55, 56, 57,
-        37, 37, 37, 37, 37, 61, 62, 63,
-        65, 37, 37, 37, 37, 42, 37, 67,
-        37, 40, 37, 37, 37, 37, 37, 37,
-        37, 41, 42, 43, 44, 45, 37, 37,
-        48, 37, 37, 37, 52, 53, 54, 37,
-        55, 56, 57, 37, 37, 37, 37, 37,
-        61, 62, 63, 65, 37, 37, 37, 37,
-        42, 37, 67, 37, 40, 37, 37, 37,
-        37, 37, 37, 37, 41, 42, 43, 44,
-        45, 37, 37, 37, 37, 37, 37, 52,
-        53, 54, 37, 55, 56, 57, 37, 37,
-        37, 37, 37, 61, 62, 63, 65, 37,
-        37, 37, 37, 42, 37, 67, 37, 40,
-        37, 37, 37, 37, 37, 37, 37, 41,
-        42, 43, 44, 45, 46, 47, 48, 37,
-        37, 37, 52, 53, 54, 37, 55, 56,
-        57, 37, 37, 37, 37, 37, 61, 62,
-        63, 65, 37, 37, 37, 37, 42, 37,
-        38, 39, 37, 40, 37, 37, 37, 37,
-        37, 37, 37, 41, 42, 43, 44, 45,
-        46, 47, 48, 49, 37, 51, 52, 53,
-        54, 37, 55, 56, 57, 37, 37, 37,
-        37, 60, 61, 62, 63, 60, 37, 37,
-        37, 37, 64, 37, 38, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        37, 40, 37, 38, 37, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        40, 37, 37, 37, 37, 37, 37, 37,
-        37, 42, 43, 44, 45, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 37, 55,
-        56, 57, 37, 37, 37, 37, 37, 61,
-        62, 63, 65, 37, 38, 39, 37, 40,
-        37, 37, 37, 37, 37, 37, 37, 41,
-        42, 43, 44, 45, 46, 47, 48, 49,
-        50, 51, 52, 53, 54, 37, 55, 56,
-        57, 37, 37, 37, 37, 60, 61, 62,
-        63, 60, 37, 37, 37, 37, 64, 37,
-        40, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 37, 58, 59, 37, 40, 37,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 37, 37, 37, 37, 37, 37,
-        37, 37, 59, 37, 69, 70, 68, 71,
-        68, 68, 68, 68, 68, 68, 68, 72,
-        73, 74, 75, 76, 77, 78, 79, 80,
-        1, 81, 82, 83, 84, 68, 85, 86,
-        87, 68, 68, 68, 68, 88, 89, 90,
-        91, 92, 68, 68, 68, 68, 93, 68,
-        69, 70, 68, 71, 68, 68, 68, 68,
-        68, 68, 68, 72, 73, 74, 75, 76,
-        77, 78, 79, 80, 81, 81, 82, 83,
-        84, 68, 85, 86, 87, 68, 68, 68,
-        68, 88, 89, 90, 91, 92, 68, 68,
-        68, 68, 93, 68, 69, 68, 68, 68,
-        68, 68, 68, 68, 68, 68, 68, 68,
-        68, 71, 68, 68, 68, 68, 68, 68,
-        68, 68, 73, 74, 75, 76, 68, 68,
-        68, 68, 68, 68, 68, 68, 68, 68,
-        85, 86, 87, 68, 68, 68, 68, 68,
-        89, 90, 91, 94, 68, 68, 68, 68,
-        73, 68, 71, 68, 68, 68, 68, 68,
-        68, 68, 68, 73, 74, 75, 76, 68,
-        68, 68, 68, 68, 68, 68, 68, 68,
-        68, 85, 86, 87, 68, 68, 68, 68,
-        68, 89, 90, 91, 94, 68, 71, 68,
-        68, 68, 68, 68, 68, 68, 68, 68,
-        74, 75, 76, 68, 68, 68, 68, 68,
-        68, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 68, 68, 89, 90, 91,
-        68, 71, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 68, 75, 76, 68, 68,
-        68, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 68, 68, 68, 68, 68,
-        89, 90, 91, 68, 71, 68, 68, 68,
-        68, 68, 68, 68, 68, 68, 68, 68,
-        76, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 89, 90, 91, 68, 71,
-        68, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 68, 68, 68, 89, 90,
-        68, 71, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 68, 68, 68, 68, 68,
-        68, 90, 68, 71, 68, 71, 68, 68,
-        68, 68, 68, 68, 68, 68, 68, 74,
-        75, 76, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 68, 85, 86, 87, 68,
-        68, 68, 68, 68, 89, 90, 91, 94,
-        68, 71, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 74, 75, 76, 68, 68,
-        68, 68, 68, 68, 68, 68, 68, 68,
-        68, 86, 87, 68, 68, 68, 68, 68,
-        89, 90, 91, 94, 68, 71, 68, 68,
-        68, 68, 68, 68, 68, 68, 68, 74,
-        75, 76, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 68, 68, 68, 87, 68,
-        68, 68, 68, 68, 89, 90, 91, 94,
-        68, 96, 95, 95, 95, 95, 95, 95,
-        95, 95, 95, 95, 95, 95, 97, 95,
-        71, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 74, 75, 76, 68, 68, 68,
-        68, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 68, 68, 68, 68, 89,
-        90, 91, 94, 68, 71, 68, 68, 68,
-        68, 68, 68, 68, 72, 73, 74, 75,
-        76, 68, 68, 68, 68, 68, 68, 82,
-        83, 84, 68, 85, 86, 87, 68, 68,
-        68, 68, 68, 89, 90, 91, 94, 68,
-        68, 68, 68, 73, 68, 71, 68, 68,
-        68, 68, 68, 68, 68, 68, 73, 74,
-        75, 76, 68, 68, 68, 68, 68, 68,
-        82, 83, 84, 68, 85, 86, 87, 68,
-        68, 68, 68, 68, 89, 90, 91, 94,
-        68, 68, 68, 68, 73, 68, 71, 68,
-        68, 68, 68, 68, 68, 68, 68, 73,
-        74, 75, 76, 68, 68, 68, 68, 68,
-        68, 68, 83, 84, 68, 85, 86, 87,
-        68, 68, 68, 68, 68, 89, 90, 91,
-        94, 68, 68, 68, 68, 73, 68, 71,
-        68, 68, 68, 68, 68, 68, 68, 68,
-        73, 74, 75, 76, 68, 68, 68, 68,
-        68, 68, 68, 68, 84, 68, 85, 86,
-        87, 68, 68, 68, 68, 68, 89, 90,
-        91, 94, 68, 68, 68, 68, 73, 68,
-        98, 68, 71, 68, 68, 68, 68, 68,
-        68, 68, 72, 73, 74, 75, 76, 68,
-        78, 79, 68, 68, 68, 82, 83, 84,
-        68, 85, 86, 87, 68, 68, 68, 68,
-        68, 89, 90, 91, 94, 68, 68, 68,
-        68, 73, 68, 71, 68, 68, 68, 68,
-        68, 68, 68, 68, 73, 74, 75, 76,
-        68, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 85, 86, 87, 68, 68, 68,
-        68, 68, 89, 90, 91, 94, 68, 68,
-        68, 68, 73, 68, 98, 68, 71, 68,
-        68, 68, 68, 68, 68, 68, 72, 73,
-        74, 75, 76, 68, 68, 79, 68, 68,
-        68, 82, 83, 84, 68, 85, 86, 87,
-        68, 68, 68, 68, 68, 89, 90, 91,
-        94, 68, 68, 68, 68, 73, 68, 98,
-        68, 71, 68, 68, 68, 68, 68, 68,
-        68, 72, 73, 74, 75, 76, 68, 68,
-        68, 68, 68, 68, 82, 83, 84, 68,
-        85, 86, 87, 68, 68, 68, 68, 68,
-        89, 90, 91, 94, 68, 68, 68, 68,
-        73, 68, 98, 68, 71, 68, 68, 68,
-        68, 68, 68, 68, 72, 73, 74, 75,
-        76, 77, 78, 79, 68, 68, 68, 82,
-        83, 84, 68, 85, 86, 87, 68, 68,
-        68, 68, 68, 89, 90, 91, 94, 68,
-        68, 68, 68, 73, 68, 69, 70, 68,
-        71, 68, 68, 68, 68, 68, 68, 68,
-        72, 73, 74, 75, 76, 77, 78, 79,
-        80, 68, 81, 82, 83, 84, 68, 85,
-        86, 87, 68, 68, 68, 68, 88, 89,
-        90, 91, 92, 68, 68, 68, 68, 93,
-        68, 69, 99, 99, 99, 99, 99, 99,
-        99, 99, 99, 99, 99, 99, 100, 99,
-        69, 95, 95, 95, 95, 95, 95, 95,
-        95, 95, 95, 95, 95, 97, 95, 69,
-        68, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 68, 71, 68, 68, 68,
-        68, 68, 68, 68, 68, 73, 74, 75,
-        76, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 85, 86, 87, 68, 68,
-        68, 68, 68, 89, 90, 91, 94, 68,
-        102, 103, 101, 3, 104, 104, 104, 104,
-        104, 104, 104, 104, 104, 105, 104, 106,
-        107, 68, 71, 68, 68, 68, 68, 68,
-        68, 68, 108, 109, 110, 111, 112, 113,
-        114, 115, 116, 117, 118, 119, 120, 121,
-        68, 122, 123, 124, 68, 58, 59, 68,
-        125, 126, 127, 128, 129, 68, 68, 68,
-        68, 130, 68, 106, 107, 68, 71, 68,
-        68, 68, 68, 68, 68, 68, 108, 109,
-        110, 111, 112, 113, 114, 115, 116, 118,
-        118, 119, 120, 121, 68, 122, 123, 124,
-        68, 68, 68, 68, 125, 126, 127, 128,
-        129, 68, 68, 68, 68, 130, 68, 106,
-        68, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 68, 71, 68, 68, 68,
-        68, 68, 68, 68, 68, 109, 110, 111,
-        112, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 122, 123, 124, 68, 68,
-        68, 68, 68, 126, 127, 128, 131, 68,
-        68, 68, 68, 109, 68, 71, 68, 68,
-        68, 68, 68, 68, 68, 68, 109, 110,
-        111, 112, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 68, 122, 123, 124, 68,
-        68, 68, 68, 68, 126, 127, 128, 131,
-        68, 71, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 110, 111, 112, 68, 68,
-        68, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 68, 68, 68, 68, 68,
-        126, 127, 128, 68, 71, 68, 68, 68,
-        68, 68, 68, 68, 68, 68, 68, 111,
-        112, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 126, 127, 128, 68, 71,
-        68, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 112, 68, 68, 68, 68,
-        68, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 68, 68, 68, 126, 127,
-        128, 68, 71, 68, 68, 68, 68, 68,
-        68, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 68, 68, 68, 68, 68,
-        68, 126, 127, 68, 71, 68, 68, 68,
-        68, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 68, 127, 68, 71, 68,
-        71, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 110, 111, 112, 68, 68, 68,
-        68, 68, 68, 68, 68, 68, 68, 122,
-        123, 124, 68, 68, 68, 68, 68, 126,
-        127, 128, 131, 68, 71, 68, 68, 68,
-        68, 68, 68, 68, 68, 68, 110, 111,
-        112, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 68, 123, 124, 68, 68,
-        68, 68, 68, 126, 127, 128, 131, 68,
-        71, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 110, 111, 112, 68, 68, 68,
-        68, 68, 68, 68, 68, 68, 68, 68,
-        68, 124, 68, 68, 68, 68, 68, 126,
-        127, 128, 131, 68, 132, 95, 95, 95,
-        95, 95, 95, 95, 95, 95, 95, 95,
-        95, 97, 95, 71, 68, 68, 68, 68,
-        68, 68, 68, 68, 68, 110, 111, 112,
-        68, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 68, 68, 68, 68, 68, 68,
-        68, 68, 126, 127, 128, 131, 68, 71,
-        68, 68, 68, 68, 68, 68, 68, 108,
-        109, 110, 111, 112, 68, 68, 68, 68,
-        68, 68, 119, 120, 121, 68, 122, 123,
-        124, 68, 68, 68, 68, 68, 126, 127,
-        128, 131, 68, 68, 68, 68, 109, 68,
-        71, 68, 68, 68, 68, 68, 68, 68,
-        68, 109, 110, 111, 112, 68, 68, 68,
-        68, 68, 68, 119, 120, 121, 68, 122,
-        123, 124, 68, 68, 68, 68, 68, 126,
-        127, 128, 131, 68, 68, 68, 68, 109,
-        68, 71, 68, 68, 68, 68, 68, 68,
-        68, 68, 109, 110, 111, 112, 68, 68,
-        68, 68, 68, 68, 68, 120, 121, 68,
-        122, 123, 124, 68, 68, 68, 68, 68,
-        126, 127, 128, 131, 68, 68, 68, 68,
-        109, 68, 71, 68, 68, 68, 68, 68,
-        68, 68, 68, 109, 110, 111, 112, 68,
-        68, 68, 68, 68, 68, 68, 68, 121,
-        68, 122, 123, 124, 68, 68, 68, 68,
-        68, 126, 127, 128, 131, 68, 68, 68,
-        68, 109, 68, 133, 68, 71, 68, 68,
-        68, 68, 68, 68, 68, 108, 109, 110,
-        111, 112, 68, 114, 115, 68, 68, 68,
-        119, 120, 121, 68, 122, 123, 124, 68,
-        68, 68, 68, 68, 126, 127, 128, 131,
-        68, 68, 68, 68, 109, 68, 71, 68,
-        68, 68, 68, 68, 68, 68, 68, 109,
-        110, 111, 112, 68, 68, 68, 68, 68,
-        68, 68, 68, 68, 68, 122, 123, 124,
-        68, 68, 68, 68, 68, 126, 127, 128,
-        131, 68, 68, 68, 68, 109, 68, 133,
-        68, 71, 68, 68, 68, 68, 68, 68,
-        68, 108, 109, 110, 111, 112, 68, 68,
-        115, 68, 68, 68, 119, 120, 121, 68,
-        122, 123, 124, 68, 68, 68, 68, 68,
-        126, 127, 128, 131, 68, 68, 68, 68,
-        109, 68, 133, 68, 71, 68, 68, 68,
-        68, 68, 68, 68, 108, 109, 110, 111,
-        112, 68, 68, 68, 68, 68, 68, 119,
-        120, 121, 68, 122, 123, 124, 68, 68,
-        68, 68, 68, 126, 127, 128, 131, 68,
-        68, 68, 68, 109, 68, 133, 68, 71,
-        68, 68, 68, 68, 68, 68, 68, 108,
-        109, 110, 111, 112, 113, 114, 115, 68,
-        68, 68, 119, 120, 121, 68, 122, 123,
-        124, 68, 68, 68, 68, 68, 126, 127,
-        128, 131, 68, 68, 68, 68, 109, 68,
-        106, 107, 68, 71, 68, 68, 68, 68,
-        68, 68, 68, 108, 109, 110, 111, 112,
-        113, 114, 115, 116, 68, 118, 119, 120,
-        121, 68, 122, 123, 124, 68, 68, 68,
-        68, 125, 126, 127, 128, 129, 68, 68,
-        68, 68, 130, 68, 106, 99, 99, 99,
-        99, 99, 99, 99, 99, 99, 99, 99,
-        99, 100, 99, 106, 95, 95, 95, 95,
-        95, 95, 95, 95, 95, 95, 95, 95,
-        97, 95, 106, 68, 68, 68, 68, 68,
+        1, 0, 2, 0, 3, 4, 5, 5,
+        6, 7, 5, 5, 5, 5, 5, 8,
+        9, 10, 11, 5, 5, 5, 12, 5,
+        5, 5, 13, 14, 15, 16, 17, 18,
+        19, 20, 21, 8, 22, 23, 24, 25,
+        5, 26, 27, 28, 5, 29, 30, 31,
+        32, 33, 34, 35, 32, 1, 5, 36,
+        5, 37, 5, 39, 40, 38, 41, 38,
+        38, 38, 38, 38, 38, 38, 42, 43,
+        44, 45, 46, 47, 48, 49, 50, 39,
+        51, 52, 53, 54, 38, 55, 56, 57,
+        38, 58, 59, 38, 60, 61, 62, 63,
+        60, 38, 38, 38, 38, 64, 38, 39,
+        40, 38, 41, 38, 38, 38, 38, 38,
+        38, 38, 42, 43, 44, 45, 46, 47,
+        48, 49, 50, 39, 51, 52, 53, 54,
+        38, 55, 56, 57, 38, 38, 38, 38,
+        60, 61, 62, 63, 60, 38, 38, 38,
+        38, 64, 38, 39, 38, 38, 38, 38,
+        38, 38, 38, 38, 38, 38, 38, 38,
+        41, 38, 38, 38, 38, 38, 38, 38,
+        38, 43, 44, 45, 46, 38, 38, 38,
+        38, 38, 38, 38, 38, 38, 38, 55,
+        56, 57, 38, 38, 38, 38, 38, 61,
+        62, 63, 65, 38, 38, 38, 38, 43,
+        38, 41, 38, 38, 38, 38, 38, 38,
+        38, 38, 43, 44, 45, 46, 38, 38,
+        38, 38, 38, 38, 38, 38, 38, 38,
+        55, 56, 57, 38, 38, 38, 38, 38,
+        61, 62, 63, 65, 38, 41, 38, 38,
+        38, 38, 38, 38, 38, 38, 38, 44,
+        45, 46, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 38, 61, 62, 63, 38,
+        41, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 45, 46, 38, 38, 38,
+        38, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 38, 38, 38, 38, 61,
+        62, 63, 38, 41, 38, 38, 38, 38,
+        38, 38, 38, 38, 38, 38, 38, 46,
+        38, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 61, 62, 63, 38, 41, 38,
+        38, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 38, 38, 61, 62, 38,
+        41, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 38, 38, 38, 38, 38,
+        62, 38, 41, 38, 41, 38, 38, 38,
+        38, 38, 38, 38, 38, 38, 44, 45,
+        46, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 55, 56, 57, 38, 38,
+        38, 38, 38, 61, 62, 63, 65, 38,
+        41, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 44, 45, 46, 38, 38, 38,
+        38, 38, 38, 38, 38, 38, 38, 38,
+        56, 57, 38, 38, 38, 38, 38, 61,
+        62, 63, 65, 38, 41, 38, 38, 38,
+        38, 38, 38, 38, 38, 38, 44, 45,
+        46, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 38, 38, 57, 38, 38,
+        38, 38, 38, 61, 62, 63, 65, 38,
+        66, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 38, 38, 41, 38, 41,
+        38, 38, 38, 38, 38, 38, 38, 38,
+        38, 44, 45, 46, 38, 38, 38, 38,
+        38, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 38, 38, 38, 61, 62,
+        63, 65, 38, 41, 38, 38, 38, 38,
+        38, 38, 38, 42, 43, 44, 45, 46,
+        38, 38, 38, 38, 38, 38, 52, 53,
+        54, 38, 55, 56, 57, 38, 38, 38,
+        38, 38, 61, 62, 63, 65, 38, 38,
+        38, 38, 43, 38, 41, 38, 38, 38,
+        38, 38, 38, 38, 38, 43, 44, 45,
+        46, 38, 38, 38, 38, 38, 38, 52,
+        53, 54, 38, 55, 56, 57, 38, 38,
+        38, 38, 38, 61, 62, 63, 65, 38,
+        38, 38, 38, 43, 38, 41, 38, 38,
+        38, 38, 38, 38, 38, 38, 43, 44,
+        45, 46, 38, 38, 38, 38, 38, 38,
+        38, 53, 54, 38, 55, 56, 57, 38,
+        38, 38, 38, 38, 61, 62, 63, 65,
+        38, 38, 38, 38, 43, 38, 41, 38,
+        38, 38, 38, 38, 38, 38, 38, 43,
+        44, 45, 46, 38, 38, 38, 38, 38,
+        38, 38, 38, 54, 38, 55, 56, 57,
+        38, 38, 38, 38, 38, 61, 62, 63,
+        65, 38, 38, 38, 38, 43, 38, 67,
+        38, 41, 38, 38, 38, 38, 38, 38,
+        38, 42, 43, 44, 45, 46, 38, 48,
+        49, 38, 38, 38, 52, 53, 54, 38,
+        55, 56, 57, 38, 38, 38, 38, 38,
+        61, 62, 63, 65, 38, 38, 38, 38,
+        43, 38, 41, 38, 38, 38, 38, 38,
+        38, 38, 38, 43, 44, 45, 46, 38,
+        38, 38, 38, 38, 38, 38, 38, 38,
+        38, 55, 56, 57, 38, 38, 38, 38,
+        38, 61, 62, 63, 65, 38, 38, 38,
+        38, 43, 38, 67, 38, 41, 38, 38,
+        38, 38, 38, 38, 38, 42, 43, 44,
+        45, 46, 38, 38, 49, 38, 38, 38,
+        52, 53, 54, 38, 55, 56, 57, 38,
+        38, 38, 38, 38, 61, 62, 63, 65,
+        38, 38, 38, 38, 43, 38, 67, 38,
+        41, 38, 38, 38, 38, 38, 38, 38,
+        42, 43, 44, 45, 46, 38, 38, 38,
+        38, 38, 38, 52, 53, 54, 38, 55,
+        56, 57, 38, 38, 38, 38, 38, 61,
+        62, 63, 65, 38, 38, 38, 38, 43,
+        38, 67, 38, 41, 38, 38, 38, 38,
+        38, 38, 38, 42, 43, 44, 45, 46,
+        47, 48, 49, 38, 38, 38, 52, 53,
+        54, 38, 55, 56, 57, 38, 38, 38,
+        38, 38, 61, 62, 63, 65, 38, 38,
+        38, 38, 43, 38, 39, 40, 38, 41,
+        38, 38, 38, 38, 38, 38, 38, 42,
+        43, 44, 45, 46, 47, 48, 49, 50,
+        38, 51, 52, 53, 54, 38, 55, 56,
+        57, 38, 38, 38, 38, 60, 61, 62,
+        63, 60, 38, 38, 38, 38, 64, 38,
+        39, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 38, 38, 41, 38, 39,
+        38, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 38, 41, 38, 38, 38,
+        38, 38, 38, 38, 38, 43, 44, 45,
+        46, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 55, 56, 57, 38, 38,
+        38, 38, 38, 61, 62, 63, 65, 38,
+        41, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 58, 59, 38, 41, 38,
+        38, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 38, 38, 38, 38, 38, 38,
+        38, 38, 59, 38, 4, 69, 68, 70,
         68, 68, 68, 68, 68, 68, 68, 71,
+        72, 73, 74, 75, 76, 77, 78, 79,
+        4, 80, 81, 82, 83, 68, 84, 85,
+        86, 68, 68, 68, 68, 87, 88, 89,
+        90, 91, 68, 68, 68, 68, 92, 68,
+        4, 68, 68, 68, 68, 68, 68, 68,
+        68, 68, 68, 68, 68, 70, 68, 68,
+        68, 68, 68, 68, 68, 68, 72, 73,
+        74, 75, 68, 68, 68, 68, 68, 68,
+        68, 68, 68, 68, 84, 85, 86, 68,
+        68, 68, 68, 68, 88, 89, 90, 93,
+        68, 68, 68, 68, 72, 68, 70, 68,
+        68, 68, 68, 68, 68, 68, 68, 72,
+        73, 74, 75, 68, 68, 68, 68, 68,
+        68, 68, 68, 68, 68, 84, 85, 86,
+        68, 68, 68, 68, 68, 88, 89, 90,
+        93, 68, 70, 68, 68, 68, 68, 68,
+        68, 68, 68, 68, 73, 74, 75, 68,
         68, 68, 68, 68, 68, 68, 68, 68,
-        109, 110, 111, 112, 68, 68, 68, 68,
-        68, 68, 68, 68, 68, 68, 122, 123,
-        124, 68, 68, 68, 68, 68, 126, 127,
-        128, 131, 68, 106, 107, 68, 71, 68,
+        68, 68, 68, 68, 68, 68, 68, 68,
+        68, 88, 89, 90, 68, 70, 68, 68,
+        68, 68, 68, 68, 68, 68, 68, 68,
+        74, 75, 68, 68, 68, 68, 68, 68,
+        68, 68, 68, 68, 68, 68, 68, 68,
+        68, 68, 68, 68, 88, 89, 90, 68,
+        70, 68, 68, 68, 68, 68, 68, 68,
+        68, 68, 68, 68, 75, 68, 68, 68,
+        68, 68, 68, 68, 68, 68, 68, 68,
+        68, 68, 68, 68, 68, 68, 68, 88,
+        89, 90, 68, 70, 68, 68, 68, 68,
+        68, 68, 68, 68, 68, 68, 68, 68,
+        68, 68, 68, 68, 68, 68, 68, 68,
+        68, 68, 68, 68, 68, 68, 68, 68,
+        68, 68, 88, 89, 68, 70, 68, 68,
+        68, 68, 68, 68, 68, 68, 68, 68,
+        68, 68, 68, 68, 68, 68, 68, 68,
+        68, 68, 68, 68, 68, 68, 68, 68,
+        68, 68, 68, 68, 68, 89, 68, 70,
+        68, 70, 68, 68, 68, 68, 68, 68,
+        68, 68, 68, 73, 74, 75, 68, 68,
+        68, 68, 68, 68, 68, 68, 68, 68,
+        84, 85, 86, 68, 68, 68, 68, 68,
+        88, 89, 90, 93, 68, 70, 68, 68,
+        68, 68, 68, 68, 68, 68, 68, 73,
+        74, 75, 68, 68, 68, 68, 68, 68,
+        68, 68, 68, 68, 68, 85, 86, 68,
+        68, 68, 68, 68, 88, 89, 90, 93,
+        68, 70, 68, 68, 68, 68, 68, 68,
+        68, 68, 68, 73, 74, 75, 68, 68,
+        68, 68, 68, 68, 68, 68, 68, 68,
+        68, 68, 86, 68, 68, 68, 68, 68,
+        88, 89, 90, 93, 68, 95, 94, 94,
+        94, 94, 94, 94, 94, 94, 94, 94,
+        94, 94, 96, 94, 70, 68, 68, 68,
+        68, 68, 68, 68, 68, 68, 73, 74,
+        75, 68, 68, 68, 68, 68, 68, 68,
+        68, 68, 68, 68, 68, 68, 68, 68,
+        68, 68, 68, 88, 89, 90, 93, 68,
+        70, 68, 68, 68, 68, 68, 68, 68,
+        71, 72, 73, 74, 75, 68, 68, 68,
+        68, 68, 68, 81, 82, 83, 68, 84,
+        85, 86, 68, 68, 68, 68, 68, 88,
+        89, 90, 93, 68, 68, 68, 68, 72,
+        68, 70, 68, 68, 68, 68, 68, 68,
+        68, 68, 72, 73, 74, 75, 68, 68,
+        68, 68, 68, 68, 81, 82, 83, 68,
+        84, 85, 86, 68, 68, 68, 68, 68,
+        88, 89, 90, 93, 68, 68, 68, 68,
+        72, 68, 70, 68, 68, 68, 68, 68,
+        68, 68, 68, 72, 73, 74, 75, 68,
+        68, 68, 68, 68, 68, 68, 82, 83,
+        68, 84, 85, 86, 68, 68, 68, 68,
+        68, 88, 89, 90, 93, 68, 68, 68,
+        68, 72, 68, 70, 68, 68, 68, 68,
+        68, 68, 68, 68, 72, 73, 74, 75,
+        68, 68, 68, 68, 68, 68, 68, 68,
+        83, 68, 84, 85, 86, 68, 68, 68,
+        68, 68, 88, 89, 90, 93, 68, 68,
+        68, 68, 72, 68, 97, 68, 70, 68,
+        68, 68, 68, 68, 68, 68, 71, 72,
+        73, 74, 75, 68, 77, 78, 68, 68,
+        68, 81, 82, 83, 68, 84, 85, 86,
+        68, 68, 68, 68, 68, 88, 89, 90,
+        93, 68, 68, 68, 68, 72, 68, 70,
+        68, 68, 68, 68, 68, 68, 68, 68,
+        72, 73, 74, 75, 68, 68, 68, 68,
+        68, 68, 68, 68, 68, 68, 84, 85,
+        86, 68, 68, 68, 68, 68, 88, 89,
+        90, 93, 68, 68, 68, 68, 72, 68,
+        97, 68, 70, 68, 68, 68, 68, 68,
+        68, 68, 71, 72, 73, 74, 75, 68,
+        68, 78, 68, 68, 68, 81, 82, 83,
+        68, 84, 85, 86, 68, 68, 68, 68,
+        68, 88, 89, 90, 93, 68, 68, 68,
+        68, 72, 68, 97, 68, 70, 68, 68,
+        68, 68, 68, 68, 68, 71, 72, 73,
+        74, 75, 68, 68, 68, 68, 68, 68,
+        81, 82, 83, 68, 84, 85, 86, 68,
+        68, 68, 68, 68, 88, 89, 90, 93,
+        68, 68, 68, 68, 72, 68, 97, 68,
+        70, 68, 68, 68, 68, 68, 68, 68,
+        71, 72, 73, 74, 75, 76, 77, 78,
+        68, 68, 68, 81, 82, 83, 68, 84,
+        85, 86, 68, 68, 68, 68, 68, 88,
+        89, 90, 93, 68, 68, 68, 68, 72,
+        68, 4, 69, 68, 70, 68, 68, 68,
+        68, 68, 68, 68, 71, 72, 73, 74,
+        75, 76, 77, 78, 79, 68, 80, 81,
+        82, 83, 68, 84, 85, 86, 68, 68,
+        68, 68, 87, 88, 89, 90, 91, 68,
+        68, 68, 68, 92, 68, 4, 98, 98,
+        98, 98, 98, 98, 98, 98, 98, 98,
+        98, 98, 99, 98, 4, 94, 94, 94,
+        94, 94, 94, 94, 94, 94, 94, 94,
+        94, 96, 94, 4, 68, 68, 68, 68,
+        68, 68, 68, 68, 68, 68, 68, 68,
+        70, 68, 68, 68, 68, 68, 68, 68,
+        68, 72, 73, 74, 75, 68, 68, 68,
+        68, 68, 68, 68, 68, 68, 68, 84,
+        85, 86, 68, 68, 68, 68, 68, 88,
+        89, 90, 93, 68, 101, 102, 100, 6,
+        103, 103, 103, 103, 103, 103, 103, 103,
+        103, 104, 103, 105, 106, 68, 70, 68,
+        68, 68, 68, 68, 68, 68, 107, 108,
+        109, 110, 111, 112, 113, 114, 115, 105,
+        116, 117, 118, 119, 68, 120, 121, 122,
+        68, 58, 59, 68, 123, 124, 125, 126,
+        127, 68, 68, 68, 68, 128, 68, 105,
+        106, 68, 70, 68, 68, 68, 68, 68,
+        68, 68, 107, 108, 109, 110, 111, 112,
+        113, 114, 115, 105, 116, 117, 118, 119,
+        68, 120, 121, 122, 68, 68, 68, 68,
+        123, 124, 125, 126, 127, 68, 68, 68,
+        68, 128, 68, 105, 68, 68, 68, 68,
+        68, 68, 68, 68, 68, 68, 68, 68,
+        70, 68, 68, 68, 68, 68, 68, 68,
+        68, 108, 109, 110, 111, 68, 68, 68,
+        68, 68, 68, 68, 68, 68, 68, 120,
+        121, 122, 68, 68, 68, 68, 68, 124,
+        125, 126, 129, 68, 68, 68, 68, 108,
+        68, 70, 68, 68, 68, 68, 68, 68,
+        68, 68, 108, 109, 110, 111, 68, 68,
+        68, 68, 68, 68, 68, 68, 68, 68,
+        120, 121, 122, 68, 68, 68, 68, 68,
+        124, 125, 126, 129, 68, 70, 68, 68,
+        68, 68, 68, 68, 68, 68, 68, 109,
+        110, 111, 68, 68, 68, 68, 68, 68,
+        68, 68, 68, 68, 68, 68, 68, 68,
+        68, 68, 68, 68, 124, 125, 126, 68,
+        70, 68, 68, 68, 68, 68, 68, 68,
+        68, 68, 68, 110, 111, 68, 68, 68,
+        68, 68, 68, 68, 68, 68, 68, 68,
+        68, 68, 68, 68, 68, 68, 68, 124,
+        125, 126, 68, 70, 68, 68, 68, 68,
+        68, 68, 68, 68, 68, 68, 68, 111,
+        68, 68, 68, 68, 68, 68, 68, 68,
+        68, 68, 68, 68, 68, 68, 68, 68,
+        68, 68, 124, 125, 126, 68, 70, 68,
+        68, 68, 68, 68, 68, 68, 68, 68,
+        68, 68, 68, 68, 68, 68, 68, 68,
+        68, 68, 68, 68, 68, 68, 68, 68,
+        68, 68, 68, 68, 68, 124, 125, 68,
+        70, 68, 68, 68, 68, 68, 68, 68,
+        68, 68, 68, 68, 68, 68, 68, 68,
+        68, 68, 68, 68, 68, 68, 68, 68,
+        68, 68, 68, 68, 68, 68, 68, 68,
+        125, 68, 70, 68, 70, 68, 68, 68,
+        68, 68, 68, 68, 68, 68, 109, 110,
+        111, 68, 68, 68, 68, 68, 68, 68,
+        68, 68, 68, 120, 121, 122, 68, 68,
+        68, 68, 68, 124, 125, 126, 129, 68,
+        70, 68, 68, 68, 68, 68, 68, 68,
+        68, 68, 109, 110, 111, 68, 68, 68,
+        68, 68, 68, 68, 68, 68, 68, 68,
+        121, 122, 68, 68, 68, 68, 68, 124,
+        125, 126, 129, 68, 70, 68, 68, 68,
+        68, 68, 68, 68, 68, 68, 109, 110,
+        111, 68, 68, 68, 68, 68, 68, 68,
+        68, 68, 68, 68, 68, 122, 68, 68,
+        68, 68, 68, 124, 125, 126, 129, 68,
+        130, 94, 94, 94, 94, 94, 94, 94,
+        94, 94, 94, 94, 94, 96, 94, 70,
+        68, 68, 68, 68, 68, 68, 68, 68,
+        68, 109, 110, 111, 68, 68, 68, 68,
+        68, 68, 68, 68, 68, 68, 68, 68,
+        68, 68, 68, 68, 68, 68, 124, 125,
+        126, 129, 68, 70, 68, 68, 68, 68,
+        68, 68, 68, 107, 108, 109, 110, 111,
+        68, 68, 68, 68, 68, 68, 117, 118,
+        119, 68, 120, 121, 122, 68, 68, 68,
+        68, 68, 124, 125, 126, 129, 68, 68,
+        68, 68, 108, 68, 70, 68, 68, 68,
+        68, 68, 68, 68, 68, 108, 109, 110,
+        111, 68, 68, 68, 68, 68, 68, 117,
+        118, 119, 68, 120, 121, 122, 68, 68,
+        68, 68, 68, 124, 125, 126, 129, 68,
+        68, 68, 68, 108, 68, 70, 68, 68,
         68, 68, 68, 68, 68, 68, 108, 109,
-        110, 111, 112, 113, 114, 115, 116, 117,
-        118, 119, 120, 121, 68, 122, 123, 124,
-        68, 68, 68, 68, 125, 126, 127, 128,
-        129, 68, 68, 68, 68, 130, 68, 5,
-        6, 134, 8, 134, 134, 134, 134, 134,
-        134, 134, 10, 11, 12, 13, 14, 15,
-        16, 17, 18, 20, 20, 21, 22, 23,
-        134, 24, 25, 26, 134, 134, 134, 134,
-        30, 31, 32, 33, 30, 134, 134, 134,
-        134, 36, 134, 5, 134, 134, 134, 134,
-        134, 134, 134, 134, 134, 134, 134, 134,
-        8, 134, 134, 134, 134, 134, 134, 134,
-        134, 11, 12, 13, 14, 134, 134, 134,
-        134, 134, 134, 134, 134, 134, 134, 24,
-        25, 26, 134, 134, 134, 134, 134, 31,
-        32, 33, 135, 134, 134, 134, 134, 11,
-        134, 8, 134, 134, 134, 134, 134, 134,
-        134, 134, 11, 12, 13, 14, 134, 134,
-        134, 134, 134, 134, 134, 134, 134, 134,
-        24, 25, 26, 134, 134, 134, 134, 134,
-        31, 32, 33, 135, 134, 8, 134, 134,
-        134, 134, 134, 134, 134, 134, 134, 12,
-        13, 14, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 134, 31, 32, 33, 134,
-        8, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 13, 14, 134, 134, 134,
-        134, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 134, 134, 134, 134, 31,
-        32, 33, 134, 8, 134, 134, 134, 134,
-        134, 134, 134, 134, 134, 134, 134, 14,
-        134, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 31, 32, 33, 134, 8, 134,
-        134, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 134, 134, 31, 32, 134,
-        8, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 134, 134, 134, 134, 134,
-        32, 134, 8, 134, 8, 134, 134, 134,
-        134, 134, 134, 134, 134, 134, 12, 13,
-        14, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 24, 25, 26, 134, 134,
-        134, 134, 134, 31, 32, 33, 135, 134,
-        8, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 12, 13, 14, 134, 134, 134,
-        134, 134, 134, 134, 134, 134, 134, 134,
-        25, 26, 134, 134, 134, 134, 134, 31,
-        32, 33, 135, 134, 8, 134, 134, 134,
-        134, 134, 134, 134, 134, 134, 12, 13,
-        14, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 134, 134, 26, 134, 134,
-        134, 134, 134, 31, 32, 33, 135, 134,
-        136, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 134, 134, 8, 134, 8,
-        134, 134, 134, 134, 134, 134, 134, 134,
-        134, 12, 13, 14, 134, 134, 134, 134,
-        134, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 134, 134, 134, 31, 32,
-        33, 135, 134, 8, 134, 134, 134, 134,
-        134, 134, 134, 10, 11, 12, 13, 14,
-        134, 134, 134, 134, 134, 134, 21, 22,
-        23, 134, 24, 25, 26, 134, 134, 134,
-        134, 134, 31, 32, 33, 135, 134, 134,
-        134, 134, 11, 134, 8, 134, 134, 134,
-        134, 134, 134, 134, 134, 11, 12, 13,
-        14, 134, 134, 134, 134, 134, 134, 21,
-        22, 23, 134, 24, 25, 26, 134, 134,
-        134, 134, 134, 31, 32, 33, 135, 134,
-        134, 134, 134, 11, 134, 8, 134, 134,
-        134, 134, 134, 134, 134, 134, 11, 12,
-        13, 14, 134, 134, 134, 134, 134, 134,
-        134, 22, 23, 134, 24, 25, 26, 134,
-        134, 134, 134, 134, 31, 32, 33, 135,
-        134, 134, 134, 134, 11, 134, 8, 134,
-        134, 134, 134, 134, 134, 134, 134, 11,
-        12, 13, 14, 134, 134, 134, 134, 134,
-        134, 134, 134, 23, 134, 24, 25, 26,
-        134, 134, 134, 134, 134, 31, 32, 33,
-        135, 134, 134, 134, 134, 11, 134, 137,
-        134, 8, 134, 134, 134, 134, 134, 134,
-        134, 10, 11, 12, 13, 14, 134, 16,
-        17, 134, 134, 134, 21, 22, 23, 134,
-        24, 25, 26, 134, 134, 134, 134, 134,
-        31, 32, 33, 135, 134, 134, 134, 134,
-        11, 134, 8, 134, 134, 134, 134, 134,
-        134, 134, 134, 11, 12, 13, 14, 134,
-        134, 134, 134, 134, 134, 134, 134, 134,
-        134, 24, 25, 26, 134, 134, 134, 134,
-        134, 31, 32, 33, 135, 134, 134, 134,
-        134, 11, 134, 137, 134, 8, 134, 134,
-        134, 134, 134, 134, 134, 10, 11, 12,
-        13, 14, 134, 134, 17, 134, 134, 134,
-        21, 22, 23, 134, 24, 25, 26, 134,
-        134, 134, 134, 134, 31, 32, 33, 135,
-        134, 134, 134, 134, 11, 134, 137, 134,
-        8, 134, 134, 134, 134, 134, 134, 134,
-        10, 11, 12, 13, 14, 134, 134, 134,
-        134, 134, 134, 21, 22, 23, 134, 24,
-        25, 26, 134, 134, 134, 134, 134, 31,
-        32, 33, 135, 134, 134, 134, 134, 11,
-        134, 137, 134, 8, 134, 134, 134, 134,
-        134, 134, 134, 10, 11, 12, 13, 14,
-        15, 16, 17, 134, 134, 134, 21, 22,
-        23, 134, 24, 25, 26, 134, 134, 134,
-        134, 134, 31, 32, 33, 135, 134, 134,
-        134, 134, 11, 134, 5, 6, 134, 8,
-        134, 134, 134, 134, 134, 134, 134, 10,
-        11, 12, 13, 14, 15, 16, 17, 18,
-        134, 20, 21, 22, 23, 134, 24, 25,
-        26, 134, 134, 134, 134, 30, 31, 32,
-        33, 30, 134, 134, 134, 134, 36, 134,
-        5, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 134, 134, 8, 134, 5,
-        134, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 134, 8, 134, 134, 134,
-        134, 134, 134, 134, 134, 11, 12, 13,
-        14, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 24, 25, 26, 134, 134,
-        134, 134, 134, 31, 32, 33, 135, 134,
-        138, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 8, 134, 7, 8, 134, 1,
-        134, 134, 134, 1, 134, 134, 134, 134,
-        134, 5, 6, 7, 8, 134, 134, 134,
-        134, 134, 134, 134, 10, 11, 12, 13,
+        110, 111, 68, 68, 68, 68, 68, 68,
+        68, 118, 119, 68, 120, 121, 122, 68,
+        68, 68, 68, 68, 124, 125, 126, 129,
+        68, 68, 68, 68, 108, 68, 70, 68,
+        68, 68, 68, 68, 68, 68, 68, 108,
+        109, 110, 111, 68, 68, 68, 68, 68,
+        68, 68, 68, 119, 68, 120, 121, 122,
+        68, 68, 68, 68, 68, 124, 125, 126,
+        129, 68, 68, 68, 68, 108, 68, 131,
+        68, 70, 68, 68, 68, 68, 68, 68,
+        68, 107, 108, 109, 110, 111, 68, 113,
+        114, 68, 68, 68, 117, 118, 119, 68,
+        120, 121, 122, 68, 68, 68, 68, 68,
+        124, 125, 126, 129, 68, 68, 68, 68,
+        108, 68, 70, 68, 68, 68, 68, 68,
+        68, 68, 68, 108, 109, 110, 111, 68,
+        68, 68, 68, 68, 68, 68, 68, 68,
+        68, 120, 121, 122, 68, 68, 68, 68,
+        68, 124, 125, 126, 129, 68, 68, 68,
+        68, 108, 68, 131, 68, 70, 68, 68,
+        68, 68, 68, 68, 68, 107, 108, 109,
+        110, 111, 68, 68, 114, 68, 68, 68,
+        117, 118, 119, 68, 120, 121, 122, 68,
+        68, 68, 68, 68, 124, 125, 126, 129,
+        68, 68, 68, 68, 108, 68, 131, 68,
+        70, 68, 68, 68, 68, 68, 68, 68,
+        107, 108, 109, 110, 111, 68, 68, 68,
+        68, 68, 68, 117, 118, 119, 68, 120,
+        121, 122, 68, 68, 68, 68, 68, 124,
+        125, 126, 129, 68, 68, 68, 68, 108,
+        68, 131, 68, 70, 68, 68, 68, 68,
+        68, 68, 68, 107, 108, 109, 110, 111,
+        112, 113, 114, 68, 68, 68, 117, 118,
+        119, 68, 120, 121, 122, 68, 68, 68,
+        68, 68, 124, 125, 126, 129, 68, 68,
+        68, 68, 108, 68, 105, 106, 68, 70,
+        68, 68, 68, 68, 68, 68, 68, 107,
+        108, 109, 110, 111, 112, 113, 114, 115,
+        68, 116, 117, 118, 119, 68, 120, 121,
+        122, 68, 68, 68, 68, 123, 124, 125,
+        126, 127, 68, 68, 68, 68, 128, 68,
+        105, 98, 98, 98, 98, 98, 98, 98,
+        98, 98, 98, 98, 98, 99, 98, 105,
+        94, 94, 94, 94, 94, 94, 94, 94,
+        94, 94, 94, 94, 96, 94, 105, 68,
+        68, 68, 68, 68, 68, 68, 68, 68,
+        68, 68, 68, 70, 68, 68, 68, 68,
+        68, 68, 68, 68, 108, 109, 110, 111,
+        68, 68, 68, 68, 68, 68, 68, 68,
+        68, 68, 120, 121, 122, 68, 68, 68,
+        68, 68, 124, 125, 126, 129, 68, 8,
+        9, 132, 11, 132, 132, 132, 132, 132,
+        132, 132, 13, 14, 15, 16, 17, 18,
+        19, 20, 21, 8, 22, 23, 24, 25,
+        132, 26, 27, 28, 132, 132, 132, 132,
+        32, 33, 34, 35, 32, 132, 132, 132,
+        132, 37, 132, 8, 132, 132, 132, 132,
+        132, 132, 132, 132, 132, 132, 132, 132,
+        11, 132, 132, 132, 132, 132, 132, 132,
+        132, 14, 15, 16, 17, 132, 132, 132,
+        132, 132, 132, 132, 132, 132, 132, 26,
+        27, 28, 132, 132, 132, 132, 132, 33,
+        34, 35, 133, 132, 132, 132, 132, 14,
+        132, 11, 132, 132, 132, 132, 132, 132,
+        132, 132, 14, 15, 16, 17, 132, 132,
+        132, 132, 132, 132, 132, 132, 132, 132,
+        26, 27, 28, 132, 132, 132, 132, 132,
+        33, 34, 35, 133, 132, 11, 132, 132,
+        132, 132, 132, 132, 132, 132, 132, 15,
+        16, 17, 132, 132, 132, 132, 132, 132,
+        132, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 132, 132, 33, 34, 35, 132,
+        11, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 132, 16, 17, 132, 132, 132,
+        132, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 132, 132, 132, 132, 132, 33,
+        34, 35, 132, 11, 132, 132, 132, 132,
+        132, 132, 132, 132, 132, 132, 132, 17,
+        132, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 33, 34, 35, 132, 11, 132,
+        132, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 132, 132, 132, 33, 34, 132,
+        11, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 132, 132, 132, 132, 132, 132,
+        34, 132, 11, 132, 11, 132, 132, 132,
+        132, 132, 132, 132, 132, 132, 15, 16,
+        17, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 132, 26, 27, 28, 132, 132,
+        132, 132, 132, 33, 34, 35, 133, 132,
+        11, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 15, 16, 17, 132, 132, 132,
+        132, 132, 132, 132, 132, 132, 132, 132,
+        27, 28, 132, 132, 132, 132, 132, 33,
+        34, 35, 133, 132, 11, 132, 132, 132,
+        132, 132, 132, 132, 132, 132, 15, 16,
+        17, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 132, 132, 132, 28, 132, 132,
+        132, 132, 132, 33, 34, 35, 133, 132,
+        134, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 132, 132, 132, 11, 132, 11,
+        132, 132, 132, 132, 132, 132, 132, 132,
+        132, 15, 16, 17, 132, 132, 132, 132,
+        132, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 132, 132, 132, 132, 33, 34,
+        35, 133, 132, 11, 132, 132, 132, 132,
+        132, 132, 132, 13, 14, 15, 16, 17,
+        132, 132, 132, 132, 132, 132, 23, 24,
+        25, 132, 26, 27, 28, 132, 132, 132,
+        132, 132, 33, 34, 35, 133, 132, 132,
+        132, 132, 14, 132, 11, 132, 132, 132,
+        132, 132, 132, 132, 132, 14, 15, 16,
+        17, 132, 132, 132, 132, 132, 132, 23,
+        24, 25, 132, 26, 27, 28, 132, 132,
+        132, 132, 132, 33, 34, 35, 133, 132,
+        132, 132, 132, 14, 132, 11, 132, 132,
+        132, 132, 132, 132, 132, 132, 14, 15,
+        16, 17, 132, 132, 132, 132, 132, 132,
+        132, 24, 25, 132, 26, 27, 28, 132,
+        132, 132, 132, 132, 33, 34, 35, 133,
+        132, 132, 132, 132, 14, 132, 11, 132,
+        132, 132, 132, 132, 132, 132, 132, 14,
+        15, 16, 17, 132, 132, 132, 132, 132,
+        132, 132, 132, 25, 132, 26, 27, 28,
+        132, 132, 132, 132, 132, 33, 34, 35,
+        133, 132, 132, 132, 132, 14, 132, 135,
+        132, 11, 132, 132, 132, 132, 132, 132,
+        132, 13, 14, 15, 16, 17, 132, 19,
+        20, 132, 132, 132, 23, 24, 25, 132,
+        26, 27, 28, 132, 132, 132, 132, 132,
+        33, 34, 35, 133, 132, 132, 132, 132,
+        14, 132, 11, 132, 132, 132, 132, 132,
+        132, 132, 132, 14, 15, 16, 17, 132,
+        132, 132, 132, 132, 132, 132, 132, 132,
+        132, 26, 27, 28, 132, 132, 132, 132,
+        132, 33, 34, 35, 133, 132, 132, 132,
+        132, 14, 132, 135, 132, 11, 132, 132,
+        132, 132, 132, 132, 132, 13, 14, 15,
+        16, 17, 132, 132, 20, 132, 132, 132,
+        23, 24, 25, 132, 26, 27, 28, 132,
+        132, 132, 132, 132, 33, 34, 35, 133,
+        132, 132, 132, 132, 14, 132, 135, 132,
+        11, 132, 132, 132, 132, 132, 132, 132,
+        13, 14, 15, 16, 17, 132, 132, 132,
+        132, 132, 132, 23, 24, 25, 132, 26,
+        27, 28, 132, 132, 132, 132, 132, 33,
+        34, 35, 133, 132, 132, 132, 132, 14,
+        132, 135, 132, 11, 132, 132, 132, 132,
+        132, 132, 132, 13, 14, 15, 16, 17,
+        18, 19, 20, 132, 132, 132, 23, 24,
+        25, 132, 26, 27, 28, 132, 132, 132,
+        132, 132, 33, 34, 35, 133, 132, 132,
+        132, 132, 14, 132, 8, 9, 132, 11,
+        132, 132, 132, 132, 132, 132, 132, 13,
         14, 15, 16, 17, 18, 19, 20, 21,
-        22, 23, 134, 24, 25, 26, 134, 27,
-        28, 134, 30, 31, 32, 33, 30, 134,
-        134, 134, 134, 36, 134, 5, 6, 134,
-        8, 134, 134, 134, 134, 134, 134, 134,
-        10, 11, 12, 13, 14, 15, 16, 17,
-        18, 19, 20, 21, 22, 23, 134, 24,
-        25, 26, 134, 134, 134, 134, 30, 31,
-        32, 33, 30, 134, 134, 134, 134, 36,
-        134, 8, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 134, 27, 28, 134, 8,
-        134, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 134, 134, 134, 134, 134,
-        134, 134, 134, 28, 134, 1, 139, 139,
-        139, 1, 139, 141, 140, 140, 140, 140,
-        140, 140, 140, 140, 140, 140, 140, 140,
-        140, 140, 140, 140, 140, 140, 140, 140,
-        140, 140, 140, 140, 140, 140, 140, 140,
-        140, 140, 140, 140, 140, 140, 140, 142,
-        140, 34, 140, 141, 140, 140, 140, 140,
-        140, 140, 140, 140, 140, 140, 140, 140,
-        140, 140, 140, 140, 140, 140, 140, 140,
-        140, 140, 140, 140, 140, 140, 140, 140,
-        140, 140, 140, 140, 140, 140, 34, 142,
-        140, 142, 140, 141, 140, 140, 140, 140,
-        140, 140, 140, 140, 140, 140, 140, 140,
-        140, 140, 140, 140, 140, 140, 140, 140,
-        140, 140, 140, 140, 140, 140, 140, 140,
-        140, 140, 140, 140, 140, 140, 34, 140,
-        35, 140, 0
+        132, 22, 23, 24, 25, 132, 26, 27,
+        28, 132, 132, 132, 132, 32, 33, 34,
+        35, 32, 132, 132, 132, 132, 37, 132,
+        8, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 132, 132, 132, 11, 132, 8,
+        132, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 132, 132, 11, 132, 132, 132,
+        132, 132, 132, 132, 132, 14, 15, 16,
+        17, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 132, 26, 27, 28, 132, 132,
+        132, 132, 132, 33, 34, 35, 133, 132,
+        136, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 11, 132, 10, 11, 132, 4,
+        132, 132, 132, 4, 132, 132, 132, 132,
+        132, 8, 9, 10, 11, 132, 132, 132,
+        132, 132, 132, 132, 13, 14, 15, 16,
+        17, 18, 19, 20, 21, 8, 22, 23,
+        24, 25, 132, 26, 27, 28, 132, 29,
+        30, 132, 32, 33, 34, 35, 32, 132,
+        132, 132, 132, 37, 132, 11, 132, 132,
+        132, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 132, 132, 132, 132, 132, 132,
+        29, 30, 132, 11, 132, 132, 132, 132,
+        132, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 132, 132, 132, 132, 132, 132,
+        132, 132, 132, 132, 132, 132, 132, 30,
+        132, 4, 137, 137, 137, 4, 137, 139,
+        138, 138, 138, 138, 138, 138, 138, 138,
+        138, 138, 138, 138, 138, 138, 138, 138,
+        138, 138, 138, 138, 138, 138, 138, 138,
+        138, 138, 138, 138, 138, 138, 138, 138,
+        138, 138, 138, 140, 138, 141, 138, 141,
+        142, 138, 139, 138, 138, 138, 138, 138,
+        138, 138, 138, 138, 138, 138, 138, 138,
+        138, 138, 138, 138, 138, 138, 138, 138,
+        138, 138, 138, 138, 138, 138, 138, 138,
+        138, 138, 138, 138, 138, 1, 140, 140,
+        138, 139, 138, 138, 138, 138, 138, 138,
+        138, 138, 138, 138, 138, 138, 138, 138,
+        138, 138, 138, 138, 138, 138, 138, 138,
+        138, 138, 138, 138, 138, 138, 138, 138,
+        138, 138, 138, 138, 138, 140, 138, 141,
+        138, 139, 138, 138, 138, 138, 138, 138,
+        138, 138, 138, 138, 138, 138, 138, 138,
+        138, 138, 138, 138, 138, 138, 138, 138,
+        138, 138, 138, 138, 138, 138, 138, 138,
+        138, 138, 138, 138, 138, 140, 138, 141,
+        138, 141, 138, 39, 40, 38, 41, 38,
+        38, 38, 38, 38, 38, 38, 42, 43,
+        44, 45, 46, 47, 48, 49, 50, 39,
+        51, 52, 53, 54, 38, 55, 56, 57,
+        38, 58, 59, 38, 60, 61, 62, 63,
+        60, 1, 38, 2, 38, 64, 38, 0
 };
 
 static const char _use_syllable_machine_trans_targs[] = {
-        1, 31, 0, 59, 61, 90, 91, 116,
-        0, 118, 104, 92, 93, 94, 95, 108,
-        110, 111, 112, 119, 113, 105, 106, 107,
-        99, 100, 101, 120, 121, 122, 114, 96,
-        97, 98, 123, 125, 115, 0, 2, 3,
-        0, 16, 4, 5, 6, 7, 20, 22,
-        23, 24, 28, 25, 17, 18, 19, 11,
-        12, 13, 29, 30, 26, 8, 9, 10,
-        27, 14, 15, 21, 0, 32, 33, 0,
-        46, 34, 35, 36, 37, 50, 52, 53,
-        54, 55, 47, 48, 49, 41, 42, 43,
-        56, 38, 39, 40, 57, 58, 44, 0,
-        45, 0, 51, 0, 0, 0, 60, 0,
-        0, 0, 62, 63, 76, 64, 65, 66,
-        67, 80, 82, 83, 84, 89, 85, 77,
-        78, 79, 71, 72, 73, 86, 68, 69,
-        70, 87, 88, 74, 75, 81, 0, 102,
-        103, 109, 117, 0, 0, 0, 124
+        1, 120, 0, 2, 31, 1, 58, 60,
+        88, 89, 114, 1, 116, 102, 90, 91,
+        92, 93, 106, 108, 109, 110, 111, 103,
+        104, 105, 97, 98, 99, 117, 118, 119,
+        112, 94, 95, 96, 124, 113, 1, 3,
+        4, 1, 17, 5, 6, 7, 8, 21,
+        23, 24, 25, 26, 18, 19, 20, 12,
+        13, 14, 29, 30, 27, 9, 10, 11,
+        28, 15, 16, 22, 1, 32, 1, 45,
+        33, 34, 35, 36, 49, 51, 52, 53,
+        54, 46, 47, 48, 40, 41, 42, 55,
+        37, 38, 39, 56, 57, 43, 1, 44,
+        1, 50, 1, 1, 1, 59, 1, 1,
+        1, 61, 62, 75, 63, 64, 65, 66,
+        79, 81, 82, 83, 84, 76, 77, 78,
+        70, 71, 72, 85, 67, 68, 69, 86,
+        87, 73, 74, 80, 1, 100, 101, 107,
+        115, 1, 1, 1, 121, 122, 123
 };
 
 static const char _use_syllable_machine_trans_actions[] = {
-        0, 0, 3, 0, 0, 0, 0, 0,
-        4, 0, 0, 0, 0, 0, 0, 0,
+        1, 0, 0, 0, 0, 4, 0, 0,
+        0, 0, 0, 5, 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, 5, 0, 0,
-        6, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 6, 0, 7, 0,
+        0, 8, 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, 7, 0, 0, 8,
+        0, 0, 0, 0, 9, 0, 10, 0,
         0, 0, 0, 0, 0, 0, 0, 0,
         0, 0, 0, 0, 0, 0, 0, 0,
-        0, 0, 0, 0, 0, 0, 0, 9,
-        0, 10, 0, 11, 12, 13, 0, 14,
-        15, 16, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 11, 0,
+        12, 0, 13, 14, 15, 0, 16, 17,
+        18, 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, 17, 0,
-        0, 0, 0, 18, 19, 20, 0
+        0, 0, 0, 0, 19, 0, 0, 0,
+        0, 20, 21, 22, 0, 0, 0
 };
 
 static const char _use_syllable_machine_to_state_actions[] = {
-        1, 0, 0, 0, 0, 0, 0, 0,
+        0, 2, 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,
@@ -778,11 +769,11 @@
         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
 };
 
 static const char _use_syllable_machine_from_state_actions[] = {
-        2, 0, 0, 0, 0, 0, 0, 0,
+        0, 3, 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,
@@ -797,40 +788,40 @@
         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
 };
 
 static const short _use_syllable_machine_eof_trans[] = {
-        0, 38, 38, 38, 38, 38, 38, 38,
-        38, 38, 38, 38, 38, 38, 38, 38,
-        38, 38, 38, 38, 38, 38, 38, 38,
-        38, 38, 38, 38, 38, 38, 38, 69,
+        1, 0, 39, 39, 39, 39, 39, 39,
+        39, 39, 39, 39, 39, 39, 39, 39,
+        39, 39, 39, 39, 39, 39, 39, 39,
+        39, 39, 39, 39, 39, 39, 39, 69,
         69, 69, 69, 69, 69, 69, 69, 69,
-        69, 69, 69, 69, 96, 69, 69, 69,
+        69, 69, 69, 95, 69, 69, 69, 69,
+        69, 69, 69, 69, 69, 69, 69, 99,
+        95, 69, 101, 104, 69, 69, 69, 69,
         69, 69, 69, 69, 69, 69, 69, 69,
-        100, 96, 69, 102, 105, 69, 69, 69,
-        69, 69, 69, 69, 69, 69, 69, 69,
-        69, 69, 96, 69, 69, 69, 69, 69,
-        69, 69, 69, 69, 69, 69, 100, 96,
-        69, 69, 135, 135, 135, 135, 135, 135,
-        135, 135, 135, 135, 135, 135, 135, 135,
-        135, 135, 135, 135, 135, 135, 135, 135,
-        135, 135, 135, 135, 135, 135, 135, 135,
-        135, 135, 140, 141, 141, 141
+        69, 95, 69, 69, 69, 69, 69, 69,
+        69, 69, 69, 69, 69, 99, 95, 69,
+        133, 133, 133, 133, 133, 133, 133, 133,
+        133, 133, 133, 133, 133, 133, 133, 133,
+        133, 133, 133, 133, 133, 133, 133, 133,
+        133, 133, 133, 133, 133, 133, 133, 138,
+        139, 139, 139, 139, 39
 };
 
-static const int use_syllable_machine_start = 0;
-static const int use_syllable_machine_first_final = 0;
+static const int use_syllable_machine_start = 1;
+static const int use_syllable_machine_first_final = 1;
 static const int use_syllable_machine_error = -1;
 
-static const int use_syllable_machine_en_main = 0;
+static const int use_syllable_machine_en_main = 1;
 
 
 #line 58 "hb-ot-shaper-use-machine.rl"
 
 
 
-#line 182 "hb-ot-shaper-use-machine.rl"
+#line 184 "hb-ot-shaper-use-machine.rl"
 
 
 #define found_syllable(syllable_type) \
@@ -929,7 +920,7 @@
   unsigned int act HB_UNUSED;
   int cs;
 
-#line 922 "hb-ot-shaper-use-machine.hh"
+#line 924 "hb-ot-shaper-use-machine.hh"
         {
         cs = use_syllable_machine_start;
         ts = 0;
@@ -937,12 +928,12 @@
         act = 0;
         }
 
-#line 282 "hb-ot-shaper-use-machine.rl"
+#line 284 "hb-ot-shaper-use-machine.rl"
 
 
   unsigned int syllable_serial = 1;
 
-#line 931 "hb-ot-shaper-use-machine.hh"
+#line 937 "hb-ot-shaper-use-machine.hh"
         {
         int _slen;
         int _trans;
@@ -952,11 +943,11 @@
                 goto _test_eof;
 _resume:
         switch ( _use_syllable_machine_from_state_actions[cs] ) {
-        case 2:
+        case 3:
 #line 1 "NONE"
         {ts = p;}
         break;
-#line 943 "hb-ot-shaper-use-machine.hh"
+#line 951 "hb-ot-shaper-use-machine.hh"
         }
 
         _keys = _use_syllable_machine_trans_keys + (cs<<1);
@@ -974,88 +965,96 @@
                 goto _again;
 
         switch ( _use_syllable_machine_trans_actions[_trans] ) {
-        case 12:
-#line 170 "hb-ot-shaper-use-machine.rl"
-        {te = p+1;{ found_syllable (use_virama_terminated_cluster); }}
-        break;
-        case 10:
-#line 171 "hb-ot-shaper-use-machine.rl"
-        {te = p+1;{ found_syllable (use_sakot_terminated_cluster); }}
-        break;
-        case 8:
-#line 172 "hb-ot-shaper-use-machine.rl"
-        {te = p+1;{ found_syllable (use_standard_cluster); }}
-        break;
-        case 16:
-#line 173 "hb-ot-shaper-use-machine.rl"
-        {te = p+1;{ found_syllable (use_number_joiner_terminated_cluster); }}
+        case 6:
+#line 1 "NONE"
+        {te = p+1;}
         break;
         case 14:
-#line 174 "hb-ot-shaper-use-machine.rl"
-        {te = p+1;{ found_syllable (use_numeral_cluster); }}
-        break;
-        case 6:
-#line 175 "hb-ot-shaper-use-machine.rl"
-        {te = p+1;{ found_syllable (use_symbol_cluster); }}
-        break;
-        case 20:
-#line 176 "hb-ot-shaper-use-machine.rl"
-        {te = p+1;{ found_syllable (use_hieroglyph_cluster); }}
-        break;
-        case 4:
-#line 177 "hb-ot-shaper-use-machine.rl"
-        {te = p+1;{ found_syllable (use_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }}
-        break;
-        case 3:
-#line 178 "hb-ot-shaper-use-machine.rl"
-        {te = p+1;{ found_syllable (use_non_cluster); }}
-        break;
-        case 11:
-#line 170 "hb-ot-shaper-use-machine.rl"
-        {te = p;p--;{ found_syllable (use_virama_terminated_cluster); }}
-        break;
-        case 9:
-#line 171 "hb-ot-shaper-use-machine.rl"
-        {te = p;p--;{ found_syllable (use_sakot_terminated_cluster); }}
-        break;
-        case 7:
 #line 172 "hb-ot-shaper-use-machine.rl"
-        {te = p;p--;{ found_syllable (use_standard_cluster); }}
+        {te = p+1;{ found_syllable (use_virama_terminated_cluster); }}
         break;
-        case 15:
+        case 12:
 #line 173 "hb-ot-shaper-use-machine.rl"
-        {te = p;p--;{ found_syllable (use_number_joiner_terminated_cluster); }}
+        {te = p+1;{ found_syllable (use_sakot_terminated_cluster); }}
         break;
-        case 13:
+        case 10:
 #line 174 "hb-ot-shaper-use-machine.rl"
-        {te = p;p--;{ found_syllable (use_numeral_cluster); }}
-        break;
-        case 5:
-#line 175 "hb-ot-shaper-use-machine.rl"
-        {te = p;p--;{ found_syllable (use_symbol_cluster); }}
-        break;
-        case 19:
-#line 176 "hb-ot-shaper-use-machine.rl"
-        {te = p;p--;{ found_syllable (use_hieroglyph_cluster); }}
-        break;
-        case 17:
-#line 177 "hb-ot-shaper-use-machine.rl"
-        {te = p;p--;{ found_syllable (use_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }}
+        {te = p+1;{ found_syllable (use_standard_cluster); }}
         break;
         case 18:
+#line 175 "hb-ot-shaper-use-machine.rl"
+        {te = p+1;{ found_syllable (use_number_joiner_terminated_cluster); }}
+        break;
+        case 16:
+#line 176 "hb-ot-shaper-use-machine.rl"
+        {te = p+1;{ found_syllable (use_numeral_cluster); }}
+        break;
+        case 8:
+#line 177 "hb-ot-shaper-use-machine.rl"
+        {te = p+1;{ found_syllable (use_symbol_cluster); }}
+        break;
+        case 22:
 #line 178 "hb-ot-shaper-use-machine.rl"
+        {te = p+1;{ found_syllable (use_hieroglyph_cluster); }}
+        break;
+        case 5:
+#line 179 "hb-ot-shaper-use-machine.rl"
+        {te = p+1;{ found_syllable (use_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }}
+        break;
+        case 4:
+#line 180 "hb-ot-shaper-use-machine.rl"
+        {te = p+1;{ found_syllable (use_non_cluster); }}
+        break;
+        case 13:
+#line 172 "hb-ot-shaper-use-machine.rl"
+        {te = p;p--;{ found_syllable (use_virama_terminated_cluster); }}
+        break;
+        case 11:
+#line 173 "hb-ot-shaper-use-machine.rl"
+        {te = p;p--;{ found_syllable (use_sakot_terminated_cluster); }}
+        break;
+        case 9:
+#line 174 "hb-ot-shaper-use-machine.rl"
+        {te = p;p--;{ found_syllable (use_standard_cluster); }}
+        break;
+        case 17:
+#line 175 "hb-ot-shaper-use-machine.rl"
+        {te = p;p--;{ found_syllable (use_number_joiner_terminated_cluster); }}
+        break;
+        case 15:
+#line 176 "hb-ot-shaper-use-machine.rl"
+        {te = p;p--;{ found_syllable (use_numeral_cluster); }}
+        break;
+        case 7:
+#line 177 "hb-ot-shaper-use-machine.rl"
+        {te = p;p--;{ found_syllable (use_symbol_cluster); }}
+        break;
+        case 21:
+#line 178 "hb-ot-shaper-use-machine.rl"
+        {te = p;p--;{ found_syllable (use_hieroglyph_cluster); }}
+        break;
+        case 19:
+#line 179 "hb-ot-shaper-use-machine.rl"
+        {te = p;p--;{ found_syllable (use_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }}
+        break;
+        case 20:
+#line 180 "hb-ot-shaper-use-machine.rl"
         {te = p;p--;{ found_syllable (use_non_cluster); }}
         break;
-#line 1014 "hb-ot-shaper-use-machine.hh"
+        case 1:
+#line 177 "hb-ot-shaper-use-machine.rl"
+        {{p = ((te))-1;}{ found_syllable (use_symbol_cluster); }}
+        break;
+#line 1049 "hb-ot-shaper-use-machine.hh"
         }
 
 _again:
         switch ( _use_syllable_machine_to_state_actions[cs] ) {
-        case 1:
+        case 2:
 #line 1 "NONE"
         {ts = 0;}
         break;
-#line 1021 "hb-ot-shaper-use-machine.hh"
+#line 1058 "hb-ot-shaper-use-machine.hh"
         }
 
         if ( ++p != pe )
@@ -1071,7 +1070,7 @@
 
         }
 
-#line 287 "hb-ot-shaper-use-machine.rl"
+#line 289 "hb-ot-shaper-use-machine.rl"
 
 }
 
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-table.hh
index 4339278..491b2f9 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-table.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use-table.hh
@@ -6,18 +6,18 @@
  *
  * on files with these headers:
  *
- * # IndicSyllabicCategory-15.0.0.txt
- * # Date: 2022-05-26, 02:18:00 GMT [KW, RP]
- * # IndicPositionalCategory-15.0.0.txt
- * # Date: 2022-05-26, 02:18:00 GMT [KW, RP]
- * # ArabicShaping-15.0.0.txt
- * # Date: 2022-02-14, 18:50:00 GMT [KW, RP]
- * # DerivedCoreProperties-15.0.0.txt
- * # Date: 2022-08-05, 22:17:05 GMT
- * # Blocks-15.0.0.txt
- * # Date: 2022-01-28, 20:58:00 GMT [KW]
- * # Scripts-15.0.0.txt
- * # Date: 2022-04-26, 23:15:02 GMT
+ * # IndicSyllabicCategory-15.1.0.txt
+ * # Date: 2023-01-05
+ * # IndicPositionalCategory-15.1.0.txt
+ * # Date: 2023-01-05
+ * # ArabicShaping-15.1.0.txt
+ * # Date: 2023-01-05
+ * # DerivedCoreProperties-15.1.0.txt
+ * # Date: 2023-08-07, 15:21:24 GMT
+ * # Blocks-15.1.0.txt
+ * # Date: 2023-07-28, 15:47:20 GMT
+ * # Scripts-15.1.0.txt
+ * # Date: 2023-07-28, 16:01:07 GMT
  * # Override values For Indic_Syllabic_Category
  * # Not derivable
  * # Initial version based on Unicode 7.0 by Andrew Glass 2014-03-17
@@ -26,6 +26,7 @@
  * # Updated for Unicode 13.0 by Andrew Glass 2020-07-28
  * # Updated for Unicode 14.0 by Andrew Glass 2021-09-25
  * # Updated for Unicode 15.0 by Andrew Glass 2022-09-16
+ * # Updated for Unicode 15.1 by Andrew Glass 2023-09-14
  * # Override values For Indic_Positional_Category
  * # Not derivable
  * # Initial version based on Unicode 7.0 by Andrew Glass 2014-03-17
@@ -36,6 +37,7 @@
  * # Updated for Unicode 13.0 by Andrew Glass 2020-07-28
  * # Updated for Unicode 14.0 by Andrew Glass 2021-09-28
  * # Updated for Unicode 15.0 by Andrew Glass 2022-09-16
+ * # Updated for Unicode 15.1 by Andrew Glass 2023-09-14
  * UnicodeData.txt does not have a header.
  */
 
@@ -54,7 +56,9 @@
 #define G       USE(G)  /* HIEROGLYPH */
 #define GB      USE(GB) /* BASE_OTHER */
 #define H       USE(H)  /* HALANT */
+#define HM      USE(HM) /* HIEROGLYPH_MOD */
 #define HN      USE(HN) /* HALANT_NUM */
+#define HR      USE(HR) /* HIEROGLYPH_MIRROR */
 #define HVM     USE(HVM)        /* HALANT_OR_VOWEL_MODIFIER */
 #define IS      USE(IS) /* INVISIBLE_STACKER */
 #define J       USE(J)  /* HIEROGLYPH_JOINER */
@@ -95,7 +99,7 @@
 #ifndef HB_OPTIMIZE_SIZE
 
 static const uint8_t
-hb_use_u8[3141] =
+hb_use_u8[3187] =
 {
      16,   50,   51,   51,   51,   52,   51,   83,  118,  131,   51,   57,   58,  179,  195,   61,
      51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,
@@ -109,244 +113,249 @@
      18,   19,   20,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,   21,
      22,   23,   24,   25,   26,   27,   28,   29,   30,   31,   32,    2,   33,    2,    2,    2,
       2,   34,   35,    2,    2,    2,    2,    2,    2,    2,    2,    2,   36,    2,    2,    2,
-      2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,   37,    2,    2,    2,    2,
+     37,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,   38,    2,   39,    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,    2,    2,    2,    2,
       2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
-      2,   38,   39,   40,   41,   42,   43,    2,   44,    2,    2,    2,    2,    2,    2,    2,
+      2,   40,   41,   42,   43,   44,   45,    2,   46,    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,    2,    2,    2,    2,    2,    2,   45,   46,    2,
-     47,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,   48,   49,    2,    2,    2,
-      2,    2,    2,    2,    2,   50,   51,    2,   52,    2,    2,   53,    2,    2,   54,   55,
-     56,   57,   58,   59,   60,   61,   62,   63,    2,   64,   65,    2,   66,   67,   68,   69,
-      2,   70,    2,   71,   72,   73,   74,    2,    2,   75,   76,   77,   78,    2,   79,   80,
-      2,   81,   81,   81,   81,   81,   81,   81,   81,   82,    2,    2,    2,    2,    2,    2,
+      2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,   47,   48,    2,
+     49,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,   50,   51,    2,    2,    2,
+      2,    2,    2,    2,    2,   52,   53,    2,   54,    2,    2,   55,    2,    2,   56,   57,
+     58,   59,   60,   61,   62,   63,   64,   65,    2,   66,   67,    2,   68,   69,   70,   71,
+      2,   72,    2,   73,   74,   75,   76,    2,    2,   77,   78,   79,   80,    2,   81,   82,
+      2,   83,   83,   83,   83,   83,   83,   83,   83,   84,    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,    2,    2,    2,    2,    2,    2,    2,    2,
-      2,    2,    2,    2,    2,    2,   83,   84,    2,    2,    2,    2,    2,    2,    2,   85,
-     86,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
-      2,    2,    2,    2,    2,    2,    2,   81,   81,   81,   87,    2,    2,    2,    2,    2,
+      2,    2,    2,    2,    2,    2,   85,   86,    2,    2,    2,    2,    2,    2,    2,   87,
+     88,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
+      2,    2,    2,    2,    2,    2,    2,   89,   89,   89,   90,    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,   88,   89,    2,    2,    2,    2,    2,
-      2,    2,    2,   90,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
+      2,    2,    2,    2,    2,    2,    2,    2,    2,   91,   92,    2,    2,    2,    2,    2,
+      2,    2,    2,   93,    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,    2,   91,    2,    2,   92,    2,    2,    2,   93,    2,    2,    2,    2,    2,
-      2,    2,    2,   94,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
-      2,   95,   95,   96,   97,   95,   95,   95,   95,   95,   95,   95,   95,   95,   95,   95,
-     95,   95,   95,   95,   95,   95,   95,   95,   95,   95,   95,   95,   95,   95,   95,   95,
-     95,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    1,
-      0,    2,    2,    2,    2,    2,    0,    0,    0,    3,    0,    0,    0,    0,    0,    4,
-      0,    0,    5,    0,    0,    0,    0,    0,    0,    0,    0,    0,    1,    0,    0,    0,
-      0,    0,    0,    0,    0,    0,    0,    0,    6,    7,    0,    0,    0,    0,    0,    0,
-      0,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
-      2,    2,    2,    2,    2,    2,    8,    9,    9,    9,    9,    0,    0,    0,    7,   10,
-      0,    2,    2,    2,    2,   11,   12,    0,    0,    9,   13,    2,    2,    2,    2,    2,
-      2,    2,    2,    2,    2,    2,   14,   15,   16,   17,   18,   19,   20,   14,   21,   22,
-     23,   10,   24,   25,   18,    2,    2,    2,    2,    2,   18,    0,    2,    2,    2,    2,
-      2,    0,    2,    2,    2,    2,    2,    2,    2,   26,   27,   28,    2,    2,    2,    7,
-     28,    7,   28,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    7,    2,    2,
-      2,    7,    7,    0,    2,    2,    0,   15,   16,   17,   18,   29,   30,   31,   30,   32,
-      0,    0,    0,    0,   33,    0,    0,    2,   28,    2,    0,    0,    0,    0,    0,    7,
-     34,   10,   13,   28,    2,    2,    7,    0,   28,    7,    2,   28,    7,    2,    0,   35,
-     16,   17,   29,    0,   25,   36,   25,   37,    0,   38,    0,    0,    0,   28,    2,    7,
-      7,    0,    0,    0,    2,    2,    2,    2,    2,   39,   40,   41,    0,    0,    0,    0,
-      0,   10,   13,   28,    2,    2,    2,    2,   28,    2,   28,    2,    2,    2,    2,    2,
-      2,    7,    2,   28,    2,    2,    0,   15,   16,   17,   18,   19,   25,   20,   33,   22,
-      0,    0,    0,    0,    0,   28,   39,   39,   42,   10,   27,   28,    2,    2,    2,    7,
-     28,    7,    2,   28,    2,    2,    0,   15,   43,    0,    0,   25,   20,    0,    0,    2,
-     28,   28,    0,    0,    0,    0,    0,    0,    0,    0,   44,   28,    2,    2,    7,    0,
-      2,    7,    2,    2,    0,   28,    7,    7,    2,    0,   28,    7,    0,    2,    7,    0,
-      2,    2,    2,    2,    2,    2,    0,    0,   21,   14,   45,    0,   46,   31,   46,   32,
-      0,    0,    0,    0,   33,    0,    0,    0,    0,   13,   27,   47,    2,    2,    2,    7,
-      2,    7,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    0,   15,
-     20,   14,   21,   45,   20,   36,   20,   37,    0,    0,    0,   25,   29,    2,    7,    0,
-      0,    8,   27,   28,    2,    2,    2,    7,    2,    2,    2,   28,    2,    2,    0,   15,
-     43,    0,    0,   33,   45,    0,    0,    0,    7,   48,   49,    0,    0,    0,    0,    0,
-      0,    9,   27,    2,    2,    2,    2,    7,    2,    2,    2,    2,    2,    2,   50,   51,
-     21,   21,   17,   29,   46,   31,   46,   32,   52,    0,    0,    0,   33,    0,    0,    0,
-     28,   10,   27,   28,    2,    2,    2,    2,    2,    2,    2,    2,    7,    0,    2,    2,
-      2,    2,   28,    2,    2,    2,    2,   28,    0,    2,    2,    2,    7,    0,   53,    0,
-     33,   21,   20,   29,   29,   16,   46,   46,   23,    0,   21,    0,    0,    0,    0,    0,
-      0,    2,    0,    2,    7,    0,    0,    0,    0,    0,    0,    0,    0,   18,    0,    0,
-      0,    2,    2,   54,   54,   55,    0,    0,   16,    2,    2,    2,    2,   28,    2,    2,
-      2,    2,    2,    2,    2,    2,    2,    7,    0,   56,   19,   57,   20,   20,   18,   18,
-     44,   19,    9,   29,    9,    2,    2,   58,   59,   59,   59,   59,   59,   60,   59,   59,
-     59,   59,   59,   59,   59,   59,   59,   59,   59,   59,   59,   59,   59,   59,   59,   61,
-      0,    0,    0,    0,   62,    0,    0,    0,    0,    2,    2,    2,    2,    2,   63,   43,
-     57,   64,   20,   20,   65,   66,   67,   68,   69,    2,    2,    2,    2,    2,    1,    0,
-      3,    2,    2,    2,   21,   18,    2,    2,   70,   69,   71,   72,   63,   71,   27,   27,
-      2,   50,   20,   51,    2,    2,    2,    2,    2,    2,   73,   74,   75,   27,   27,   76,
-     77,    2,    2,    2,    2,    2,   27,   43,    0,    2,   57,   78,    0,    0,    0,    0,
-     28,    2,   57,   45,    0,    0,    0,    0,    0,    2,   57,    0,    0,    0,    0,    0,
-      0,    2,    2,    2,    2,    2,    2,    7,    2,    7,   57,    0,    0,    0,    0,    0,
-      0,    2,    2,   79,   43,   20,   57,   18,   46,   46,   46,   46,   13,   80,   81,   82,
-     83,   84,   85,    0,    0,    0,    0,   86,    0,    7,    0,    0,   28,    0,   87,   79,
-     88,    2,    2,    2,    2,    7,    0,    0,    0,   40,   40,   89,   90,    2,    2,    2,
-      2,    2,    2,    2,    2,   11,    7,    0,    0,   91,    2,    2,    2,    2,    2,    2,
-      2,    2,    2,    2,    2,    2,    2,    2,    7,   20,   78,   43,   20,   92,   59,    0,
-      0,   93,   94,   93,   93,   95,   96,    0,    0,    2,    2,    2,    2,    2,    2,    2,
-      0,    2,    2,    7,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,    2,    0,
-      0,    2,    2,    2,    2,   27,    0,    0,    0,    2,    2,    2,    2,    2,    7,    0,
-      0,    2,    2,    2,   50,   97,   43,    0,    0,    2,    2,   98,   99,  100,  101,   59,
-     61,  102,   14,   43,   20,   57,   19,   78,   46,   46,   74,    9,    9,    9,  103,   44,
-     38,    9,  104,   72,    2,    2,    2,    2,    2,    2,    2,  105,   20,   18,   18,   20,
-     46,   46,   20,  106,    2,    2,    2,    7,    0,    0,    0,    0,    0,    0,  107,  108,
-    109,  109,  109,    0,    0,    0,    0,    0,    0,  104,   72,    2,    2,    2,    2,    2,
-      2,   58,   59,   57,   23,   20,  110,   59,    2,    2,    2,    2,  105,   20,   21,   43,
-     43,  100,   12,    0,    0,    0,    0,    0,    0,    2,    2,   59,   16,   46,   21,  111,
-    100,  100,  100,  112,  113,    0,    0,    0,    0,    2,    2,    2,    2,    2,    0,   28,
-      2,    9,   44,  114,  114,  114,    9,  114,  114,   13,  114,  114,  114,   24,    0,   38,
-      0,    0,    0,  115,   49,    9,    3,    0,    0,    0,    0,    0,    0,    0,  116,    0,
-      0,    0,    0,    0,    0,    0,    4,  117,  118,   40,   40,    3,    0,    0,    0,    0,
-      0,    0,    0,    0,    0,    0,  118,  118,  119,  118,  118,  118,  118,  118,  118,  118,
-    118,    0,    0,  120,    0,    0,    0,    0,    0,    0,    5,  120,    0,    0,    0,    0,
-      0,   44,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    7,
-      0,    2,    2,    2,    2,    0,    0,    0,   28,    0,    0,    0,    0,    0,    0,    0,
-    121,    2,   51,    2,  106,    2,    8,    2,    2,    2,   63,   17,   14,    0,    0,   29,
-      0,    2,    2,    0,    0,    0,    0,    0,    0,   27,    2,    2,    2,    2,    2,    2,
-      2,    2,    2,  122,   21,   21,   21,   21,   21,   21,   21,  123,    0,    0,    0,    0,
-      0,    9,    9,    9,    9,    9,    9,    9,    9,    9,    2,    0,    0,    0,    0,    0,
-     50,    2,    2,    2,   20,   20,  124,  114,    0,    2,    2,    2,  125,   18,   57,   18,
-    111,  100,  126,    0,    0,    0,    0,    0,    0,    9,  127,    2,    2,    2,    2,    2,
-      2,    2,  128,   21,   20,   18,   46,  129,  130,  131,    0,    0,    0,    0,    0,    0,
-      0,    2,    2,   50,   28,    2,    2,    2,    2,    2,    2,    2,    2,    8,   20,   57,
-     97,   74,  132,  133,  134,    0,    0,    0,    0,    2,  135,    2,    2,    2,    2,  136,
-      0,   28,    2,   40,    3,    0,   77,   13,    2,   51,   20,  137,   50,   51,    2,    2,
-    103,    8,    7,    0,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,  138,   19,
-     23,    0,    0,  139,  140,    0,    0,    0,    0,    2,   63,   43,   21,   78,   45,  141,
-      0,   79,   79,   79,   79,   79,   79,   79,   79,    0,    0,    0,    0,    0,    0,    0,
-      4,  118,  118,  118,  118,  119,    0,    0,    0,    2,    2,    2,    2,    2,    7,    2,
-      2,    2,    7,    2,   28,    2,    2,    2,    2,    2,   28,    2,    2,    2,   28,    7,
-      0,  125,   18,   25,   29,    0,    0,  142,  143,    2,    2,   28,    2,   28,    2,    2,
-      2,    2,    2,    2,    0,   12,   35,    0,  144,    2,    2,   11,   35,    0,   28,    2,
-      2,    2,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,   28,    2,    2,
-      7,    2,    2,    9,   39,    0,    0,    0,    0,    2,    2,    2,    2,    2,   25,   36,
-      0,    2,    2,    2,  114,  114,  114,  114,  114,  145,    2,    7,    0,    0,    0,    0,
-      0,    2,   12,   12,    0,    0,    0,    0,    0,    7,    2,    2,    7,    2,    2,    2,
-      2,   28,    2,    7,    0,   28,    2,    0,    0,  146,  147,  148,    2,    2,    2,    2,
-      2,    2,    2,    2,    2,   20,   20,   18,   18,   18,   20,   20,  131,    0,    0,    0,
-      0,    0,  149,  149,  149,  149,  149,  149,  149,  149,  149,  149,    2,    2,    2,    2,
-      2,   51,   50,   51,    0,    0,    0,    0,  150,    9,   72,    2,    2,    2,    2,    2,
-      2,   16,   17,   19,   14,   22,   35,    0,    0,    0,   29,    0,    0,    0,    0,    0,
-      0,    9,   47,    2,    2,    2,    2,    2,    2,    2,    2,    2,  125,   18,   20,  151,
-     20,   19,  152,  153,    2,    2,    2,    2,    2,    0,    0,   63,  154,    0,    0,    0,
-      0,    2,   11,    0,    0,    0,    0,    0,    0,    2,   63,   23,   18,   18,   18,   20,
-     20,  106,  155,    0,    0,   54,  156,   29,  157,   28,    2,    2,    2,    2,    2,    2,
-      2,    2,    2,    2,    2,    2,    2,   21,   17,   20,   20,  158,   42,    0,    0,    0,
-     47,  125,    0,    0,    0,    0,    0,    0,    0,    2,    2,    2,    7,    7,    2,    2,
-     28,    2,    2,    2,    2,    2,    2,    2,   28,    2,    2,    2,    2,    2,    2,    2,
-      8,   16,   17,   19,   20,  159,   29,    0,    0,    9,    9,   28,    2,    2,    2,    7,
-     28,    7,    2,   28,    2,    2,   56,   15,   21,   14,   21,   45,   30,   31,   30,   32,
-      0,    0,    0,    0,   33,    0,    0,    0,    2,    2,   21,    0,    9,    9,    9,   44,
-      0,    9,    9,   44,    0,    0,    0,    0,    0,    2,    2,   63,   23,   18,   18,   18,
-     20,   21,  123,   13,   15,    0,    0,    0,    0,    2,    2,    2,    2,    2,    0,    0,
-    160,  161,    0,    0,    0,    0,    0,    0,    0,   16,   17,   18,   18,   64,   97,   23,
-    157,    9,  162,    7,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,    2,    2,
-     63,   23,   18,   18,    0,   46,   46,    9,  163,   35,    0,    0,    0,    0,    0,    0,
-      0,    0,    0,    0,    0,    2,    2,   18,    0,   21,   17,   18,   18,   19,   14,   80,
-    163,   36,    0,    0,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,    8,  164,
-     23,   18,   20,   20,  162,    7,    0,    0,    0,    2,    2,    2,    2,    2,    7,   41,
-    133,   21,   20,   18,   74,   19,   20,    0,    0,    2,    2,    2,    7,    0,    0,    0,
-      0,    2,    2,    2,    2,    2,    2,   16,   17,   18,   19,   20,  103,  163,   35,    0,
-      0,    2,    2,    2,    7,   28,    0,    2,    2,    2,    2,   28,    7,    2,    2,    2,
-      2,   21,   21,   16,   30,   31,   10,  165,  166,  167,  168,    0,    0,    0,    0,    0,
-      0,    2,    2,    2,    2,    0,    2,    2,    2,   63,   23,   18,   18,    0,   20,   21,
-     27,  106,    0,   31,    0,    0,    0,    0,    0,   50,   18,   20,   20,   20,  137,    2,
-      2,    2,  169,  170,    9,   13,  171,   70,  172,    0,    0,    1,  144,    0,    0,    0,
-      0,   50,   18,   20,   14,   17,   18,    2,    2,    2,    2,  155,  155,  155,  173,  173,
-    173,  173,  173,  173,   13,  174,    0,   28,    0,   20,   18,   18,   29,   20,   20,    9,
-    163,    0,   59,   59,   59,   59,   59,   59,   59,   64,   19,   80,   44,    0,    0,    0,
-      0,    2,    2,    2,    7,    2,   28,    2,    2,   50,   20,   20,   29,    0,   36,   20,
-     25,    9,  156,  175,  171,    0,    0,    0,    0,    2,    2,    2,   28,    7,    2,    2,
-      2,    2,    2,    2,    2,    2,   21,   21,   45,   20,   33,   80,   66,    0,    0,    0,
-      0,    2,  176,   64,   45,    0,    0,    0,    0,    9,  177,    2,    2,    2,    2,    2,
-      2,    2,    2,   21,   20,   18,   29,    0,   46,   14,  140,    0,    0,    0,    0,    0,
-      0,  178,  178,  178,  106,  179,  178,    0,    0,  145,    2,    2,  180,  114,  114,  114,
-    114,  114,  114,  114,    0,    0,    0,    0,    0,    9,    9,    9,   44,    0,    0,    0,
-      0,    2,    2,    2,    2,    2,    7,    0,   56,  181,   18,   18,   18,   18,   18,   18,
-     18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,    0,    0,    0,
-     38,  114,   24,    0,    0,    0,    0,    0,    0,    0,    0,    7,    0,    0,    0,    0,
-      0,    2,    2,    2,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,    0,   56,
-     35,    0,    4,  118,  118,  118,  119,    0,    0,    9,    9,    9,   47,    2,    2,    2,
+      2,    2,    2,   94,    2,    2,   95,    2,    2,    2,   96,    2,    2,    2,    2,    2,
+      2,    2,    2,   97,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
+      2,   98,   98,   99,  100,   98,   98,   98,   98,   98,   98,   98,   98,   98,   98,   98,
+     98,   98,   98,   98,   98,   98,   98,   98,   98,   98,   98,   98,   98,   98,   98,   98,
+     98,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    1,
+      0,    2,    2,    2,    2,    2,    0,    0,    0,    0,    0,    0,    0,    0,    3,    4,
+      0,    5,    0,    0,    0,    0,    0,    6,    0,    0,    7,    0,    0,    0,    0,    0,
+      0,    0,    0,    0,    1,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+      8,    9,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    2,    2,
+      2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,   10,   11,
+     11,   11,   11,    0,    0,    0,    9,   12,    0,    2,    2,    2,    2,   13,   14,    0,
+      0,   11,   15,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,   16,   17,
+     18,   19,   20,   21,   22,   16,   23,   24,   25,   12,   26,   27,   20,    2,    2,    2,
+      2,    2,   20,    0,    2,    2,    2,    2,    2,    0,    2,    2,    2,    2,    2,    2,
+      2,   28,   29,   30,    2,    2,    2,    9,   30,    9,   30,    2,    2,    2,    2,    2,
+      2,    2,    2,    2,    2,    9,    2,    2,    2,    9,    9,    0,    2,    2,    0,   17,
+     18,   19,   20,   31,   32,   33,   32,   34,    0,    0,    0,    0,   35,    0,    0,    2,
+     30,    2,    0,    0,    0,    0,    0,    9,   36,   12,   15,   30,    2,    2,    9,    0,
+     30,    9,    2,   30,    9,    2,    0,   37,   18,   19,   31,    0,   27,   38,   27,   39,
+      0,   40,    0,    0,    0,   30,    2,    9,    9,    0,    0,    0,    2,    2,    2,    2,
+      2,   41,   42,   43,    0,    0,    0,    0,    0,   12,   15,   30,    2,    2,    2,    2,
+     30,    2,   30,    2,    2,    2,    2,    2,    2,    9,    2,   30,    2,    2,    0,   17,
+     18,   19,   20,   21,   27,   22,   35,   24,    0,    0,    0,    0,    0,   30,   41,   41,
+     44,   12,   29,   30,    2,    2,    2,    9,   30,    9,    2,   30,    2,    2,    0,   17,
+     45,    0,    0,   27,   22,    0,    0,    2,   30,   30,    0,    0,    0,    0,    0,    0,
+      0,    0,   46,   30,    2,    2,    9,    0,    2,    9,    2,    2,    0,   30,    9,    9,
+      2,    0,   30,    9,    0,    2,    9,    0,    2,    2,    2,    2,    2,    2,    0,    0,
+     23,   16,   47,    0,   48,   33,   48,   34,    0,    0,    0,    0,   35,    0,    0,    0,
+      0,   15,   29,   49,    2,    2,    2,    9,    2,    9,    2,    2,    2,    2,    2,    2,
+      2,    2,    2,    2,    2,    2,    0,   17,   22,   16,   23,   47,   22,   38,   22,   39,
+      0,    0,    0,   27,   31,    2,    9,    0,    0,   10,   29,   30,    2,    2,    2,    9,
+      2,    2,    2,   30,    2,    2,    0,   17,   45,    0,    0,   35,   47,    0,    0,    0,
+      9,   50,   51,    0,    0,    0,    0,    0,    0,   11,   29,    2,    2,    2,    2,    9,
+      2,    2,    2,    2,    2,    2,   52,   53,   23,   23,   19,   31,   48,   33,   48,   34,
+     54,    0,    0,    0,   35,    0,    0,    0,   30,   12,   29,   30,    2,    2,    2,    2,
+      2,    2,    2,    2,    9,    0,    2,    2,    2,    2,   30,    2,    2,    2,    2,   30,
+      0,    2,    2,    2,    9,    0,   55,    0,   35,   23,   22,   31,   31,   18,   48,   48,
+     25,    0,   23,    0,    0,    0,    0,    0,    0,    2,    0,    2,    9,    0,    0,    0,
+      0,    0,    0,    0,    0,   20,    0,    0,    0,    2,    2,   56,   56,   57,    0,    0,
+     18,    2,    2,    2,    2,   30,    2,    2,    2,    2,    2,    2,    2,    2,    2,    9,
+      0,   58,   21,   59,   22,   22,   20,   20,   46,   21,   11,   31,   11,    2,    2,   60,
+     61,   61,   61,   61,   61,   62,   61,   61,   61,   61,   61,   61,   61,   61,   61,   61,
+     61,   61,   61,   61,   61,   61,   61,   63,    0,    0,    0,    0,   64,    0,    0,    0,
+      0,    2,    2,    2,    2,    2,   65,   45,   59,   66,   22,   22,   67,   68,   69,   70,
+     71,    2,    2,    2,    2,    2,    1,    0,    5,    2,    2,    2,   23,   20,    2,    2,
+     72,   71,   73,   74,   65,   73,   29,   29,    2,   52,   22,   53,    2,    2,    2,    2,
+      2,    2,   75,   76,   77,   29,   29,   78,   79,    2,    2,    2,    2,    2,   29,   45,
+      0,    2,   59,   80,    0,    0,    0,    0,   30,    2,   59,   47,    0,    0,    0,    0,
+      0,    2,   59,    0,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,    2,    9,
+      2,    9,   59,    0,    0,    0,    0,    0,    0,    2,    2,   81,   45,   22,   59,   20,
+     48,   48,   48,   48,   15,   82,   83,   84,   85,   86,   87,    0,    0,    0,    0,   88,
+      0,    9,    0,    0,   30,    0,   89,   81,   90,    2,    2,    2,    2,    9,    0,    0,
+      0,   42,   42,   91,   92,    2,    2,    2,    2,    2,    2,    2,    2,   13,    9,    0,
+      0,   93,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
+      9,   22,   80,   45,   22,   94,   61,    0,    0,   95,   96,   95,   95,   97,   98,    0,
+      0,    2,    2,    2,    2,    2,    2,    2,    0,    2,    2,    9,    0,    0,    0,    0,
+      0,    2,    2,    2,    2,    2,    2,    0,    0,    2,    2,    2,    2,   29,    0,    0,
+      0,    2,    2,    2,    2,    2,    9,    0,    0,    2,    2,    2,   52,   99,   45,    0,
+      0,    2,    2,  100,  101,  102,  103,   61,   63,  104,   16,   45,   22,   59,   21,   80,
+     48,   48,   76,   11,   11,   11,  105,   46,   40,   11,  106,   74,    2,    2,    2,    2,
+      2,    2,    2,  107,   22,   20,   20,   22,   48,   48,   22,  108,    2,    2,    2,    9,
+      0,    0,    0,    0,    0,    0,  109,  110,  111,  111,  111,    0,    0,    0,    0,    0,
+      0,  106,   74,    2,    2,    2,    2,    2,    2,   60,   61,   59,   25,   22,  112,   61,
+      2,    2,    2,    2,  107,   22,   23,   45,   45,  102,   14,    0,    0,    0,    0,    0,
+      0,    2,    2,   61,   18,   48,   23,  113,  102,  102,  102,  114,  115,    0,    0,    0,
+      0,    2,    2,    2,    2,    2,    0,   30,    2,   11,   46,  116,  116,  116,   11,  116,
+    116,   15,  116,  116,  116,   26,    0,   40,    0,    0,    0,  117,   51,   11,    5,    0,
+      0,    0,    0,    0,    0,    0,  118,    0,    0,    0,    0,    0,    0,    0,    6,  119,
+    120,   42,   42,    5,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,  120,  120,
+    121,  120,  120,  120,  120,  120,  120,  120,  120,    0,    0,  122,    0,    0,    0,    0,
+      0,    0,    7,  122,    0,    0,    0,    0,    0,   46,    0,    0,    0,    0,    0,    0,
+      0,    0,    0,    0,    0,    0,    0,    9,    0,    0,    0,    0,  123,  123,    0,    0,
+      0,    2,    2,    2,    2,    0,    0,    0,   30,    0,    0,    0,    0,    0,    0,    0,
+    124,    0,  123,  123,    0,    0,    0,    0,    0,    2,   53,    2,  108,    2,   10,    2,
+      2,    2,   65,   19,   16,    0,    0,   31,    0,    2,    2,    0,    0,    0,    0,    0,
+      0,   29,    2,    2,    2,    2,    2,    2,    2,    2,    2,  125,   23,   23,   23,   23,
+     23,   23,   23,  126,    0,    0,    0,    0,    0,   11,   11,   11,   11,   11,   11,   11,
+     11,   11,    2,    0,    0,    0,    0,    0,   52,    2,    2,    2,   22,   22,  127,  116,
+      0,    2,    2,    2,  128,   20,   59,   20,  113,  102,  129,    0,    0,    0,    0,    0,
+      0,   11,  130,    2,    2,    2,    2,    2,    2,    2,  131,   23,   22,   20,   48,  132,
+    133,  134,    0,    0,    0,    0,    0,    0,    0,    2,    2,   52,   30,    2,    2,    2,
+      2,    2,    2,    2,    2,   10,   22,   59,   99,   76,  135,  136,  137,    0,    0,    0,
+      0,    2,  138,    2,    2,    2,    2,  139,    0,   30,    2,   42,    5,    0,   79,   15,
+      2,   53,   22,  140,   52,   53,    2,    2,  105,   10,    9,    0,    0,    0,    0,    0,
+      0,    2,    2,    2,    2,    2,  141,   21,   25,    0,    0,  142,  143,    0,    0,    0,
+      0,    2,   65,   45,   23,   80,   47,  144,    0,   81,   81,   81,   81,   81,   81,   81,
+     81,    0,    0,    0,    0,    0,    0,    0,    6,  120,  120,  120,  120,  121,    0,    0,
+      0,    2,    2,    2,    2,    2,    9,    2,    2,    2,    9,    2,   30,    2,    2,    2,
+      2,    2,   30,    2,    2,    2,   30,    9,    0,  128,   20,   27,   31,    0,    0,  145,
+    146,    2,    2,   30,    2,   30,    2,    2,    2,    2,    2,    2,    0,   14,   37,    0,
+    147,    2,    2,   13,   37,    0,   30,    2,    2,    2,    0,    0,    0,    0,    0,    0,
+      0,    0,    0,    0,    0,   30,    2,    2,    9,    2,    2,   11,   41,    0,    0,    0,
+      0,    2,    2,    2,    2,    2,   27,   38,    0,    2,    2,    2,  116,  116,  116,  116,
+    116,  148,    2,    9,    0,    0,    0,    0,    0,    2,   14,   14,    0,    0,    0,    0,
+      0,    9,    2,    2,    9,    2,    2,    2,    2,   30,    2,    9,    0,   30,    2,    0,
+      0,  149,  150,  151,    2,    2,    2,    2,    2,    2,    2,    2,    2,   22,   22,   20,
+     20,   20,   22,   22,  134,    0,    0,    0,    0,    0,  152,  152,  152,  152,  152,  152,
+    152,  152,  152,  152,    2,    2,    2,    2,    2,   53,   52,   53,    0,    0,    0,    0,
+    153,   11,   74,    2,    2,    2,    2,    2,    2,   18,   19,   21,   16,   24,   37,    0,
+      0,    0,   31,    0,    0,    0,    0,    0,    0,   11,   49,    2,    2,    2,    2,    2,
+      2,    2,    2,    2,  128,   20,   22,  154,   22,   21,  155,  156,    2,    2,    2,    2,
+      2,    0,    0,   65,  157,    0,    0,    0,    0,    2,   13,    0,    0,    0,    0,    0,
+      0,    2,   65,   25,   20,   20,   20,   22,   22,  108,  158,    0,    0,   56,  159,   31,
+    160,   30,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,   23,
+     19,   22,   22,  161,   44,    0,    0,    0,   49,  128,    0,    0,    0,    0,    0,    0,
+      0,    2,    2,    2,    9,    9,    2,    2,   30,    2,    2,    2,    2,    2,    2,    2,
+     30,    2,    2,    2,    2,    2,    2,    2,   10,   18,   19,   21,   22,  162,   31,    0,
+      0,   11,   11,   30,    2,    2,    2,    9,   30,    9,    2,   30,    2,    2,   58,   17,
+     23,   16,   23,   47,   32,   33,   32,   34,    0,    0,    0,    0,   35,    0,    0,    0,
+      2,    2,   23,    0,   11,   11,   11,   46,    0,   11,   11,   46,    0,    0,    0,    0,
+      0,    2,    2,   65,   25,   20,   20,   20,   22,   23,  126,   15,   17,    0,    0,    0,
+      0,    2,    2,    2,    2,    2,    0,    0,  163,  164,    0,    0,    0,    0,    0,    0,
+      0,   18,   19,   20,   20,   66,   99,   25,  160,   11,  165,    9,    0,    0,    0,    0,
+      0,    2,    2,    2,    2,    2,    2,    2,   65,   25,   20,   20,    0,   48,   48,   11,
+    166,   37,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    2,    2,   20,
+      0,   23,   19,   20,   20,   21,   16,   82,  166,   38,    0,    0,    0,    0,    0,    0,
+      0,    2,    2,    2,    2,    2,   10,  167,   25,   20,   22,   22,  165,    9,    0,    0,
+      0,    2,    2,    2,    2,    2,    9,   43,  136,   23,   22,   20,   76,   21,   22,    0,
+      0,    2,    2,    2,    9,    0,    0,    0,    0,    2,    2,    2,    2,    2,    2,   18,
+     19,   20,   21,   22,  105,  166,   37,    0,    0,    2,    2,    2,    9,   30,    0,    2,
+      2,    2,    2,   30,    9,    2,    2,    2,    2,   23,   23,   18,   32,   33,   12,  168,
+    169,  170,  171,    0,    0,    0,    0,    0,    0,    2,    2,    2,    2,    0,    2,    2,
+      2,   65,   25,   20,   20,    0,   22,   23,   29,  108,    0,   33,    0,    0,    0,    0,
+      0,   52,   20,   22,   22,   22,  140,    2,    2,    2,  172,  173,   11,   15,  174,   72,
+    175,    0,    0,    1,  147,    0,    0,    0,    0,   52,   20,   22,   16,   19,   20,    2,
+      2,    2,    2,  158,  158,  158,  176,  176,  176,  176,  176,  176,   15,  177,    0,   30,
+      0,   22,   20,   20,   31,   22,   22,   11,  166,    0,   61,   61,   61,   61,   61,   61,
+     61,   66,   21,   82,   46,    0,    0,    0,    0,    2,    2,    2,    9,    2,   30,    2,
+      2,   52,   22,   22,   31,    0,   38,   22,   27,   11,  159,  178,  174,    0,    0,    0,
+      0,    2,    2,    2,   30,    9,    2,    2,    2,    2,    2,    2,    2,    2,   23,   23,
+     47,   22,   35,   82,   68,    0,    0,    0,    0,    2,  179,   66,   47,    0,    0,    0,
+      0,   11,  180,    2,    2,    2,    2,    2,    2,    2,    2,   23,   22,   20,   31,    0,
+     48,   16,  143,    0,    0,    0,    0,    0,    0,  181,  181,  181,  181,  181,  181,  181,
+    181,  182,  182,  182,  183,  184,  182,  181,  181,  185,  181,  181,  186,  187,  187,  187,
+    187,  187,  187,  187,    0,    0,    0,    0,    0,   11,   11,   11,   46,    0,    0,    0,
+      0,    2,    2,    2,    2,    2,    9,    0,   58,  188,   20,   20,   20,   20,   20,   20,
+     20,   20,   20,   20,   20,   20,   20,   20,   20,   20,   20,   20,   20,    0,    0,    0,
+     40,  116,   26,    0,    0,    0,    0,    0,    0,    0,    0,    9,    0,    0,    0,    0,
+      0,    2,    2,    2,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,    0,   58,
+     37,    0,    6,  120,  120,  120,  121,    0,    0,   11,   11,   11,   49,    2,    2,    2,
       0,    2,    2,    2,    2,    2,    0,    0,    2,    2,    2,    2,    2,    2,    2,    2,
-     44,    2,    2,    2,    2,    2,    2,    9,    9,    2,    2,    2,    2,    2,    2,   20,
-     20,    2,    2,   42,   42,   42,   90,    0,    0,    O,    O,    O,   GB,    B,    B,   GB,
-      O,    O,   WJ,FMPst,FMPst,    O,  CGJ,    B,    O,    B,VMAbv,VMAbv,VMAbv,    O,VMAbv,    B,
-  CMBlw,CMBlw,CMBlw,VMAbv,VMPst, VAbv, VPst,CMBlw,    B, VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw,
-   VAbv, VAbv, VAbv, VPst, VPst, VPst,    H, VPre, VPst,VMBlw,    O,    O, VAbv,   GB,VMAbv,VMPst,
-  VMPst,    O,    B, VBlw,    O,    O, VPre, VPre,    O, VPre,    H,    O, VPst,FMAbv,    O,CMBlw,
-      O, VAbv,    O, VAbv,    H,    O,VMBlw,VMAbv,CMAbv,   GB,   GB,    O, MBlw,CMAbv,CMAbv, VPst,
-   VAbv,VMAbv,    O, VPst,    O, VPre, VPre,VMAbv,    B,    O,   CS,   CS,VMPst,    B, VAbv, VAbv,
-      B,    R,    O,  HVM,    O,    O,FMBlw,    O,CMAbv,    O,CMBlw, VAbv, VBlw,    B,  SUB,  SUB,
-    SUB,    O,  SUB,  SUB,    O,FMBlw,    O,    B, VPst, VBlw, VPre,VMAbv,VMBlw,VMPst,   IS, VAbv,
-   MPst, MPre, MBlw, MBlw,    B, MBlw, MBlw, VPst,VMPst,VMPst,    B, MBlw, VPst, VPre, VAbv, VAbv,
-  VMPst,VMPst,VMBlw,    B,VMPst, VBlw, VPst,  CGJ,  CGJ, VPst,VMAbv,VMAbv,FMAbv, FAbv,CMAbv,FMAbv,
-  VMAbv,FMAbv, VAbv,   IS,FMAbv,    B,FMAbv,    B,  CGJ,   WJ,  CGJ,   GB,CMAbv,CMAbv,    B,   GB,
-      B, VAbv,  SUB, FPst, FPst,VMBlw, FPst, FPst, FBlw,VMAbv,FMBlw, VAbv, VPre,    B, MPre, MBlw,
-    SUB, FAbv, FAbv, MAbv,  SUB,   Sk, VPst, VAbv,VMAbv,VMAbv, FAbv,CMAbv, VPst,    H,    B,    O,
-  SMAbv,SMBlw,SMAbv,SMAbv,SMAbv, VPst,   IS, VBlw, FAbv,VMPre,VMPre,FMAbv,CMBlw,VMBlw,VMBlw,VMAbv,
-     CS,    O,FMAbv, ZWNJ,  CGJ,   WJ,   WJ,   WJ,    O,FMPst,    O,    O,    H, MPst, VPst,    H,
-  VMAbv, VAbv,VMBlw,    B, VBlw, FPst, VPst, FAbv,VMPst,    B,CMAbv, VAbv, MBlw, MPst, MBlw,    H,
-      O, VBlw, MPst, MPre, MAbv, MBlw,    O,    B, FAbv, FAbv, FPst, VBlw,    B,    B, VPre,    O,
-  VMPst,   IS,    O,VMPst, VBlw, VPst,VMBlw,VMBlw,VMAbv,    O,   IS,VMBlw,    B,VMPst,VMAbv,VMPst,
-     CS,   CS,    B,    N,    N,    O,   HN, VPre, VBlw, VAbv,   IS,CMAbv,    O, VPst,    B,    R,
-      R,CMBlw, VAbv, VPre,VMAbv,VMAbv,    H, VAbv,CMBlw,FMAbv,    B,   CS,   CS,    H,CMBlw,VMPst,
-      H,VMPst, VAbv,VMAbv, VPst,   IS,    R, MPst,    R, MPst,CMBlw,    B,FMBlw, VBlw,VMAbv,    R,
-   MBlw, MBlw,   GB, FBlw, FBlw,CMAbv,   IS, VBlw,   IS,   GB, VAbv,    R,VMPst,    H,    H,    B,
-      H,    B,VMBlw,    O, VBlw,
+     46,    2,    2,    2,    2,    2,    2,   11,   11,    2,    2,    2,    2,    2,    2,   22,
+     22,    2,    2,   44,   44,   44,   92,    0,    0,    O,    O,    O,   GB,    B,    B,    O,
+     SB,    O,   SE,   GB,    O,    O,   WJ,FMPst,FMPst,    O,  CGJ,    B,    O,    B,VMAbv,VMAbv,
+  VMAbv,    O,VMAbv,    B,CMBlw,CMBlw,CMBlw,VMAbv,VMPst, VAbv, VPst,CMBlw,    B, VPst, VPre, VPst,
+   VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VPst, VPst, VPst,    H, VPre, VPst,VMBlw,    O,    O,
+   VAbv,   GB,VMAbv,VMPst,VMPst,    O,    B, VBlw,    O,    O, VPre, VPre,    O, VPre,    H,    O,
+   VPst,FMAbv,    O,CMBlw,    O, VAbv,    O, VAbv,    H,    O,VMBlw,VMAbv,CMAbv,   GB,   GB,    O,
+   MBlw,CMAbv,CMAbv, VPst, VAbv,VMAbv,    O, VPst,    O, VPre, VPre,VMAbv,    B,    O,   CS,   CS,
+  VMPst,    B, VAbv, VAbv,    B,    R,    O,  HVM,    O,    O,FMBlw,    O,CMAbv,    O,CMBlw, VAbv,
+   VBlw,    B,  SUB,  SUB,  SUB,    O,  SUB,  SUB,    O,FMBlw,    O,    B, VPst, VBlw, VPre,VMAbv,
+  VMBlw,VMPst,   IS, VAbv, MPst, MPre, MBlw, MBlw,    B, MBlw, MBlw, VPst,VMPst,VMPst,    B, MBlw,
+   VPst, VPre, VAbv, VAbv,VMPst,VMPst,VMBlw,    B,VMPst, VBlw, VPst,  CGJ,  CGJ, VPst,VMAbv,VMAbv,
+  FMAbv, FAbv,CMAbv,FMAbv,VMAbv,FMAbv, VAbv,   IS,FMAbv,    B,FMAbv,    B,  CGJ,   WJ,  CGJ,   GB,
+  CMAbv,CMAbv,    B,   GB,    B, VAbv,  SUB, FPst, FPst,VMBlw, FPst, FPst, FBlw,VMAbv,FMBlw, VAbv,
+   VPre,    B, MPre, MBlw,  SUB, FAbv, FAbv, MAbv,  SUB,   Sk, VPst, VAbv,VMAbv,VMAbv, FAbv,CMAbv,
+   VPst,    H,    B,    O,SMAbv,SMBlw,SMAbv,SMAbv,SMAbv, VPst,   IS, VBlw, FAbv,VMPre,VMPre,FMAbv,
+  CMBlw,VMBlw,VMBlw,VMAbv,   CS,    O,FMAbv, ZWNJ,  CGJ,   WJ,   WJ,   WJ,    O,FMPst,    O,   SB,
+     SE,    O,    H, MPst, VPst,    H,VMAbv, VAbv,VMBlw,    B, VBlw, FPst, VPst, FAbv,VMPst,    B,
+  CMAbv, VAbv, MBlw, MPst, MBlw,    H,    O, VBlw, MPst, MPre, MAbv, MBlw,    O,    B, FAbv, FAbv,
+   FPst, VBlw,    B,    B, VPre,    O,VMPst,   IS,    O,VMPst, VBlw, VPst,VMBlw,VMBlw,VMAbv,    O,
+     IS,VMBlw,    B,VMPst,VMAbv,VMPst,   CS,   CS,    B,    N,    N,    O,   HN, VPre, VBlw, VAbv,
+     IS,CMAbv,    O, VPst,    B,    R,    R,CMBlw, VAbv, VPre,VMAbv,VMAbv,    H, VAbv,CMBlw,FMAbv,
+      B,   CS,   CS,    H,CMBlw,VMPst,    H,VMPst, VAbv,VMAbv, VPst,   IS,    R, MPst,    R, MPst,
+  CMBlw,    B,FMBlw, VBlw,VMAbv,    R, MBlw, MBlw,   GB, FBlw, FBlw,CMAbv,   IS, VBlw,   IS,   GB,
+   VAbv,    R,VMPst,    G,    G,    J,    J,    J,   SB,   SE,    J,   HR,    G,    G,   HM,   HM,
+     HM,    O, VBlw,
 };
 static const uint16_t
-hb_use_u16[784] =
+hb_use_u16[808] =
 {
-    0,  0,  1,  2,  0,  0,  0,  0,  0,  0,  3,  4,  0,  5,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  6,  0,  0,  0,
-    0,  0,  0,  0,  7,  0,  0,  0,  0,  0,  0,  0,  8,  9, 10, 11,
-    0,  0,  0,  0,  9, 12,  0,  0, 13,  9,  9, 14, 15, 16, 17, 18,
-   19, 20, 21, 22, 23, 24, 17, 25, 26, 20, 21, 27, 28, 29, 30, 31,
-   32, 33, 21, 34, 35,  0, 17, 36, 37, 20, 21, 38, 23, 39, 17, 40,
-   41, 42, 43, 44, 45, 46, 30,  0, 47, 48, 21, 49, 50, 51, 17,  0,
-   52, 48, 21, 53, 50, 54, 17, 55, 56, 48,  9, 57, 58, 59, 17,  0,
-   60, 61,  9, 62, 63, 64, 30, 65, 66, 67,  9, 68, 69,  9, 70, 71,
-   72, 73, 74, 75, 76,  0,  0,  0,  9,  9, 77, 78, 79, 80, 81, 82,
-   83, 84,  0,  0,  0,  0,  0,  0,  9, 85,  9, 86,  9, 87, 88, 89,
-    9,  9,  9, 90, 91, 92,  2,  0, 93,  0,  9,  9,  9,  9,  9, 94,
-   95,  9, 96,  0,  0,  0,  0,  0, 97, 98, 99,100, 30,  9,101,102,
-    9,  9,103,  9,104,105,  0,  0,  9,106,  9,  9,  9,107,108,109,
-    2,  2,  0,  0,  0,  0,  0,  0,110,  9,  9,111,112,  2,113,114,
-  115,  9,116,  9,  9,  9,117,118,  9,  9,119,120,121,  0,  0,  0,
-    0,  0,  0,  0,  0,122,123,124,  0,  0,  0,  0,  0,  0,  0,125,
-  126,127,128,  0,  0,  0,129,130,131,  0,  0,  0,  0,  0,  0,132,
-    0,  0,  0,  0,133,  0,  0,  0,  0,  0,  0,  9,  9,  9,134,135,
-  136,  9,137,  0,  9,  9,  9,138,139,  9,  9,140,141,  2,142,143,
-    9,  9,144,  9,145,146,  0,  0,147,  9,  9,148,149,  2,150, 98,
-    9,  9,151,152,153,  2,  9,154,  9,  9,  9,155,156,  0,157,158,
-    0,  0,  0,  0,  9,  9,159,  2,160,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,161,  0,  0,  0,  0,  0,  0,  0,162,
-    0,  0,  0,  0,  0,  0,  0,163,163,164, 33,165,  0,  0,  0,  0,
-  166,167,  9,168, 94,  0,  0,  0,  0,  0,  0,  0, 69,  9,169,  0,
-    9,170,171,  0,  0,  0,  0,  0,  9,  9,172,  2,  0,  0,  0,  0,
-    9,  9,173,170,  0,  0,  0,  0,  0,  0,  0,  9,174,175,  0,  9,
-  176,  0,  0,177,178,  0,  0,  0,179,  9,  9,180,181,182,183,184,
-  185,  9,  9,186,187,  0,  0,  0,188,  9,189,190,191,  9,  9,192,
-  185,  9,  9,193,194,105,195,102,  9, 33,196,197,198,  0,  0,  0,
-  199,200, 94,  9,  9,201,202,  2,203, 20, 21,204,205,206,207,208,
-    9,  9,  9,209,210,211,212,  0,195,  9,  9,213,214,  2,  0,  0,
-    9,  9,215,216,217,218,  0,  0,  9,  9,  9,219,220,  2,  0,  0,
-    9,  9,221,222,  2,  0,  0,  0,  9,223,224,103,225,  0,  0,  0,
-    9,  9,226,227,  0,  0,  0,  0,228,229,  9,230,231,  2,  0,  0,
-    0,  0,232,  9,  9,233,234,  0,235,  9,  9,236,237,238,  9,  9,
-  239,240,  0,  0,  0,  0,  0,  0, 21,  9,215,241,  7,  9, 70, 18,
-    9,242, 73,243,  0,  0,  0,  0,244,  9,  9,245,246,  2,247,  9,
-  248,249,  2,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  9,250,
-  251, 48,  9,252,253,  2,  0,  0,  9,  9,  9,  9,  9,  9,  9,  9,
-    9,  9,  9,254,255,256,  0,  0,  0,  0,  0,  0,  2,  0,  0,  0,
-    9,  9,  9,257,  0,  0,  0,  0,  9,  9,  9,  9,258,259,260,260,
-  261,262,  0,  0,  0,  0,263,  0,  9,  9,  9,  9,  9,264,  0,  0,
-    9,  9,  9,  9,  9,  9,105, 70, 94,265,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,266,  9,  9, 70,267,268,  0,  0,  0,
-    0,  9,269,  0,  9,  9,270,  2,  0,  0,  0,  0,  0,  9,271,  2,
-    9,  9,  9,  9,272,  2,  0,  0,129,129,129,129,129,129,129,129,
-  160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,129,
+    0,  0,  1,  2,  0,  3,  0,  3,  0,  0,  4,  5,  0,  6,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  7,  0,  0,  0,
+    0,  0,  0,  0,  8,  0,  0,  0,  0,  0,  0,  0,  9, 10, 11, 12,
+    0,  0,  0,  0, 10, 13,  0,  0, 14, 10, 10, 15, 16, 17, 18, 19,
+   20, 21, 22, 23, 24, 25, 18, 26, 27, 21, 22, 28, 29, 30, 31, 32,
+   33, 34, 22, 35, 36,  0, 18, 37, 38, 21, 22, 39, 24, 40, 18, 41,
+   42, 43, 44, 45, 46, 47, 31,  0, 48, 49, 22, 50, 51, 52, 18,  0,
+   53, 49, 22, 54, 51, 55, 18, 56, 57, 49, 10, 58, 59, 60, 18,  0,
+   61, 62, 10, 63, 64, 65, 31, 66, 67, 68, 10, 69, 70, 10, 71, 72,
+   73, 74, 75, 76, 77,  0,  0,  0, 10, 10, 78, 79, 80, 81, 82, 83,
+   84, 85,  0,  0,  0,  0,  0,  0, 10, 86, 10, 87, 10, 88, 89, 90,
+   10, 10, 10, 91, 92, 93,  2,  0, 94,  0, 10, 10, 10, 10, 10, 95,
+   96, 10, 97,  0,  0,  0,  0,  0, 98, 99,100,101, 31, 10,102,103,
+   10, 10,104, 10,105,106,  0,  0, 10,107, 10, 10, 10,108,109,110,
+    2,  2,  0,  0,  0,  0,  0,  0,111, 10, 10,112,113,  2,114,115,
+  116, 10,117, 10, 10, 10,118,119, 10, 10,120,121,122,  0,  0,  0,
+    0,  0,  0,  0,  0,123,124,125,  0,  0,  0,  0,  0,  0,  0,126,
+  127,128,129,  0,  0,  0,130,131,132,  0,  0,  0,  0,  0,  0,133,
+    0,  0,  0,  0,134,  0,  0,  0,  0,  0,  0,  0,  0,  0,135,  0,
+    0,  0,  0, 10, 10, 10,136,137,  0,  0,138,  0,  0,  0,  0,  0,
+  139, 10,140,  0, 10, 10, 10,141,142, 10, 10,143,144,  2,145,146,
+   10, 10,147, 10,148,149,  0,  0,150, 10, 10,151,152,  2,153, 99,
+   10, 10,154,155,156,  2, 10,157, 10, 10, 10,158,159,  0,160,161,
+    0,  0,  0,  0, 10, 10,162,  2,163,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,164,  0,  0,  0,  0,  0,  0,  0,165,
+    0,  0,  0,  0,  0,  0,  0,166,166,167, 34,168,  0,  0,  0,  0,
+  169,170, 10,171, 95,  0,  0,  0,  0,  0,  0,  0, 70, 10,172,  0,
+   10,173,174,  0,  0,  0,  0,  0, 10, 10,175,  2,  0,  0,  0,  0,
+   10, 10,176,173,  0,  0,  0,  0,  0,  0,  0, 10,177,178,  0, 10,
+  179,  0,  0,180,181,  0,  0,  0,182, 10, 10,183,184,185,186,187,
+  188, 10, 10,189,190,  0,  0,  0,191, 10,192,193,194, 10, 10,195,
+  188, 10, 10,196,197,106,198,103, 10, 34,199,200,201,  0,  0,  0,
+  202,203, 95, 10, 10,204,205,  2,206, 21, 22,207,208,209,210,211,
+   10, 10, 10,212,213,214,215,  0,198, 10, 10,216,217,  2,  0,  0,
+   10, 10,218,219,220,221,  0,  0, 10, 10, 10,222,223,  2,  0,  0,
+   10, 10,224,225,  2,  0,  0,  0, 10,226,227,104,228,  0,  0,  0,
+   10, 10,229,230,  0,  0,  0,  0,231,232, 10,233,234,  2,  0,  0,
+    0,  0,235, 10, 10,236,237,  0,238, 10, 10,239,240,241, 10, 10,
+  242,243,  0,  0,  0,  0,  0,  0, 22, 10,218,244,  8, 10, 71, 19,
+   10,245, 74,246,  0,  0,  0,  0,247, 10, 10,248,249,  2,250, 10,
+  251,252,  2,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 10,253,
+  254, 49, 10,255,256,  2,  0,  0,257,257,257,257,257,257,257,257,
+  257,257,257,258,259,260,  0,  0,  0,  0,  0,  0,  2,  0,  0,  0,
+   10, 10, 10,261,  0,  0,  0,  0, 10, 10, 10, 10,262,263,264,264,
+  265,266,  0,  0,  0,  0,267,  0, 10, 10, 10, 10, 10, 10, 10, 10,
+   10, 10, 10, 10, 10,268,  0,  0, 10, 10, 10, 10, 10, 10,106, 71,
+   95,269,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,270,
+   10, 10, 71,271,272,  0,  0,  0,  0, 10,273,  0, 10, 10,274,  2,
+    0,  0,  0,  0,  0, 10,275,  2, 10, 10, 10, 10,276,  2,  0,  0,
+  130,130,130,130,130,130,130,130,163,163,163,163,163,163,163,163,
+  163,163,163,163,163,163,163,130,
 };
 
 static inline unsigned
@@ -357,14 +366,14 @@
 static inline uint_fast8_t
 hb_use_get_category (unsigned u)
 {
-  return u<921600u?hb_use_u8[2777+(((hb_use_u8[593+(((hb_use_u16[((hb_use_u8[113+(((hb_use_b4(hb_use_u8,u>>1>>3>>3>>5))<<5)+((u>>1>>3>>3)&31u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:O;
+  return u<921600u?hb_use_u8[2809+(((hb_use_u8[593+(((hb_use_u16[((hb_use_u8[113+(((hb_use_b4(hb_use_u8,u>>1>>3>>3>>5))<<5)+((u>>1>>3>>3)&31u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:O;
 }
 
 
 #else
 
 static const uint8_t
-hb_use_u8[3413] =
+hb_use_u8[3483] =
 {
      16,   50,   51,   51,   51,   52,   51,   83,  118,  131,   51,   57,   58,  179,  195,   61,
      51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,
@@ -375,243 +384,248 @@
      51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,   51,
      14,    0,    1,    1,    2,    1,    1,    3,    4,    5,    6,    7,    8,    9,   10,    1,
      11,   12,    1,    1,    1,    1,    1,    1,   13,   14,   15,   16,   17,   18,   19,    1,
-      1,   20,    1,    1,    1,    1,   21,    1,    1,    1,    1,    1,    1,    1,   22,    1,
+      1,   20,    1,    1,    1,    1,   21,    1,   22,    1,    1,    1,    1,    1,   23,   24,
       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,   23,   24,   25,   26,    1,    1,    1,
-      1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,   27,
-     28,    1,    1,    1,    1,    1,   29,    1,    1,    1,    1,   30,   31,    1,   32,   33,
-     34,   35,   36,   37,   38,   39,   40,   41,   42,   43,   44,   45,    1,   46,   47,   48,
-     49,   50,   50,   50,   50,   51,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-      1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,   52,   53,    1,    1,    1,
-     54,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,   50,   55,    1,    1,
-      1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,   56,    1,    1,
-      1,    1,   57,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-      1,    1,   58,   59,    1,   60,    1,    1,    1,    1,   61,    1,    1,    1,    1,    1,
-      1,   62,   63,   62,   62,   62,   62,   62,   62,   62,   62,   62,   62,   62,   62,   62,
-     62,    0,    1,    0,    0,    0,    2,    3,    0,    0,    0,    0,    0,    0,    0,    0,
-      0,    0,    0,    4,    0,    0,    0,    0,    0,    0,    0,    5,    0,    0,    0,    0,
-      0,    0,    0,    0,    0,    0,    0,    6,    7,    0,    0,    8,    0,    0,    0,    0,
-      0,    9,   10,   11,   12,   13,   14,   15,   16,   17,   18,   19,   20,   21,   22,   23,
-     24,   25,   26,   27,   28,   29,   30,   31,   32,   33,   34,   35,   36,   37,   38,   39,
-     40,   41,   42,   43,   36,   44,   45,   46,   47,   48,   49,   50,   51,   52,   53,   54,
-      0,   55,   56,   57,   58,   59,    0,    0,    0,   60,   61,   62,   63,   55,   64,   65,
-     66,   67,   55,   55,   68,   69,   70,    0,    0,   71,   72,   73,   74,   55,   75,   76,
-      0,   77,   55,   78,   79,   80,    0,    0,    0,   81,   82,   83,   84,   85,   86,   55,
-     87,   55,   88,   89,    0,    0,    0,   90,   91,    0,    0,    0,    0,    0,    0,    0,
-     92,   93,   94,    0,   95,   96,    0,    0,   97,    0,    0,    0,    0,    0,    0,   98,
-      0,    0,   99,   55,  100,    0,    0,    0,    0,  101,  102,   55,  103,  104,  105,  106,
-    107,   55,  108,  109,    0,  110,  111,  112,  113,   55,  114,  115,  116,   55,  117,  118,
-    119,    0,    0,    0,    0,    0,    0,   55,  120,  121,    0,    0,    0,    0,    0,    0,
-    122,    0,    0,    0,    0,    0,    0,    0,  123,    0,    0,    0,  124,  125,  126,    0,
-      0,  127,  128,  129,    0,    0,    0,   50,  130,    0,    0,    0,    0,  131,  132,    0,
-      0,   55,  133,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,   55,  134,    0,
-      0,    0,   99,  135,   99,  136,  137,  138,    0,  139,  140,  141,  142,  143,  144,  145,
-      0,  146,  147,  148,  149,  143,  150,  151,  152,  153,  154,  155,    0,  156,  157,  158,
-    159,  160,  161,  162,  163,    0,    0,    0,    0,   55,  164,  165,  166,  167,  168,  169,
-      0,    0,    0,    0,    0,   55,  170,  171,    0,   55,  172,  173,    0,   55,  174,   66,
-      0,  175,  176,  177,    0,    0,    0,    0,    0,   55,  178,    0,    0,    0,    0,    0,
-      0,  179,  180,  181,    0,    0,  182,  183,  184,  185,  186,  187,   55,  188,    0,    0,
-      0,  189,  190,  191,  192,  193,  194,    0,    0,  195,  196,  197,  198,  199,   66,    0,
-      0,    0,    0,    0,    0,    0,    0,    0,  200,  201,  202,  203,    0,    0,    0,    0,
-      0,   55,   55,   55,   55,   55,   55,   55,   55,   55,  204,  205,    0,    0,    0,    0,
-      0,    0,    0,    0,    0,    0,    0,   66,    0,   55,  206,    0,    0,    0,    0,    0,
-      0,   55,   55,  207,  208,  209,    0,    0,  210,   55,   55,   55,   55,   55,   55,  211,
-      0,   55,   55,   55,  212,  213,    0,    0,    0,    0,    0,    0,  214,    0,    0,    0,
-      0,   55,  215,  216,    0,    0,    0,    0,    0,    0,    0,    0,    0,   99,  217,   55,
-    218,    0,    0,    0,    0,    0,    0,   99,  219,   55,   55,  220,    0,    0,    0,    0,
-      0,  221,  221,  221,  221,  221,  221,  221,  221,  222,  222,  222,  222,  222,  222,  222,
-    223,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    1,
-      0,    2,    2,    2,    2,    2,    0,    0,    0,    3,    0,    0,    0,    0,    0,    4,
-      0,    0,    5,    0,    0,    0,    0,    0,    0,    0,    0,    0,    1,    0,    0,    0,
-      0,    0,    0,    0,    0,    0,    0,    0,    6,    7,    0,    0,    0,    0,    0,    0,
+      1,    1,    1,    1,    1,    1,    1,    1,    1,   25,   26,   27,   28,    1,    1,    1,
+      1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,   29,
+     30,    1,    1,    1,    1,    1,   31,    1,    1,    1,    1,   32,   33,    1,   34,   35,
+     36,   37,   38,   39,   40,   41,   42,   43,   44,   45,   46,   47,    1,   48,   49,   50,
+     51,   52,   52,   52,   52,   53,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+      1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,   54,   55,    1,    1,    1,
+     56,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,   57,   58,    1,    1,
+      1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,   59,    1,    1,
+      1,    1,   60,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+      1,    1,   61,   62,    1,   63,    1,    1,    1,    1,   64,    1,    1,    1,    1,    1,
+      1,   65,   66,   65,   65,   65,   65,   65,   65,   65,   65,   65,   65,   65,   65,   65,
+     65,    0,    1,    2,    2,    0,    3,    4,    0,    0,    0,    0,    0,    0,    0,    0,
+      0,    0,    0,    5,    0,    0,    0,    0,    0,    0,    0,    6,    0,    0,    0,    0,
+      0,    0,    0,    0,    0,    0,    0,    7,    8,    0,    0,    9,    0,    0,    0,    0,
+      0,   10,   11,   12,   13,   14,   15,   16,   17,   18,   19,   20,   21,   22,   23,   24,
+     25,   26,   27,   28,   29,   30,   31,   32,   33,   34,   35,   36,   37,   38,   39,   40,
+     41,   42,   43,   44,   37,   45,   46,   47,   48,   49,   50,   51,   52,   53,   54,   55,
+      0,   56,   57,   58,   59,   60,    0,    0,    0,   61,   62,   63,   64,   56,   65,   66,
+     67,   68,   56,   56,   69,   70,   71,    0,    0,   72,   73,   74,   75,   56,   76,   77,
+      0,   78,   56,   79,   80,   81,    0,    0,    0,   82,   83,   84,   85,   86,   87,   56,
+     88,   56,   89,   90,    0,    0,    0,   91,   92,    0,    0,    0,    0,    0,    0,    0,
+     93,   94,   95,    0,   96,   97,    0,    0,   98,    0,    0,    0,    0,    0,    0,   99,
+      0,    0,    0,    0,    0,    0,    0,    0,  100,    0,  101,   56,  102,    0,    0,    0,
+      0,    0,  103,    0,    0,    0,    0,    0,    0,  104,  105,   56,  106,  107,  108,  109,
+    110,   56,  111,  112,    0,  113,  114,  115,  116,   56,  117,  118,  119,   56,  120,  121,
+    122,    0,    0,    0,    0,    0,    0,   56,  123,  124,    0,    0,    0,    0,    0,    0,
+    125,    0,    0,    0,    0,    0,    0,    0,  126,    0,    0,    0,  127,  128,  129,    0,
+      0,  130,  131,  132,    0,    0,    0,   51,  133,    0,    0,    0,    0,  134,  135,    0,
+      0,   56,  136,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,   56,  137,    0,
+      0,    0,  101,  138,  101,  139,  140,  141,    0,  142,  143,  144,  145,  146,  147,  148,
+      0,  149,  150,  151,  152,  146,  153,  154,  155,  156,  157,  158,    0,  159,  160,  161,
+    162,  163,  164,  165,  166,    0,    0,    0,    0,   56,  167,  168,  169,  170,  171,  172,
+      0,    0,    0,    0,    0,   56,  173,  174,    0,   56,  175,  176,    0,   56,  177,   67,
+      0,  178,  179,  180,    0,    0,    0,    0,    0,   56,  181,    0,    0,    0,    0,    0,
+      0,  182,  183,  184,    0,    0,  185,  186,  187,  188,  189,  190,   56,  191,    0,    0,
+      0,  192,  193,  194,  195,  196,  197,    0,    0,  198,  199,  200,  201,  202,   67,    0,
+      0,    0,    0,    0,    0,    0,    0,    0,  203,  204,  205,  206,    0,    0,    0,    0,
+      0,  207,  207,  207,  207,  207,  207,  207,  207,  207,  208,  209,    0,    0,    0,    0,
+      0,    0,    0,    0,    0,    0,    0,   67,    0,   56,  210,    0,    0,    0,    0,    0,
+      0,   56,   56,  211,  212,  213,    0,    0,  214,   56,   56,   56,   56,   56,   56,   56,
+     56,   56,   56,   56,   56,   56,   56,  215,    0,   56,   56,   56,  216,  217,    0,    0,
+      0,    0,    0,    0,  218,    0,    0,    0,    0,   56,  219,  220,    0,    0,    0,    0,
+      0,    0,    0,    0,    0,  101,  221,   56,  222,    0,    0,    0,    0,    0,    0,  101,
+    223,   56,   56,  224,    0,    0,    0,    0,    0,  225,  225,  225,  225,  225,  225,  225,
+    225,  226,  226,  226,  226,  226,  226,  226,  227,    0,    0,    0,    0,    0,    0,    0,
+      0,    0,    0,    0,    0,    0,    0,    1,    0,    2,    2,    2,    2,    2,    0,    0,
+      0,    0,    0,    0,    0,    0,    3,    4,    0,    5,    0,    0,    0,    0,    0,    6,
+      0,    0,    7,    0,    0,    0,    0,    0,    0,    0,    0,    0,    1,    0,    0,    0,
+      0,    0,    0,    0,    0,    0,    0,    0,    8,    9,    0,    0,    0,    0,    0,    0,
       0,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
-      2,    2,    2,    2,    2,    2,    8,    9,    9,    9,    9,    0,    0,    0,    7,   10,
-      0,    2,    2,    2,    2,   11,   12,    0,    0,    9,   13,    2,    2,    2,    2,    2,
-      2,    2,    2,    2,    2,    2,   14,   15,   16,   17,   18,   19,   20,   14,   21,   22,
-     23,   10,   24,   25,   18,    2,    2,    2,    2,    2,   18,    0,    2,    2,    2,    2,
-      2,    0,    2,    2,    2,    2,    2,    2,    2,   26,   27,   28,    2,    2,    2,    7,
-     28,    7,   28,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    7,    2,    2,
-      2,    7,    7,    0,    2,    2,    0,   15,   16,   17,   18,   29,   30,   31,   30,   32,
-      0,    0,    0,    0,   33,    0,    0,    2,   28,    2,    0,    0,    0,    0,    0,    7,
-     34,   10,   13,   28,    2,    2,    7,    0,   28,    7,    2,   28,    7,    2,    0,   35,
-     16,   17,   29,    0,   25,   36,   25,   37,    0,   38,    0,    0,    0,   28,    2,    7,
-      7,    0,    0,    0,    2,    2,    2,    2,    2,   39,   40,   41,    0,    0,    0,    0,
-      0,   10,   13,   28,    2,    2,    2,    2,   28,    2,   28,    2,    2,    2,    2,    2,
-      2,    7,    2,   28,    2,    2,    0,   15,   16,   17,   18,   19,   25,   20,   33,   22,
-      0,    0,    0,    0,    0,   28,   39,   39,   42,   10,   27,   28,    2,    2,    2,    7,
-     28,    7,    2,   28,    2,    2,    0,   15,   43,    0,    0,   25,   20,    0,    0,    2,
-     28,   28,    0,    0,    0,    0,    0,    0,    0,    0,   44,   28,    2,    2,    7,    0,
-      2,    7,    2,    2,    0,   28,    7,    7,    2,    0,   28,    7,    0,    2,    7,    0,
-      2,    2,    2,    2,    2,    2,    0,    0,   21,   14,   45,    0,   46,   31,   46,   32,
-      0,    0,    0,    0,   33,    0,    0,    0,    0,   13,   27,   47,    2,    2,    2,    7,
-      2,    7,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    0,   15,
-     20,   14,   21,   45,   20,   36,   20,   37,    0,    0,    0,   25,   29,    2,    7,    0,
-      0,    8,   27,   28,    2,    2,    2,    7,    2,    2,    2,   28,    2,    2,    0,   15,
-     43,    0,    0,   33,   45,    0,    0,    0,    7,   48,   49,    0,    0,    0,    0,    0,
-      0,    9,   27,    2,    2,    2,    2,    7,    2,    2,    2,    2,    2,    2,   50,   51,
-     21,   21,   17,   29,   46,   31,   46,   32,   52,    0,    0,    0,   33,    0,    0,    0,
-     28,   10,   27,   28,    2,    2,    2,    2,    2,    2,    2,    2,    7,    0,    2,    2,
-      2,    2,   28,    2,    2,    2,    2,   28,    0,    2,    2,    2,    7,    0,   53,    0,
-     33,   21,   20,   29,   29,   16,   46,   46,   23,    0,   21,    0,    0,    0,    0,    0,
-      0,    2,    0,    2,    7,    0,    0,    0,    0,    0,    0,    0,    0,   18,    0,    0,
-      0,    2,    2,   54,   54,   55,    0,    0,   16,    2,    2,    2,    2,   28,    2,    2,
-      2,    2,    2,    2,    2,    2,    2,    7,    0,   56,   19,   57,   20,   20,   18,   18,
-     44,   19,    9,   29,    9,    2,    2,   58,   59,   59,   59,   59,   59,   60,   59,   59,
-     59,   59,   59,   59,   59,   59,   59,   59,   59,   59,   59,   59,   59,   59,   59,   61,
-      0,    0,    0,    0,   62,    0,    0,    0,    0,    2,    2,    2,    2,    2,   63,   43,
-     57,   64,   20,   20,   65,   66,   67,   68,   69,    2,    2,    2,    2,    2,    1,    0,
-      3,    2,    2,    2,   21,   18,    2,    2,   70,   69,   71,   72,   63,   71,   27,   27,
-      2,   50,   20,   51,    2,    2,    2,    2,    2,    2,   73,   74,   75,   27,   27,   76,
-     77,    2,    2,    2,    2,    2,   27,   43,    0,    2,   57,   78,    0,    0,    0,    0,
-     28,    2,   57,   45,    0,    0,    0,    0,    0,    2,   57,    0,    0,    0,    0,    0,
-      0,    2,    2,    2,    2,    2,    2,    7,    2,    7,   57,    0,    0,    0,    0,    0,
-      0,    2,    2,   79,   43,   20,   57,   18,   46,   46,   46,   46,   13,   80,   81,   82,
-     83,   84,   85,    0,    0,    0,    0,   86,    0,    7,    0,    0,   28,    0,   87,   79,
-     88,    2,    2,    2,    2,    7,    0,    0,    0,   40,   40,   89,   90,    2,    2,    2,
-      2,    2,    2,    2,    2,   11,    7,    0,    0,   91,    2,    2,    2,    2,    2,    2,
-      2,    2,    2,    2,    2,    2,    2,    2,    7,   20,   78,   43,   20,   92,   59,    0,
-      0,   93,   94,   93,   93,   95,   96,    0,    0,    2,    2,    2,    2,    2,    2,    2,
-      0,    2,    2,    7,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,    2,    0,
-      0,    2,    2,    2,    2,   27,    0,    0,    0,    2,    2,    2,    2,    2,    7,    0,
-      0,    2,    2,    2,   50,   97,   43,    0,    0,    2,    2,   98,   99,  100,  101,   59,
-     61,  102,   14,   43,   20,   57,   19,   78,   46,   46,   74,    9,    9,    9,  103,   44,
-     38,    9,  104,   72,    2,    2,    2,    2,    2,    2,    2,  105,   20,   18,   18,   20,
-     46,   46,   20,  106,    2,    2,    2,    7,    0,    0,    0,    0,    0,    0,  107,  108,
-    109,  109,  109,    0,    0,    0,    0,    0,    0,  104,   72,    2,    2,    2,    2,    2,
-      2,   58,   59,   57,   23,   20,  110,   59,    2,    2,    2,    2,  105,   20,   21,   43,
-     43,  100,   12,    0,    0,    0,    0,    0,    0,    2,    2,   59,   16,   46,   21,  111,
-    100,  100,  100,  112,  113,    0,    0,    0,    0,    2,    2,    2,    2,    2,    0,   28,
-      2,    9,   44,  114,  114,  114,    9,  114,  114,   13,  114,  114,  114,   24,    0,   38,
-      0,    0,    0,  115,   49,    9,    3,    0,    0,    0,    0,    0,    0,    0,  116,    0,
-      0,    0,    0,    0,    0,    0,    4,  117,  118,   40,   40,    3,    0,    0,    0,    0,
-      0,    0,    0,    0,    0,    0,  118,  118,  119,  118,  118,  118,  118,  118,  118,  118,
-    118,    0,    0,  120,    0,    0,    0,    0,    0,    0,    5,  120,    0,    0,    0,    0,
-      0,   44,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    7,
-      0,    2,    2,    2,    2,    0,    0,    0,   28,    0,    0,    0,    0,    0,    0,    0,
-    121,    2,   51,    2,  106,    2,    8,    2,    2,    2,   63,   17,   14,    0,    0,   29,
-      0,    2,    2,    0,    0,    0,    0,    0,    0,   27,    2,    2,    2,    2,    2,    2,
-      2,    2,    2,  122,   21,   21,   21,   21,   21,   21,   21,  123,    0,    0,    0,    0,
-      0,    9,    9,    9,    9,    9,    9,    9,    9,    9,    2,    0,    0,    0,    0,    0,
-     50,    2,    2,    2,   20,   20,  124,  114,    0,    2,    2,    2,  125,   18,   57,   18,
-    111,  100,  126,    0,    0,    0,    0,    0,    0,    9,  127,    2,    2,    2,    2,    2,
-      2,    2,  128,   21,   20,   18,   46,  129,  130,  131,    0,    0,    0,    0,    0,    0,
-      0,    2,    2,   50,   28,    2,    2,    2,    2,    2,    2,    2,    2,    8,   20,   57,
-     97,   74,  132,  133,  134,    0,    0,    0,    0,    2,  135,    2,    2,    2,    2,  136,
-      0,   28,    2,   40,    3,    0,   77,   13,    2,   51,   20,  137,   50,   51,    2,    2,
-    103,    8,    7,    0,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,  138,   19,
-     23,    0,    0,  139,  140,    0,    0,    0,    0,    2,   63,   43,   21,   78,   45,  141,
-      0,   79,   79,   79,   79,   79,   79,   79,   79,    0,    0,    0,    0,    0,    0,    0,
-      4,  118,  118,  118,  118,  119,    0,    0,    0,    2,    2,    2,    2,    2,    7,    2,
-      2,    2,    7,    2,   28,    2,    2,    2,    2,    2,   28,    2,    2,    2,   28,    7,
-      0,  125,   18,   25,   29,    0,    0,  142,  143,    2,    2,   28,    2,   28,    2,    2,
-      2,    2,    2,    2,    0,   12,   35,    0,  144,    2,    2,   11,   35,    0,   28,    2,
-      2,    2,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,   28,    2,    2,
-      7,    2,    2,    9,   39,    0,    0,    0,    0,    2,    2,    2,    2,    2,   25,   36,
-      0,    2,    2,    2,  114,  114,  114,  114,  114,  145,    2,    7,    0,    0,    0,    0,
-      0,    2,   12,   12,    0,    0,    0,    0,    0,    7,    2,    2,    7,    2,    2,    2,
-      2,   28,    2,    7,    0,   28,    2,    0,    0,  146,  147,  148,    2,    2,    2,    2,
-      2,    2,    2,    2,    2,   20,   20,   18,   18,   18,   20,   20,  131,    0,    0,    0,
-      0,    0,  149,  149,  149,  149,  149,  149,  149,  149,  149,  149,    2,    2,    2,    2,
-      2,   51,   50,   51,    0,    0,    0,    0,  150,    9,   72,    2,    2,    2,    2,    2,
-      2,   16,   17,   19,   14,   22,   35,    0,    0,    0,   29,    0,    0,    0,    0,    0,
-      0,    9,   47,    2,    2,    2,    2,    2,    2,    2,    2,    2,  125,   18,   20,  151,
-     20,   19,  152,  153,    2,    2,    2,    2,    2,    0,    0,   63,  154,    0,    0,    0,
-      0,    2,   11,    0,    0,    0,    0,    0,    0,    2,   63,   23,   18,   18,   18,   20,
-     20,  106,  155,    0,    0,   54,  156,   29,  157,   28,    2,    2,    2,    2,    2,    2,
-      2,    2,    2,    2,    2,    2,    2,   21,   17,   20,   20,  158,   42,    0,    0,    0,
-     47,  125,    0,    0,    0,    0,    0,    0,    0,    2,    2,    2,    7,    7,    2,    2,
-     28,    2,    2,    2,    2,    2,    2,    2,   28,    2,    2,    2,    2,    2,    2,    2,
-      8,   16,   17,   19,   20,  159,   29,    0,    0,    9,    9,   28,    2,    2,    2,    7,
-     28,    7,    2,   28,    2,    2,   56,   15,   21,   14,   21,   45,   30,   31,   30,   32,
-      0,    0,    0,    0,   33,    0,    0,    0,    2,    2,   21,    0,    9,    9,    9,   44,
-      0,    9,    9,   44,    0,    0,    0,    0,    0,    2,    2,   63,   23,   18,   18,   18,
-     20,   21,  123,   13,   15,    0,    0,    0,    0,    2,    2,    2,    2,    2,    0,    0,
-    160,  161,    0,    0,    0,    0,    0,    0,    0,   16,   17,   18,   18,   64,   97,   23,
-    157,    9,  162,    7,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,    2,    2,
-     63,   23,   18,   18,    0,   46,   46,    9,  163,   35,    0,    0,    0,    0,    0,    0,
-      0,    0,    0,    0,    0,    2,    2,   18,    0,   21,   17,   18,   18,   19,   14,   80,
-    163,   36,    0,    0,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,    8,  164,
-     23,   18,   20,   20,  162,    7,    0,    0,    0,    2,    2,    2,    2,    2,    7,   41,
-    133,   21,   20,   18,   74,   19,   20,    0,    0,    2,    2,    2,    7,    0,    0,    0,
-      0,    2,    2,    2,    2,    2,    2,   16,   17,   18,   19,   20,  103,  163,   35,    0,
-      0,    2,    2,    2,    7,   28,    0,    2,    2,    2,    2,   28,    7,    2,    2,    2,
-      2,   21,   21,   16,   30,   31,   10,  165,  166,  167,  168,    0,    0,    0,    0,    0,
-      0,    2,    2,    2,    2,    0,    2,    2,    2,   63,   23,   18,   18,    0,   20,   21,
-     27,  106,    0,   31,    0,    0,    0,    0,    0,   50,   18,   20,   20,   20,  137,    2,
-      2,    2,  169,  170,    9,   13,  171,   70,  172,    0,    0,    1,  144,    0,    0,    0,
-      0,   50,   18,   20,   14,   17,   18,    2,    2,    2,    2,  155,  155,  155,  173,  173,
-    173,  173,  173,  173,   13,  174,    0,   28,    0,   20,   18,   18,   29,   20,   20,    9,
-    163,    0,   59,   59,   59,   59,   59,   59,   59,   64,   19,   80,   44,    0,    0,    0,
-      0,    2,    2,    2,    7,    2,   28,    2,    2,   50,   20,   20,   29,    0,   36,   20,
-     25,    9,  156,  175,  171,    0,    0,    0,    0,    2,    2,    2,   28,    7,    2,    2,
-      2,    2,    2,    2,    2,    2,   21,   21,   45,   20,   33,   80,   66,    0,    0,    0,
-      0,    2,  176,   64,   45,    0,    0,    0,    0,    9,  177,    2,    2,    2,    2,    2,
-      2,    2,    2,   21,   20,   18,   29,    0,   46,   14,  140,    0,    0,    0,    0,    0,
-      0,  178,  178,  178,  106,  179,  178,    0,    0,  145,    2,    2,  180,  114,  114,  114,
-    114,  114,  114,  114,    0,    0,    0,    0,    0,    9,    9,    9,   44,    0,    0,    0,
-      0,    2,    2,    2,    2,    2,    7,    0,   56,  181,   18,   18,   18,   18,   18,   18,
-     18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,   18,    0,    0,    0,
-     38,  114,   24,    0,    0,    0,    0,    0,    0,    0,    0,    7,    0,    0,    0,    0,
-      0,    2,    2,    2,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,    0,   56,
-     35,    0,    4,  118,  118,  118,  119,    0,    0,    9,    9,    9,   47,    2,    2,    2,
-      0,    2,    2,    2,    2,    2,    0,    0,    2,    2,    2,    2,    2,    2,    2,    2,
-     44,    2,    2,    2,    2,    2,    2,    9,    9,    2,    2,    2,    2,    2,    2,   20,
-     20,    2,    2,   42,   42,   42,   90,    0,    0,    O,    O,    O,   GB,    B,    B,   GB,
-      O,    O,   WJ,FMPst,FMPst,    O,  CGJ,    B,    O,    B,VMAbv,VMAbv,VMAbv,    O,VMAbv,    B,
-  CMBlw,CMBlw,CMBlw,VMAbv,VMPst, VAbv, VPst,CMBlw,    B, VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw,
-   VAbv, VAbv, VAbv, VPst, VPst, VPst,    H, VPre, VPst,VMBlw,    O,    O, VAbv,   GB,VMAbv,VMPst,
-  VMPst,    O,    B, VBlw,    O,    O, VPre, VPre,    O, VPre,    H,    O, VPst,FMAbv,    O,CMBlw,
-      O, VAbv,    O, VAbv,    H,    O,VMBlw,VMAbv,CMAbv,   GB,   GB,    O, MBlw,CMAbv,CMAbv, VPst,
-   VAbv,VMAbv,    O, VPst,    O, VPre, VPre,VMAbv,    B,    O,   CS,   CS,VMPst,    B, VAbv, VAbv,
-      B,    R,    O,  HVM,    O,    O,FMBlw,    O,CMAbv,    O,CMBlw, VAbv, VBlw,    B,  SUB,  SUB,
-    SUB,    O,  SUB,  SUB,    O,FMBlw,    O,    B, VPst, VBlw, VPre,VMAbv,VMBlw,VMPst,   IS, VAbv,
-   MPst, MPre, MBlw, MBlw,    B, MBlw, MBlw, VPst,VMPst,VMPst,    B, MBlw, VPst, VPre, VAbv, VAbv,
-  VMPst,VMPst,VMBlw,    B,VMPst, VBlw, VPst,  CGJ,  CGJ, VPst,VMAbv,VMAbv,FMAbv, FAbv,CMAbv,FMAbv,
-  VMAbv,FMAbv, VAbv,   IS,FMAbv,    B,FMAbv,    B,  CGJ,   WJ,  CGJ,   GB,CMAbv,CMAbv,    B,   GB,
-      B, VAbv,  SUB, FPst, FPst,VMBlw, FPst, FPst, FBlw,VMAbv,FMBlw, VAbv, VPre,    B, MPre, MBlw,
-    SUB, FAbv, FAbv, MAbv,  SUB,   Sk, VPst, VAbv,VMAbv,VMAbv, FAbv,CMAbv, VPst,    H,    B,    O,
-  SMAbv,SMBlw,SMAbv,SMAbv,SMAbv, VPst,   IS, VBlw, FAbv,VMPre,VMPre,FMAbv,CMBlw,VMBlw,VMBlw,VMAbv,
-     CS,    O,FMAbv, ZWNJ,  CGJ,   WJ,   WJ,   WJ,    O,FMPst,    O,    O,    H, MPst, VPst,    H,
-  VMAbv, VAbv,VMBlw,    B, VBlw, FPst, VPst, FAbv,VMPst,    B,CMAbv, VAbv, MBlw, MPst, MBlw,    H,
-      O, VBlw, MPst, MPre, MAbv, MBlw,    O,    B, FAbv, FAbv, FPst, VBlw,    B,    B, VPre,    O,
-  VMPst,   IS,    O,VMPst, VBlw, VPst,VMBlw,VMBlw,VMAbv,    O,   IS,VMBlw,    B,VMPst,VMAbv,VMPst,
-     CS,   CS,    B,    N,    N,    O,   HN, VPre, VBlw, VAbv,   IS,CMAbv,    O, VPst,    B,    R,
-      R,CMBlw, VAbv, VPre,VMAbv,VMAbv,    H, VAbv,CMBlw,FMAbv,    B,   CS,   CS,    H,CMBlw,VMPst,
-      H,VMPst, VAbv,VMAbv, VPst,   IS,    R, MPst,    R, MPst,CMBlw,    B,FMBlw, VBlw,VMAbv,    R,
-   MBlw, MBlw,   GB, FBlw, FBlw,CMAbv,   IS, VBlw,   IS,   GB, VAbv,    R,VMPst,    H,    H,    B,
-      H,    B,VMBlw,    O, VBlw,
+      2,    2,    2,    2,    2,    2,   10,   11,   11,   11,   11,    0,    0,    0,    9,   12,
+      0,    2,    2,    2,    2,   13,   14,    0,    0,   11,   15,    2,    2,    2,    2,    2,
+      2,    2,    2,    2,    2,    2,   16,   17,   18,   19,   20,   21,   22,   16,   23,   24,
+     25,   12,   26,   27,   20,    2,    2,    2,    2,    2,   20,    0,    2,    2,    2,    2,
+      2,    0,    2,    2,    2,    2,    2,    2,    2,   28,   29,   30,    2,    2,    2,    9,
+     30,    9,   30,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    9,    2,    2,
+      2,    9,    9,    0,    2,    2,    0,   17,   18,   19,   20,   31,   32,   33,   32,   34,
+      0,    0,    0,    0,   35,    0,    0,    2,   30,    2,    0,    0,    0,    0,    0,    9,
+     36,   12,   15,   30,    2,    2,    9,    0,   30,    9,    2,   30,    9,    2,    0,   37,
+     18,   19,   31,    0,   27,   38,   27,   39,    0,   40,    0,    0,    0,   30,    2,    9,
+      9,    0,    0,    0,    2,    2,    2,    2,    2,   41,   42,   43,    0,    0,    0,    0,
+      0,   12,   15,   30,    2,    2,    2,    2,   30,    2,   30,    2,    2,    2,    2,    2,
+      2,    9,    2,   30,    2,    2,    0,   17,   18,   19,   20,   21,   27,   22,   35,   24,
+      0,    0,    0,    0,    0,   30,   41,   41,   44,   12,   29,   30,    2,    2,    2,    9,
+     30,    9,    2,   30,    2,    2,    0,   17,   45,    0,    0,   27,   22,    0,    0,    2,
+     30,   30,    0,    0,    0,    0,    0,    0,    0,    0,   46,   30,    2,    2,    9,    0,
+      2,    9,    2,    2,    0,   30,    9,    9,    2,    0,   30,    9,    0,    2,    9,    0,
+      2,    2,    2,    2,    2,    2,    0,    0,   23,   16,   47,    0,   48,   33,   48,   34,
+      0,    0,    0,    0,   35,    0,    0,    0,    0,   15,   29,   49,    2,    2,    2,    9,
+      2,    9,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    2,    0,   17,
+     22,   16,   23,   47,   22,   38,   22,   39,    0,    0,    0,   27,   31,    2,    9,    0,
+      0,   10,   29,   30,    2,    2,    2,    9,    2,    2,    2,   30,    2,    2,    0,   17,
+     45,    0,    0,   35,   47,    0,    0,    0,    9,   50,   51,    0,    0,    0,    0,    0,
+      0,   11,   29,    2,    2,    2,    2,    9,    2,    2,    2,    2,    2,    2,   52,   53,
+     23,   23,   19,   31,   48,   33,   48,   34,   54,    0,    0,    0,   35,    0,    0,    0,
+     30,   12,   29,   30,    2,    2,    2,    2,    2,    2,    2,    2,    9,    0,    2,    2,
+      2,    2,   30,    2,    2,    2,    2,   30,    0,    2,    2,    2,    9,    0,   55,    0,
+     35,   23,   22,   31,   31,   18,   48,   48,   25,    0,   23,    0,    0,    0,    0,    0,
+      0,    2,    0,    2,    9,    0,    0,    0,    0,    0,    0,    0,    0,   20,    0,    0,
+      0,    2,    2,   56,   56,   57,    0,    0,   18,    2,    2,    2,    2,   30,    2,    2,
+      2,    2,    2,    2,    2,    2,    2,    9,    0,   58,   21,   59,   22,   22,   20,   20,
+     46,   21,   11,   31,   11,    2,    2,   60,   61,   61,   61,   61,   61,   62,   61,   61,
+     61,   61,   61,   61,   61,   61,   61,   61,   61,   61,   61,   61,   61,   61,   61,   63,
+      0,    0,    0,    0,   64,    0,    0,    0,    0,    2,    2,    2,    2,    2,   65,   45,
+     59,   66,   22,   22,   67,   68,   69,   70,   71,    2,    2,    2,    2,    2,    1,    0,
+      5,    2,    2,    2,   23,   20,    2,    2,   72,   71,   73,   74,   65,   73,   29,   29,
+      2,   52,   22,   53,    2,    2,    2,    2,    2,    2,   75,   76,   77,   29,   29,   78,
+     79,    2,    2,    2,    2,    2,   29,   45,    0,    2,   59,   80,    0,    0,    0,    0,
+     30,    2,   59,   47,    0,    0,    0,    0,    0,    2,   59,    0,    0,    0,    0,    0,
+      0,    2,    2,    2,    2,    2,    2,    9,    2,    9,   59,    0,    0,    0,    0,    0,
+      0,    2,    2,   81,   45,   22,   59,   20,   48,   48,   48,   48,   15,   82,   83,   84,
+     85,   86,   87,    0,    0,    0,    0,   88,    0,    9,    0,    0,   30,    0,   89,   81,
+     90,    2,    2,    2,    2,    9,    0,    0,    0,   42,   42,   91,   92,    2,    2,    2,
+      2,    2,    2,    2,    2,   13,    9,    0,    0,   93,    2,    2,    2,    2,    2,    2,
+      2,    2,    2,    2,    2,    2,    2,    2,    9,   22,   80,   45,   22,   94,   61,    0,
+      0,   95,   96,   95,   95,   97,   98,    0,    0,    2,    2,    2,    2,    2,    2,    2,
+      0,    2,    2,    9,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,    2,    0,
+      0,    2,    2,    2,    2,   29,    0,    0,    0,    2,    2,    2,    2,    2,    9,    0,
+      0,    2,    2,    2,   52,   99,   45,    0,    0,    2,    2,  100,  101,  102,  103,   61,
+     63,  104,   16,   45,   22,   59,   21,   80,   48,   48,   76,   11,   11,   11,  105,   46,
+     40,   11,  106,   74,    2,    2,    2,    2,    2,    2,    2,  107,   22,   20,   20,   22,
+     48,   48,   22,  108,    2,    2,    2,    9,    0,    0,    0,    0,    0,    0,  109,  110,
+    111,  111,  111,    0,    0,    0,    0,    0,    0,  106,   74,    2,    2,    2,    2,    2,
+      2,   60,   61,   59,   25,   22,  112,   61,    2,    2,    2,    2,  107,   22,   23,   45,
+     45,  102,   14,    0,    0,    0,    0,    0,    0,    2,    2,   61,   18,   48,   23,  113,
+    102,  102,  102,  114,  115,    0,    0,    0,    0,    2,    2,    2,    2,    2,    0,   30,
+      2,   11,   46,  116,  116,  116,   11,  116,  116,   15,  116,  116,  116,   26,    0,   40,
+      0,    0,    0,  117,   51,   11,    5,    0,    0,    0,    0,    0,    0,    0,  118,    0,
+      0,    0,    0,    0,    0,    0,    6,  119,  120,   42,   42,    5,    0,    0,    0,    0,
+      0,    0,    0,    0,    0,    0,  120,  120,  121,  120,  120,  120,  120,  120,  120,  120,
+    120,    0,    0,  122,    0,    0,    0,    0,    0,    0,    7,  122,    0,    0,    0,    0,
+      0,   46,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    9,
+      0,    0,    0,    0,  123,  123,    0,    0,    0,    2,    2,    2,    2,    0,    0,    0,
+     30,    0,    0,    0,    0,    0,    0,    0,  124,    0,  123,  123,    0,    0,    0,    0,
+      0,    2,   53,    2,  108,    2,   10,    2,    2,    2,   65,   19,   16,    0,    0,   31,
+      0,    2,    2,    0,    0,    0,    0,    0,    0,   29,    2,    2,    2,    2,    2,    2,
+      2,    2,    2,  125,   23,   23,   23,   23,   23,   23,   23,  126,    0,    0,    0,    0,
+      0,   11,   11,   11,   11,   11,   11,   11,   11,   11,    2,    0,    0,    0,    0,    0,
+     52,    2,    2,    2,   22,   22,  127,  116,    0,    2,    2,    2,  128,   20,   59,   20,
+    113,  102,  129,    0,    0,    0,    0,    0,    0,   11,  130,    2,    2,    2,    2,    2,
+      2,    2,  131,   23,   22,   20,   48,  132,  133,  134,    0,    0,    0,    0,    0,    0,
+      0,    2,    2,   52,   30,    2,    2,    2,    2,    2,    2,    2,    2,   10,   22,   59,
+     99,   76,  135,  136,  137,    0,    0,    0,    0,    2,  138,    2,    2,    2,    2,  139,
+      0,   30,    2,   42,    5,    0,   79,   15,    2,   53,   22,  140,   52,   53,    2,    2,
+    105,   10,    9,    0,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,  141,   21,
+     25,    0,    0,  142,  143,    0,    0,    0,    0,    2,   65,   45,   23,   80,   47,  144,
+      0,   81,   81,   81,   81,   81,   81,   81,   81,    0,    0,    0,    0,    0,    0,    0,
+      6,  120,  120,  120,  120,  121,    0,    0,    0,    2,    2,    2,    2,    2,    9,    2,
+      2,    2,    9,    2,   30,    2,    2,    2,    2,    2,   30,    2,    2,    2,   30,    9,
+      0,  128,   20,   27,   31,    0,    0,  145,  146,    2,    2,   30,    2,   30,    2,    2,
+      2,    2,    2,    2,    0,   14,   37,    0,  147,    2,    2,   13,   37,    0,   30,    2,
+      2,    2,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,   30,    2,    2,
+      9,    2,    2,   11,   41,    0,    0,    0,    0,    2,    2,    2,    2,    2,   27,   38,
+      0,    2,    2,    2,  116,  116,  116,  116,  116,  148,    2,    9,    0,    0,    0,    0,
+      0,    2,   14,   14,    0,    0,    0,    0,    0,    9,    2,    2,    9,    2,    2,    2,
+      2,   30,    2,    9,    0,   30,    2,    0,    0,  149,  150,  151,    2,    2,    2,    2,
+      2,    2,    2,    2,    2,   22,   22,   20,   20,   20,   22,   22,  134,    0,    0,    0,
+      0,    0,  152,  152,  152,  152,  152,  152,  152,  152,  152,  152,    2,    2,    2,    2,
+      2,   53,   52,   53,    0,    0,    0,    0,  153,   11,   74,    2,    2,    2,    2,    2,
+      2,   18,   19,   21,   16,   24,   37,    0,    0,    0,   31,    0,    0,    0,    0,    0,
+      0,   11,   49,    2,    2,    2,    2,    2,    2,    2,    2,    2,  128,   20,   22,  154,
+     22,   21,  155,  156,    2,    2,    2,    2,    2,    0,    0,   65,  157,    0,    0,    0,
+      0,    2,   13,    0,    0,    0,    0,    0,    0,    2,   65,   25,   20,   20,   20,   22,
+     22,  108,  158,    0,    0,   56,  159,   31,  160,   30,    2,    2,    2,    2,    2,    2,
+      2,    2,    2,    2,    2,    2,    2,   23,   19,   22,   22,  161,   44,    0,    0,    0,
+     49,  128,    0,    0,    0,    0,    0,    0,    0,    2,    2,    2,    9,    9,    2,    2,
+     30,    2,    2,    2,    2,    2,    2,    2,   30,    2,    2,    2,    2,    2,    2,    2,
+     10,   18,   19,   21,   22,  162,   31,    0,    0,   11,   11,   30,    2,    2,    2,    9,
+     30,    9,    2,   30,    2,    2,   58,   17,   23,   16,   23,   47,   32,   33,   32,   34,
+      0,    0,    0,    0,   35,    0,    0,    0,    2,    2,   23,    0,   11,   11,   11,   46,
+      0,   11,   11,   46,    0,    0,    0,    0,    0,    2,    2,   65,   25,   20,   20,   20,
+     22,   23,  126,   15,   17,    0,    0,    0,    0,    2,    2,    2,    2,    2,    0,    0,
+    163,  164,    0,    0,    0,    0,    0,    0,    0,   18,   19,   20,   20,   66,   99,   25,
+    160,   11,  165,    9,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,    2,    2,
+     65,   25,   20,   20,    0,   48,   48,   11,  166,   37,    0,    0,    0,    0,    0,    0,
+      0,    0,    0,    0,    0,    2,    2,   20,    0,   23,   19,   20,   20,   21,   16,   82,
+    166,   38,    0,    0,    0,    0,    0,    0,    0,    2,    2,    2,    2,    2,   10,  167,
+     25,   20,   22,   22,  165,    9,    0,    0,    0,    2,    2,    2,    2,    2,    9,   43,
+    136,   23,   22,   20,   76,   21,   22,    0,    0,    2,    2,    2,    9,    0,    0,    0,
+      0,    2,    2,    2,    2,    2,    2,   18,   19,   20,   21,   22,  105,  166,   37,    0,
+      0,    2,    2,    2,    9,   30,    0,    2,    2,    2,    2,   30,    9,    2,    2,    2,
+      2,   23,   23,   18,   32,   33,   12,  168,  169,  170,  171,    0,    0,    0,    0,    0,
+      0,    2,    2,    2,    2,    0,    2,    2,    2,   65,   25,   20,   20,    0,   22,   23,
+     29,  108,    0,   33,    0,    0,    0,    0,    0,   52,   20,   22,   22,   22,  140,    2,
+      2,    2,  172,  173,   11,   15,  174,   72,  175,    0,    0,    1,  147,    0,    0,    0,
+      0,   52,   20,   22,   16,   19,   20,    2,    2,    2,    2,  158,  158,  158,  176,  176,
+    176,  176,  176,  176,   15,  177,    0,   30,    0,   22,   20,   20,   31,   22,   22,   11,
+    166,    0,   61,   61,   61,   61,   61,   61,   61,   66,   21,   82,   46,    0,    0,    0,
+      0,    2,    2,    2,    9,    2,   30,    2,    2,   52,   22,   22,   31,    0,   38,   22,
+     27,   11,  159,  178,  174,    0,    0,    0,    0,    2,    2,    2,   30,    9,    2,    2,
+      2,    2,    2,    2,    2,    2,   23,   23,   47,   22,   35,   82,   68,    0,    0,    0,
+      0,    2,  179,   66,   47,    0,    0,    0,    0,   11,  180,    2,    2,    2,    2,    2,
+      2,    2,    2,   23,   22,   20,   31,    0,   48,   16,  143,    0,    0,    0,    0,    0,
+      0,  181,  181,  181,  181,  181,  181,  181,  181,  182,  182,  182,  183,  184,  182,  181,
+    181,  185,  181,  181,  186,  187,  187,  187,  187,  187,  187,  187,    0,    0,    0,    0,
+      0,   11,   11,   11,   46,    0,    0,    0,    0,    2,    2,    2,    2,    2,    9,    0,
+     58,  188,   20,   20,   20,   20,   20,   20,   20,   20,   20,   20,   20,   20,   20,   20,
+     20,   20,   20,   20,   20,    0,    0,    0,   40,  116,   26,    0,    0,    0,    0,    0,
+      0,    0,    0,    9,    0,    0,    0,    0,    0,    2,    2,    2,    0,    0,    0,    0,
+      0,    2,    2,    2,    2,    2,    0,   58,   37,    0,    6,  120,  120,  120,  121,    0,
+      0,   11,   11,   11,   49,    2,    2,    2,    0,    2,    2,    2,    2,    2,    0,    0,
+      2,    2,    2,    2,    2,    2,    2,    2,   46,    2,    2,    2,    2,    2,    2,   11,
+     11,    2,    2,    2,    2,    2,    2,   22,   22,    2,    2,   44,   44,   44,   92,    0,
+      0,    O,    O,    O,   GB,    B,    B,    O,   SB,    O,   SE,   GB,    O,    O,   WJ,FMPst,
+  FMPst,    O,  CGJ,    B,    O,    B,VMAbv,VMAbv,VMAbv,    O,VMAbv,    B,CMBlw,CMBlw,CMBlw,VMAbv,
+  VMPst, VAbv, VPst,CMBlw,    B, VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VPst,
+   VPst, VPst,    H, VPre, VPst,VMBlw,    O,    O, VAbv,   GB,VMAbv,VMPst,VMPst,    O,    B, VBlw,
+      O,    O, VPre, VPre,    O, VPre,    H,    O, VPst,FMAbv,    O,CMBlw,    O, VAbv,    O, VAbv,
+      H,    O,VMBlw,VMAbv,CMAbv,   GB,   GB,    O, MBlw,CMAbv,CMAbv, VPst, VAbv,VMAbv,    O, VPst,
+      O, VPre, VPre,VMAbv,    B,    O,   CS,   CS,VMPst,    B, VAbv, VAbv,    B,    R,    O,  HVM,
+      O,    O,FMBlw,    O,CMAbv,    O,CMBlw, VAbv, VBlw,    B,  SUB,  SUB,  SUB,    O,  SUB,  SUB,
+      O,FMBlw,    O,    B, VPst, VBlw, VPre,VMAbv,VMBlw,VMPst,   IS, VAbv, MPst, MPre, MBlw, MBlw,
+      B, MBlw, MBlw, VPst,VMPst,VMPst,    B, MBlw, VPst, VPre, VAbv, VAbv,VMPst,VMPst,VMBlw,    B,
+  VMPst, VBlw, VPst,  CGJ,  CGJ, VPst,VMAbv,VMAbv,FMAbv, FAbv,CMAbv,FMAbv,VMAbv,FMAbv, VAbv,   IS,
+  FMAbv,    B,FMAbv,    B,  CGJ,   WJ,  CGJ,   GB,CMAbv,CMAbv,    B,   GB,    B, VAbv,  SUB, FPst,
+   FPst,VMBlw, FPst, FPst, FBlw,VMAbv,FMBlw, VAbv, VPre,    B, MPre, MBlw,  SUB, FAbv, FAbv, MAbv,
+    SUB,   Sk, VPst, VAbv,VMAbv,VMAbv, FAbv,CMAbv, VPst,    H,    B,    O,SMAbv,SMBlw,SMAbv,SMAbv,
+  SMAbv, VPst,   IS, VBlw, FAbv,VMPre,VMPre,FMAbv,CMBlw,VMBlw,VMBlw,VMAbv,   CS,    O,FMAbv, ZWNJ,
+    CGJ,   WJ,   WJ,   WJ,    O,FMPst,    O,   SB,   SE,    O,    H, MPst, VPst,    H,VMAbv, VAbv,
+  VMBlw,    B, VBlw, FPst, VPst, FAbv,VMPst,    B,CMAbv, VAbv, MBlw, MPst, MBlw,    H,    O, VBlw,
+   MPst, MPre, MAbv, MBlw,    O,    B, FAbv, FAbv, FPst, VBlw,    B,    B, VPre,    O,VMPst,   IS,
+      O,VMPst, VBlw, VPst,VMBlw,VMBlw,VMAbv,    O,   IS,VMBlw,    B,VMPst,VMAbv,VMPst,   CS,   CS,
+      B,    N,    N,    O,   HN, VPre, VBlw, VAbv,   IS,CMAbv,    O, VPst,    B,    R,    R,CMBlw,
+   VAbv, VPre,VMAbv,VMAbv,    H, VAbv,CMBlw,FMAbv,    B,   CS,   CS,    H,CMBlw,VMPst,    H,VMPst,
+   VAbv,VMAbv, VPst,   IS,    R, MPst,    R, MPst,CMBlw,    B,FMBlw, VBlw,VMAbv,    R, MBlw, MBlw,
+     GB, FBlw, FBlw,CMAbv,   IS, VBlw,   IS,   GB, VAbv,    R,VMPst,    G,    G,    J,    J,    J,
+     SB,   SE,    J,   HR,    G,    G,   HM,   HM,   HM,    O, VBlw,
 };
 static const uint16_t
-hb_use_u16[448] =
+hb_use_u16[456] =
 {
-    0,  0,  1,  2,  3,  4,  0,  5,  6,  0,  7,  0,  8,  9, 10, 11,
-    9, 12, 13,  9,  9, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
-   17, 25, 26, 20, 21, 27, 28, 29, 30, 31, 32, 33, 21, 34, 35,  0,
-   17, 36, 37, 20, 21, 38, 23, 39, 17, 40, 41, 42, 43, 44, 45, 46,
-   30,  0, 47, 48, 21, 49, 50, 51, 17,  0, 52, 48, 21, 53, 50, 54,
-   17, 55, 56, 48,  9, 57, 58, 59, 60, 61,  9, 62, 63, 64, 30, 65,
-   66, 67,  9, 68, 69,  9, 70, 71, 72, 73, 74, 75, 76,  0,  9,  9,
-   77, 78, 79, 80, 81, 82, 83, 84,  9, 85,  9, 86,  9, 87, 88, 89,
-    9, 90, 91, 92,  2,  0, 93,  0,  9, 94, 95,  9, 96,  0, 97, 98,
-   99,100, 30,  9,101,102,103,  9,104,105,  9,106,  9,107,108,109,
-    2,  2,110,  9,  9,111,112,  2,113,114,115,  9,116,  9,117,118,
-  119,120,121,  0,  0,122,123,124,  0,125,126,127,128,  0,129,130,
-  131,  0,  0,132,133,  0,  0,  9,134,135,136,  9,137,  0,  9,138,
-  139,  9,  9,140,141,  2,142,143,144,  9,145,146,147,  9,  9,148,
-  149,  2,150, 98,151,152,153,  2,  9,154,  9,155,156,  0,157,158,
-  159,  2,160,  0,  0,161,  0,162,  0,163,163,164, 33,165,166,167,
-    9,168, 94,  0,169,  0,  9,170,171,  0,172,  2,173,170,174,175,
-  176,  0,  0,177,178,  0,179,  9,  9,180,181,182,183,184,185,  9,
-    9,186,187,  0,188,  9,189,190,191,  9,  9,192,  9,193,194,105,
-  195,102,  9, 33,196,197,198,  0,199,200, 94,  9,  9,201,202,  2,
-  203, 20, 21,204,205,206,207,208,  9,209,210,211,212,  0,195,  9,
-    9,213,214,  2,215,216,217,218,  9,219,220,  2,221,222,  9,223,
-  224,103,225,  0,226,227,228,229,  9,230,231,  2,232,  9,  9,233,
-  234,  0,235,  9,  9,236,237,238,239,240, 21,  9,215,241,  7,  9,
-   70, 18,  9,242, 73,243,244,  9,  9,245,246,  2,247,  9,248,249,
-    9,250,251, 48,  9,252,253,  2,  9,254,255,256,  9,257,258,259,
-  260,260,261,262,263,  0,  9,264,105, 70, 94,265,  0,266, 70,267,
-  268,  0,269,  0,270,  2,271,  2,272,  2,129,129,160,160,160,129,
+    0,  0,  1,  2,  0,  3,  4,  5,  0,  6,  7,  0,  8,  0,  9, 10,
+   11, 12, 10, 13, 14, 10, 10, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+   24, 25, 18, 26, 27, 21, 22, 28, 29, 30, 31, 32, 33, 34, 22, 35,
+   36,  0, 18, 37, 38, 21, 22, 39, 24, 40, 18, 41, 42, 43, 44, 45,
+   46, 47, 31,  0, 48, 49, 22, 50, 51, 52, 18,  0, 53, 49, 22, 54,
+   51, 55, 18, 56, 57, 49, 10, 58, 59, 60, 61, 62, 10, 63, 64, 65,
+   31, 66, 67, 68, 10, 69, 70, 10, 71, 72, 73, 74, 75, 76, 77,  0,
+   10, 10, 78, 79, 80, 81, 82, 83, 84, 85, 10, 86, 10, 87, 10, 88,
+   89, 90, 10, 91, 92, 93,  2,  0, 94,  0, 10, 95, 96, 10, 97,  0,
+   98, 99,100,101, 31, 10,102,103,104, 10,105,106, 10,107, 10,108,
+  109,110,  2,  2,111, 10, 10,112,113,  2,114,115,116, 10,117, 10,
+  118,119,120,121,122,  0,  0,123,124,125,  0,126,127,128,129,  0,
+  130,131,132,  0,  0,133,134,  0,135,  0,  0, 10,136,137,138,  0,
+  139, 10,140,  0, 10,141,142, 10, 10,143,144,  2,145,146,147, 10,
+  148,149,150, 10, 10,151,152,  2,153, 99,154,155,156,  2, 10,157,
+   10,158,159,  0,160,161,162,  2,163,  0,  0,164,  0,165,  0,166,
+  166,167, 34,168,169,170, 10,171, 95,  0,172,  0, 10,173,174,  0,
+  175,  2,176,173,177,178,179,  0,  0,180,181,  0,182, 10, 10,183,
+  184,185,186,187,188, 10, 10,189,190,  0,191, 10,192,193,194, 10,
+   10,195, 10,196,197,106,198,103, 10, 34,199,200,201,  0,202,203,
+   95, 10, 10,204,205,  2,206, 21, 22,207,208,209,210,211, 10,212,
+  213,214,215,  0,198, 10, 10,216,217,  2,218,219,220,221, 10,222,
+  223,  2,224,225, 10,226,227,104,228,  0,229,230,231,232, 10,233,
+  234,  2,235, 10, 10,236,237,  0,238, 10, 10,239,240,241,242,243,
+   22, 10,218,244,  8, 10, 71, 19, 10,245, 74,246,247, 10, 10,248,
+  249,  2,250, 10,251,252, 10,253,254, 49, 10,255,256,  2,257,257,
+  257,258,259,260, 10,261,262,263,264,264,265,266,267,  0, 10,268,
+  106, 71, 95,269,  0,270, 71,271,272,  0,273,  0,274,  2,275,  2,
+  276,  2,130,130,163,163,163,130,
 };
 
 static inline unsigned
@@ -622,7 +636,7 @@
 static inline uint_fast8_t
 hb_use_get_category (unsigned u)
 {
-  return u<921600u?hb_use_u8[3049+(((hb_use_u8[865+(((hb_use_u16[((hb_use_u8[353+(((hb_use_u8[113+(((hb_use_b4(hb_use_u8,u>>1>>3>>1>>3>>4))<<4)+((u>>1>>3>>1>>3)&15u))])<<3)+((u>>1>>3>>1)&7u))])<<1)+((u>>1>>3)&1u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:O;
+  return u<921600u?hb_use_u8[3105+(((hb_use_u8[889+(((hb_use_u16[((hb_use_u8[353+(((hb_use_u8[113+(((hb_use_b4(hb_use_u8,u>>1>>3>>1>>3>>4))<<4)+((u>>1>>3>>1>>3)&15u))])<<3)+((u>>1>>3>>1)&7u))])<<1)+((u>>1>>3)&1u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:O;
 }
 
 #endif
@@ -633,7 +647,9 @@
 #undef G
 #undef GB
 #undef H
+#undef HM
 #undef HN
+#undef HR
 #undef HVM
 #undef IS
 #undef J
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use.cc
index b2c47f6..9bbfa1e 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use.cc
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-use.cc
@@ -377,6 +377,9 @@
 #define POST_BASE_FLAGS64 (FLAG64 (USE(FAbv)) | \
                            FLAG64 (USE(FBlw)) | \
                            FLAG64 (USE(FPst)) | \
+                           FLAG64 (USE(FMAbv)) | \
+                           FLAG64 (USE(FMBlw)) | \
+                           FLAG64 (USE(FMPst)) | \
                            FLAG64 (USE(MAbv)) | \
                            FLAG64 (USE(MBlw)) | \
                            FLAG64 (USE(MPst)) | \
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-vowel-constraints.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-vowel-constraints.cc
index 9568da1..3569325 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-vowel-constraints.cc
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-shaper-vowel-constraints.cc
@@ -10,8 +10,8 @@
  * # Date: 2015-03-12, 21:17:00 GMT [AG]
  * # Date: 2019-11-08, 23:22:00 GMT [AG]
  *
- * # Scripts-15.0.0.txt
- * # Date: 2022-04-26, 23:15:02 GMT
+ * # Scripts-15.1.0.txt
+ * # Date: 2023-07-28, 16:01:07 GMT
  */
 
 #include "hb.hh"
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-stat-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-stat-table.hh
index 448d03e..7f6b52d 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-stat-table.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-stat-table.hh
@@ -57,6 +57,16 @@
   // Reserved = 0xFFFC                          /* Reserved for future use — set to zero. */
 };
 
+static bool axis_value_is_outside_axis_range (hb_tag_t axis_tag, float axis_value,
+                                              const hb_hashmap_t<hb_tag_t, Triple> *user_axes_location)
+{
+  if (!user_axes_location->has (axis_tag))
+    return false;
+
+  Triple axis_range = user_axes_location->get (axis_tag);
+  return (axis_value < axis_range.minimum || axis_value > axis_range.maximum);
+}
+
 struct StatAxisRecord
 {
   int cmp (hb_tag_t key) const { return tag.cmp (key); }
@@ -96,23 +106,19 @@
   }
 
   bool keep_axis_value (const hb_array_t<const StatAxisRecord> axis_records,
-                        const hb_hashmap_t<hb_tag_t, float> *user_axes_location) const
+                        const hb_hashmap_t<hb_tag_t, Triple> *user_axes_location) const
   {
     hb_tag_t axis_tag = get_axis_tag (axis_records);
     float axis_value = get_value ();
 
-    if (!user_axes_location->has (axis_tag) ||
-        fabsf(axis_value - user_axes_location->get (axis_tag)) < 0.001f)
-      return true;
-
-    return false;
+    return !axis_value_is_outside_axis_range (axis_tag, axis_value, user_axes_location);
   }
 
   bool subset (hb_subset_context_t *c,
                const hb_array_t<const StatAxisRecord> axis_records) const
   {
     TRACE_SUBSET (this);
-    const hb_hashmap_t<hb_tag_t, float>* user_axes_location = &c->plan->user_axes_location;
+    const hb_hashmap_t<hb_tag_t, Triple>* user_axes_location = &c->plan->user_axes_location;
 
     if (keep_axis_value (axis_records, user_axes_location))
       return_trace (c->serializer->embed (this));
@@ -155,23 +161,19 @@
   }
 
   bool keep_axis_value (const hb_array_t<const StatAxisRecord> axis_records,
-                        const hb_hashmap_t<hb_tag_t, float> *user_axes_location) const
+                        const hb_hashmap_t<hb_tag_t, Triple> *user_axes_location) const
   {
     hb_tag_t axis_tag = get_axis_tag (axis_records);
     float axis_value = get_value ();
 
-    if (!user_axes_location->has (axis_tag) ||
-        fabsf(axis_value - user_axes_location->get (axis_tag)) < 0.001f)
-      return true;
-
-    return false;
+    return !axis_value_is_outside_axis_range (axis_tag, axis_value, user_axes_location);
   }
 
   bool subset (hb_subset_context_t *c,
                const hb_array_t<const StatAxisRecord> axis_records) const
   {
     TRACE_SUBSET (this);
-    const hb_hashmap_t<hb_tag_t, float>* user_axes_location = &c->plan->user_axes_location;
+    const hb_hashmap_t<hb_tag_t, Triple>* user_axes_location = &c->plan->user_axes_location;
 
     if (keep_axis_value (axis_records, user_axes_location))
       return_trace (c->serializer->embed (this));
@@ -218,23 +220,19 @@
   }
 
   bool keep_axis_value (const hb_array_t<const StatAxisRecord> axis_records,
-                        const hb_hashmap_t<hb_tag_t, float> *user_axes_location) const
+                        const hb_hashmap_t<hb_tag_t, Triple> *user_axes_location) const
   {
     hb_tag_t axis_tag = get_axis_tag (axis_records);
     float axis_value = get_value ();
 
-    if (!user_axes_location->has (axis_tag) ||
-        fabsf(axis_value - user_axes_location->get (axis_tag)) < 0.001f)
-      return true;
-
-    return false;
+    return !axis_value_is_outside_axis_range (axis_tag, axis_value, user_axes_location);
   }
 
   bool subset (hb_subset_context_t *c,
                const hb_array_t<const StatAxisRecord> axis_records) const
   {
     TRACE_SUBSET (this);
-    const hb_hashmap_t<hb_tag_t, float>* user_axes_location = &c->plan->user_axes_location;
+    const hb_hashmap_t<hb_tag_t, Triple>* user_axes_location = &c->plan->user_axes_location;
 
     if (keep_axis_value (axis_records, user_axes_location))
       return_trace (c->serializer->embed (this));
@@ -291,7 +289,7 @@
   { return axisValues.as_array (axisCount)[axis_index]; }
 
   bool keep_axis_value (const hb_array_t<const StatAxisRecord> axis_records,
-                        const hb_hashmap_t<hb_tag_t, float> *user_axes_location) const
+                        const hb_hashmap_t<hb_tag_t, Triple> *user_axes_location) const
   {
     hb_array_t<const AxisValueRecord> axis_value_records = axisValues.as_array (axisCount);
 
@@ -301,8 +299,7 @@
       float axis_value = rec.get_value ();
       hb_tag_t axis_tag = axis_records[axis_idx].get_axis_tag ();
 
-      if (user_axes_location->has (axis_tag) &&
-          fabsf(axis_value - user_axes_location->get (axis_tag)) > 0.001f)
+      if (axis_value_is_outside_axis_range (axis_tag, axis_value, user_axes_location))
         return false;
     }
 
@@ -313,7 +310,7 @@
                const hb_array_t<const StatAxisRecord> axis_records) const
   {
     TRACE_SUBSET (this);
-    const hb_hashmap_t<hb_tag_t, float> *user_axes_location = &c->plan->user_axes_location;
+    const hb_hashmap_t<hb_tag_t, Triple> *user_axes_location = &c->plan->user_axes_location;
     if (!keep_axis_value (axis_records, user_axes_location))
       return_trace (false);
 
@@ -402,7 +399,7 @@
   }
 
   bool keep_axis_value (const hb_array_t<const StatAxisRecord> axis_records,
-                        hb_hashmap_t<hb_tag_t, float> *user_axes_location) const
+                        hb_hashmap_t<hb_tag_t, Triple> *user_axes_location) const
   {
     switch (u.format)
     {
@@ -451,8 +448,6 @@
                const hb_array_t<const StatAxisRecord> axis_records) const
   {
     TRACE_SUBSET (this);
-    auto *out = c->serializer->start_embed (this);
-    if (unlikely (!out)) return_trace (false);
 
     auto axisValueOffsets = as_array (axisValueCount);
     count = 0;
@@ -517,7 +512,7 @@
     return axis_value.get_value_name_id ();
   }
 
-  void collect_name_ids (hb_hashmap_t<hb_tag_t, float> *user_axes_location,
+  void collect_name_ids (hb_hashmap_t<hb_tag_t, Triple> *user_axes_location,
                          hb_set_t *nameids_to_retain /* OUT */) const
   {
     if (!has_data ()) return;
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-tag-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-tag-table.hh
index 4c7215e..8ee42e6 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-tag-table.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-tag-table.hh
@@ -6,8 +6,8 @@
  *
  * on files with these headers:
  *
- * <meta name="updated_at" content="2022-01-28 10:00 PM" />
- * File-Date: 2022-03-02
+ * <meta name="updated_at" content="2022-09-30 11:47 PM" />
+ * File-Date: 2023-08-02
  */
 
 #ifndef HB_OT_TAG_TABLE_HH
@@ -257,7 +257,7 @@
   {HB_TAG('a','i','i',' '),     HB_TAG('S','Y','R',' ')},       /* Assyrian Neo-Aramaic -> Syriac */
 /*{HB_TAG('a','i','o',' '),     HB_TAG('A','I','O',' ')},*/     /* Aiton */
   {HB_TAG('a','i','w',' '),     HB_TAG('A','R','I',' ')},       /* Aari */
-  {HB_TAG('a','j','p',' '),     HB_TAG('A','R','A',' ')},       /* South Levantine Arabic -> Arabic */
+  {HB_TAG('a','j','p',' '),     HB_TAG('A','R','A',' ')},       /* South Levantine Arabic (retired code) -> Arabic */
   {HB_TAG('a','j','t',' '),     HB_TAG('A','R','A',' ')},       /* Judeo-Tunisian Arabic (retired code) -> Arabic */
   {HB_TAG('a','k','b',' '),     HB_TAG('A','K','B',' ')},       /* Batak Angkola */
   {HB_TAG('a','k','b',' '),     HB_TAG('B','T','K',' ')},       /* Batak Angkola -> Batak */
@@ -269,7 +269,7 @@
 /*{HB_TAG('a','n','g',' '),     HB_TAG('A','N','G',' ')},*/     /* Old English (ca. 450-1100) -> Anglo-Saxon */
   {HB_TAG('a','o','a',' '),     HB_TAG('C','P','P',' ')},       /* Angolar -> Creoles */
   {HB_TAG('a','p','a',' '),     HB_TAG('A','T','H',' ')},       /* Apache [collection] -> Athapaskan */
-  {HB_TAG('a','p','c',' '),     HB_TAG('A','R','A',' ')},       /* North Levantine Arabic -> Arabic */
+  {HB_TAG('a','p','c',' '),     HB_TAG('A','R','A',' ')},       /* Levantine Arabic -> Arabic */
   {HB_TAG('a','p','d',' '),     HB_TAG('A','R','A',' ')},       /* Sudanese Arabic -> Arabic */
   {HB_TAG('a','p','j',' '),     HB_TAG('A','T','H',' ')},       /* Jicarilla Apache -> Athapaskan */
   {HB_TAG('a','p','k',' '),     HB_TAG('A','T','H',' ')},       /* Kiowa Apache -> Athapaskan */
@@ -1211,6 +1211,7 @@
   {HB_TAG('p','p','a',' '),     HB_TAG('B','A','G',' ')},       /* Pao (retired code) -> Baghelkhandi */
   {HB_TAG('p','r','e',' '),     HB_TAG('C','P','P',' ')},       /* Principense -> Creoles */
 /*{HB_TAG('p','r','o',' '),     HB_TAG('P','R','O',' ')},*/     /* Old Provençal (to 1500) -> Provençal / Old Provençal */
+  {HB_TAG('p','r','p',' '),     HB_TAG('G','U','J',' ')},       /* Parsi (retired code) -> Gujarati */
   {HB_TAG('p','r','s',' '),     HB_TAG('D','R','I',' ')},       /* Dari */
   {HB_TAG('p','r','s',' '),     HB_TAG('F','A','R',' ')},       /* Dari -> Persian */
   {HB_TAG('p','s','e',' '),     HB_TAG('M','L','Y',' ')},       /* Central Malay -> Malay */
@@ -1439,7 +1440,7 @@
   {HB_TAG('t','c','h',' '),     HB_TAG('C','P','P',' ')},       /* Turks And Caicos Creole English -> Creoles */
   {HB_TAG('t','c','p',' '),     HB_TAG('Q','I','N',' ')},       /* Tawr Chin -> Chin */
   {HB_TAG('t','c','s',' '),     HB_TAG('C','P','P',' ')},       /* Torres Strait Creole -> Creoles */
-  {HB_TAG('t','c','y',' '),     HB_TAG('T','U','L',' ')},       /* Tulu -> Tumbuka */
+  {HB_TAG('t','c','y',' '),     HB_TAG('T','U','L',' ')},       /* Tulu */
   {HB_TAG('t','c','z',' '),     HB_TAG('Q','I','N',' ')},       /* Thado Chin -> Chin */
 /*{HB_TAG('t','d','d',' '),     HB_TAG('T','D','D',' ')},*/     /* Tai Nüa -> Dehong Dai */
   {HB_TAG('t','d','x',' '),     HB_TAG('M','L','G',' ')},       /* Tandroy-Mahafaly Malagasy -> Malagasy */
@@ -1495,8 +1496,8 @@
   {HB_TAG('t','t','q',' '),     HB_TAG('T','M','H',' ')},       /* Tawallammat Tamajaq -> Tamashek */
   {HB_TAG('t','t','q',' '),     HB_TAG('B','B','R',' ')},       /* Tawallammat Tamajaq -> Berber */
   {HB_TAG('t','u','a',' '),     HB_TAG_NONE            },       /* Wiarumus != Turoyo Aramaic */
-  {HB_TAG('t','u','l',' '),     HB_TAG_NONE            },       /* Tula != Tumbuka */
-/*{HB_TAG('t','u','m',' '),     HB_TAG('T','U','M',' ')},*/     /* Tumbuka -> Tulu */
+  {HB_TAG('t','u','l',' '),     HB_TAG_NONE            },       /* Tula != Tulu */
+/*{HB_TAG('t','u','m',' '),     HB_TAG('T','U','M',' ')},*/     /* Tumbuka */
   {HB_TAG('t','u','u',' '),     HB_TAG('A','T','H',' ')},       /* Tututni -> Athapaskan */
   {HB_TAG('t','u','v',' '),     HB_TAG_NONE            },       /* Turkana != Tuvin */
   {HB_TAG('t','u','y',' '),     HB_TAG('K','A','L',' ')},       /* Tugen -> Kalenjin */
@@ -1581,6 +1582,7 @@
   {HB_TAG('y','b','a',' '),     HB_TAG_NONE            },       /* Yala != Yoruba */
   {HB_TAG('y','b','b',' '),     HB_TAG('B','M','L',' ')},       /* Yemba -> Bamileke */
   {HB_TAG('y','b','d',' '),     HB_TAG('A','R','K',' ')},       /* Yangbye (retired code) -> Rakhine */
+  {HB_TAG('y','c','r',' '),     HB_TAG_NONE            },       /* Yilan Creole != Y-Cree */
   {HB_TAG('y','d','d',' '),     HB_TAG('J','I','I',' ')},       /* Eastern Yiddish -> Yiddish */
 /*{HB_TAG('y','g','p',' '),     HB_TAG('Y','G','P',' ')},*/     /* Gepo */
   {HB_TAG('y','i','h',' '),     HB_TAG('J','I','I',' ')},       /* Western Yiddish -> Yiddish */
@@ -1602,6 +1604,7 @@
   {HB_TAG('z','g','n',' '),     HB_TAG('Z','H','A',' ')},       /* Guibian Zhuang -> Zhuang */
   {HB_TAG('z','h','d',' '),     HB_TAG('Z','H','A',' ')},       /* Dai Zhuang -> Zhuang */
   {HB_TAG('z','h','n',' '),     HB_TAG('Z','H','A',' ')},       /* Nong Zhuang -> Zhuang */
+  {HB_TAG('z','k','b',' '),     HB_TAG('K','H','A',' ')},       /* Koibal (retired code) -> Khakass */
   {HB_TAG('z','l','j',' '),     HB_TAG('Z','H','A',' ')},       /* Liujiang Zhuang -> Zhuang */
   {HB_TAG('z','l','m',' '),     HB_TAG('M','L','Y',' ')},       /* Malay */
   {HB_TAG('z','l','n',' '),     HB_TAG('Z','H','A',' ')},       /* Lianshan Zhuang -> Zhuang */
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-tag.cc b/src/java.desktop/share/native/libharfbuzz/hb-ot-tag.cc
index 91bb117..9f0ae3b 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-tag.cc
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-tag.cc
@@ -412,7 +412,7 @@
 /**
  * hb_ot_tags_from_script_and_language:
  * @script: an #hb_script_t to convert.
- * @language: an #hb_language_t to convert.
+ * @language: (nullable): an #hb_language_t to convert.
  * @script_count: (inout) (optional): maximum number of script tags to retrieve (IN)
  * and actual number of script tags retrieved (OUT)
  * @script_tags: (out) (optional): array of size at least @script_count to store the
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-avar-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-avar-table.hh
index 7a54a37..0aaf68a 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-avar-table.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-avar-table.hh
@@ -72,6 +72,65 @@
     return_trace (c->check_struct (this));
   }
 
+  void set_mapping (float from_coord, float to_coord)
+  {
+    coords[0].set_float (from_coord);
+    coords[1].set_float (to_coord);
+  }
+
+  bool is_outside_axis_range (const Triple& axis_range) const
+  {
+    float from_coord = coords[0].to_float ();
+    return !axis_range.contains (from_coord);
+  }
+
+  bool must_include () const
+  {
+    float from_coord = coords[0].to_float ();
+    float to_coord = coords[1].to_float ();
+    return (from_coord == -1.f && to_coord == -1.f) ||
+           (from_coord == 0.f && to_coord == 0.f) ||
+           (from_coord == 1.f && to_coord == 1.f);
+  }
+
+  void instantiate (const Triple& axis_range,
+                    const Triple& unmapped_range,
+                    const TripleDistances& triple_distances)
+  {
+    float from_coord = coords[0].to_float ();
+    float to_coord = coords[1].to_float ();
+
+    from_coord = renormalizeValue (from_coord, unmapped_range, triple_distances);
+    to_coord = renormalizeValue (to_coord, axis_range, triple_distances);
+
+    coords[0].set_float (from_coord);
+    coords[1].set_float (to_coord);
+  }
+
+  HB_INTERNAL static int cmp (const void *pa, const void *pb)
+  {
+    const AxisValueMap *a = (const AxisValueMap *) pa;
+    const AxisValueMap *b = (const AxisValueMap *) pb;
+
+    int a_from = a->coords[0].to_int ();
+    int b_from = b->coords[0].to_int ();
+    if (a_from != b_from)
+      return a_from - b_from;
+
+    /* this should never be reached. according to the spec, all of the axis
+     * value map records for a given axis must have different fromCoord values
+     * */
+    int a_to = a->coords[1].to_int ();
+    int b_to = b->coords[1].to_int ();
+    return a_to - b_to;
+  }
+
+  bool serialize (hb_serialize_context_t *c) const
+  {
+    TRACE_SERIALIZE (this);
+    return_trace (c->embed (this));
+  }
+
   public:
   F2DOT14       coords[2];
 //   F2DOT14    fromCoord;      /* A normalized coordinate value obtained using
@@ -122,6 +181,78 @@
 
   int unmap (int value) const { return map (value, 1, 0); }
 
+  Triple unmap_axis_range (const Triple& axis_range) const
+  {
+    F2DOT14 val, unmapped_val;
+
+    val.set_float (axis_range.minimum);
+    unmapped_val.set_int (unmap (val.to_int ()));
+    float unmapped_min = unmapped_val.to_float ();
+
+    val.set_float (axis_range.middle);
+    unmapped_val.set_int (unmap (val.to_int ()));
+    float unmapped_middle = unmapped_val.to_float ();
+
+    val.set_float (axis_range.maximum);
+    unmapped_val.set_int (unmap (val.to_int ()));
+    float unmapped_max = unmapped_val.to_float ();
+
+    return Triple{unmapped_min, unmapped_middle, unmapped_max};
+  }
+
+  bool subset (hb_subset_context_t *c, hb_tag_t axis_tag) const
+  {
+    TRACE_SUBSET (this);
+    /* avar mapped normalized axis range*/
+    Triple *axis_range;
+    if (!c->plan->axes_location.has (axis_tag, &axis_range))
+      return c->serializer->embed (*this);
+
+    TripleDistances *axis_triple_distances;
+    if (!c->plan->axes_triple_distances.has (axis_tag, &axis_triple_distances))
+      return_trace (false);
+
+    auto *out = c->serializer->start_embed (this);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+
+    Triple unmapped_range = unmap_axis_range (*axis_range);
+
+    /* create a vector of retained mappings and sort */
+    hb_vector_t<AxisValueMap> value_mappings;
+    for (const auto& _ : as_array ())
+    {
+      if (_.is_outside_axis_range (unmapped_range))
+        continue;
+      AxisValueMap mapping;
+      mapping = _;
+      mapping.instantiate (*axis_range, unmapped_range, *axis_triple_distances);
+      /* (-1, -1), (0, 0), (1, 1) mappings will be added later, so avoid
+       * duplicates here */
+      if (mapping.must_include ())
+        continue;
+      value_mappings.push (std::move (mapping));
+    }
+
+    AxisValueMap m;
+    m.set_mapping (-1.f, -1.f);
+    value_mappings.push (m);
+
+    m.set_mapping (0.f, 0.f);
+    value_mappings.push (m);
+
+    m.set_mapping (1.f, 1.f);
+    value_mappings.push (m);
+
+    value_mappings.qsort ();
+
+    for (const auto& _ : value_mappings)
+    {
+      if (!_.serialize (c->serializer))
+        return_trace (false);
+    }
+    return_trace (c->serializer->check_assign (out->len, value_mappings.length, HB_SERIALIZE_ERROR_INT_OVERFLOW));
+  }
+
   public:
   DEFINE_SIZE_ARRAY (2, *this);
 };
@@ -225,6 +356,39 @@
     }
   }
 
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    unsigned retained_axis_count = c->plan->axes_index_map.get_population ();
+    if (!retained_axis_count) //all axes are pinned/dropped
+      return_trace (false);
+
+    avar *out = c->serializer->allocate_min<avar> ();
+    if (unlikely (!out)) return_trace (false);
+
+    out->version.major = 1;
+    out->version.minor = 0;
+    if (!c->serializer->check_assign (out->axisCount, retained_axis_count, HB_SERIALIZE_ERROR_INT_OVERFLOW))
+      return_trace (false);
+
+    const hb_map_t& axes_index_map = c->plan->axes_index_map;
+    const SegmentMaps *map = &firstAxisSegmentMaps;
+    unsigned count = axisCount;
+    for (unsigned int i = 0; i < count; i++)
+    {
+      if (axes_index_map.has (i))
+      {
+        hb_tag_t *axis_tag;
+        if (!c->plan->axes_old_index_tag_map.has (i, &axis_tag))
+          return_trace (false);
+        if (!map->subset (c, *axis_tag))
+          return_trace (false);
+      }
+      map = &StructAfter<SegmentMaps> (*map);
+    }
+    return_trace (true);
+  }
+
   protected:
   FixedVersion<>version;        /* Version of the avar table
                                  * initially set to 0x00010000u */
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-common.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-common.hh
index 97d2a4b..271250f 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-common.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-common.hh
@@ -27,6 +27,7 @@
 #define HB_OT_VAR_COMMON_HH
 
 #include "hb-ot-layout-common.hh"
+#include "hb-priority-queue.hh"
 
 
 namespace OT {
@@ -36,19 +37,14 @@
 {
   friend struct DeltaSetIndexMap;
 
+  unsigned get_size () const
+  { return min_size + mapCount * get_width (); }
+
   private:
   DeltaSetIndexMapFormat01* copy (hb_serialize_context_t *c) const
   {
     TRACE_SERIALIZE (this);
-    auto *out = c->start_embed (this);
-    if (unlikely (!out)) return_trace (nullptr);
-
-    unsigned total_size = min_size + mapCount * get_width ();
-    HBUINT8 *p = c->allocate_size<HBUINT8> (total_size);
-    if (unlikely (!p)) return_trace (nullptr);
-
-    hb_memcpy (p, this, HBUINT8::static_size * total_size);
-    return_trace (out);
+    return_trace (c->embed (this));
   }
 
   template <typename T>
@@ -69,14 +65,17 @@
     if (unlikely (!p)) return_trace (false);
     for (unsigned int i = 0; i < output_map.length; i++)
     {
-      unsigned int v = output_map[i];
-      unsigned int outer = v >> 16;
-      unsigned int inner = v & 0xFFFF;
-      unsigned int u = (outer << inner_bit_count) | inner;
-      for (unsigned int w = width; w > 0;)
+      unsigned int v = output_map.arrayZ[i];
+      if (v)
       {
-        p[--w] = u;
-        u >>= 8;
+        unsigned int outer = v >> 16;
+        unsigned int inner = v & 0xFFFF;
+        unsigned int u = (outer << inner_bit_count) | inner;
+        for (unsigned int w = width; w > 0;)
+        {
+          p[--w] = u;
+          u >>= 8;
+        }
       }
       p += width;
     }
@@ -232,7 +231,7 @@
   /* according to the spec, if colr table has varStore but does not have
    * varIdxMap, then an implicit identity mapping is used */
   float operator() (uint32_t varIdx, unsigned short offset = 0) const
-  { return varStore->get_delta (varIdxMap ? varIdxMap->map (VarIdx::add (varIdx, offset)) : varIdx + offset, coords); }
+  { return coords ? varStore->get_delta (varIdxMap ? varIdxMap->map (VarIdx::add (varIdx, offset)) : varIdx + offset, coords) : 0; }
 
   const VariationStore *varStore;
   const DeltaSetIndexMap *varIdxMap;
@@ -242,6 +241,7 @@
 /* https://docs.microsoft.com/en-us/typography/opentype/spec/otvarcommonformats#tuplevariationheader */
 struct TupleVariationHeader
 {
+  friend struct tuple_delta_t;
   unsigned get_size (unsigned axis_count) const
   { return min_size + get_all_tuples (axis_count).get_size (); }
 
@@ -250,14 +250,67 @@
   const TupleVariationHeader &get_next (unsigned axis_count) const
   { return StructAtOffset<TupleVariationHeader> (this, get_size (axis_count)); }
 
+  bool unpack_axis_tuples (unsigned axis_count,
+                           const hb_array_t<const F2DOT14> shared_tuples,
+                           const hb_map_t *axes_old_index_tag_map,
+                           hb_hashmap_t<hb_tag_t, Triple>& axis_tuples /* OUT */) const
+  {
+    const F2DOT14 *peak_tuple = nullptr;
+    if (has_peak ())
+      peak_tuple = get_peak_tuple (axis_count).arrayZ;
+    else
+    {
+      unsigned int index = get_index ();
+      if (unlikely ((index + 1) * axis_count > shared_tuples.length))
+        return false;
+      peak_tuple = shared_tuples.sub_array (axis_count * index, axis_count).arrayZ;
+    }
+
+    const F2DOT14 *start_tuple = nullptr;
+    const F2DOT14 *end_tuple = nullptr;
+    bool has_interm = has_intermediate ();
+
+    if (has_interm)
+    {
+      start_tuple = get_start_tuple (axis_count).arrayZ;
+      end_tuple = get_end_tuple (axis_count).arrayZ;
+    }
+
+    for (unsigned i = 0; i < axis_count; i++)
+    {
+      float peak = peak_tuple[i].to_float ();
+      if (peak == 0.f) continue;
+
+      hb_tag_t *axis_tag;
+      if (!axes_old_index_tag_map->has (i, &axis_tag))
+        return false;
+
+      float start, end;
+      if (has_interm)
+      {
+        start = start_tuple[i].to_float ();
+        end = end_tuple[i].to_float ();
+      }
+      else
+      {
+        start = hb_min (peak, 0.f);
+        end = hb_max (peak, 0.f);
+      }
+      axis_tuples.set (*axis_tag, Triple (start, peak, end));
+    }
+
+    return true;
+  }
+
   float calculate_scalar (hb_array_t<int> coords, unsigned int coord_count,
                           const hb_array_t<const F2DOT14> shared_tuples,
-                          const hb_vector_t<int> *shared_tuple_active_idx = nullptr) const
+                          const hb_vector_t<hb_pair_t<int,int>> *shared_tuple_active_idx = nullptr) const
   {
     const F2DOT14 *peak_tuple;
 
     unsigned start_idx = 0;
     unsigned end_idx = coord_count;
+    unsigned step = 1;
 
     if (has_peak ())
       peak_tuple = get_peak_tuple (coord_count).arrayZ;
@@ -270,11 +323,18 @@
 
       if (shared_tuple_active_idx)
       {
-        assert (index < shared_tuple_active_idx->length);
-        int v = (*shared_tuple_active_idx).arrayZ[index];
-        if (v != -1)
+        if (unlikely (index >= shared_tuple_active_idx->length))
+          return 0.f;
+        auto _ = (*shared_tuple_active_idx).arrayZ[index];
+        if (_.second != -1)
         {
-          start_idx = v;
+          start_idx = _.first;
+          end_idx = _.second + 1;
+          step = _.second - _.first;
+        }
+        else if (_.first != -1)
+        {
+          start_idx = _.first;
           end_idx = start_idx + 1;
         }
       }
@@ -290,7 +350,7 @@
     }
 
     float scalar = 1.f;
-    for (unsigned int i = start_idx; i < end_idx; i++)
+    for (unsigned int i = start_idx; i < end_idx; i += step)
     {
       int peak = peak_tuple[i].to_int ();
       if (!peak) continue;
@@ -332,6 +392,7 @@
       TupleIndexMask      = 0x0FFFu
     };
 
+    TuppleIndex& operator = (uint16_t i) { HBUINT16::operator= (i); return *this; }
     DEFINE_SIZE_STATIC (2);
   };
 
@@ -364,6 +425,609 @@
   DEFINE_SIZE_MIN (4);
 };
 
+enum packed_delta_flag_t
+{
+  DELTAS_ARE_ZERO      = 0x80,
+  DELTAS_ARE_WORDS     = 0x40,
+  DELTA_RUN_COUNT_MASK = 0x3F
+};
+
+struct tuple_delta_t
+{
+  public:
+  hb_hashmap_t<hb_tag_t, Triple> axis_tuples;
+
+  /* indices_length = point_count, indice[i] = 1 means point i is referenced */
+  hb_vector_t<bool> indices;
+
+  hb_vector_t<float> deltas_x;
+  /* empty for cvar tuples */
+  hb_vector_t<float> deltas_y;
+
+  /* compiled data: header and deltas
+   * compiled point data is saved in a hashmap within tuple_variations_t cause
+   * some point sets might be reused by different tuple variations */
+  hb_vector_t<char> compiled_tuple_header;
+  hb_vector_t<char> compiled_deltas;
+
+  /* compiled peak coords, empty for non-gvar tuples */
+  hb_vector_t<char> compiled_peak_coords;
+
+  tuple_delta_t () = default;
+  tuple_delta_t (const tuple_delta_t& o) = default;
+
+  friend void swap (tuple_delta_t& a, tuple_delta_t& b)
+  {
+    hb_swap (a.axis_tuples, b.axis_tuples);
+    hb_swap (a.indices, b.indices);
+    hb_swap (a.deltas_x, b.deltas_x);
+    hb_swap (a.deltas_y, b.deltas_y);
+    hb_swap (a.compiled_tuple_header, b.compiled_tuple_header);
+    hb_swap (a.compiled_deltas, b.compiled_deltas);
+    hb_swap (a.compiled_peak_coords, b.compiled_peak_coords);
+  }
+
+  tuple_delta_t (tuple_delta_t&& o) : tuple_delta_t ()
+  { hb_swap (*this, o); }
+
+  tuple_delta_t& operator = (tuple_delta_t&& o)
+  {
+    hb_swap (*this, o);
+    return *this;
+  }
+
+  void remove_axis (hb_tag_t axis_tag)
+  { axis_tuples.del (axis_tag); }
+
+  bool set_tent (hb_tag_t axis_tag, Triple tent)
+  { return axis_tuples.set (axis_tag, tent); }
+
+  tuple_delta_t& operator += (const tuple_delta_t& o)
+  {
+    unsigned num = indices.length;
+    for (unsigned i = 0; i < num; i++)
+    {
+      if (indices.arrayZ[i])
+      {
+        if (o.indices.arrayZ[i])
+        {
+          deltas_x[i] += o.deltas_x[i];
+          if (deltas_y && o.deltas_y)
+            deltas_y[i] += o.deltas_y[i];
+        }
+      }
+      else
+      {
+        if (!o.indices.arrayZ[i]) continue;
+        indices.arrayZ[i] = true;
+        deltas_x[i] = o.deltas_x[i];
+        if (deltas_y && o.deltas_y)
+          deltas_y[i] = o.deltas_y[i];
+      }
+    }
+    return *this;
+  }
+
+  tuple_delta_t& operator *= (float scalar)
+  {
+    if (scalar == 1.0f)
+      return *this;
+
+    unsigned num = indices.length;
+    for (unsigned i = 0; i < num; i++)
+    {
+      if (!indices.arrayZ[i]) continue;
+
+      deltas_x[i] *= scalar;
+      if (deltas_y)
+        deltas_y[i] *= scalar;
+    }
+    return *this;
+  }
+
+  hb_vector_t<tuple_delta_t> change_tuple_var_axis_limit (hb_tag_t axis_tag, Triple axis_limit,
+                                                          TripleDistances axis_triple_distances) const
+  {
+    hb_vector_t<tuple_delta_t> out;
+    Triple *tent;
+    if (!axis_tuples.has (axis_tag, &tent))
+    {
+      out.push (*this);
+      return out;
+    }
+
+    if ((tent->minimum < 0.f && tent->maximum > 0.f) ||
+        !(tent->minimum <= tent->middle && tent->middle <= tent->maximum))
+      return out;
+
+    if (tent->middle == 0.f)
+    {
+      out.push (*this);
+      return out;
+    }
+
+    result_t solutions = rebase_tent (*tent, axis_limit, axis_triple_distances);
+    for (auto t : solutions)
+    {
+      tuple_delta_t new_var = *this;
+      if (t.second == Triple ())
+        new_var.remove_axis (axis_tag);
+      else
+        new_var.set_tent (axis_tag, t.second);
+
+      new_var *= t.first;
+      out.push (std::move (new_var));
+    }
+
+    return out;
+  }
+
+  bool compile_peak_coords (const hb_map_t& axes_index_map,
+                            const hb_map_t& axes_old_index_tag_map)
+  {
+    unsigned axis_count = axes_index_map.get_population ();
+    if (unlikely (!compiled_peak_coords.alloc (axis_count * F2DOT14::static_size)))
+      return false;
+
+    unsigned orig_axis_count = axes_old_index_tag_map.get_population ();
+    for (unsigned i = 0; i < orig_axis_count; i++)
+    {
+      if (!axes_index_map.has (i))
+        continue;
+
+      hb_tag_t axis_tag = axes_old_index_tag_map.get (i);
+      Triple *coords;
+      F2DOT14 peak_coord;
+      if (axis_tuples.has (axis_tag, &coords))
+        peak_coord.set_float (coords->middle);
+      else
+        peak_coord.set_int (0);
+
+      /* push F2DOT14 value into char vector */
+      int16_t val = peak_coord.to_int ();
+      compiled_peak_coords.push (static_cast<char> (val >> 8));
+      compiled_peak_coords.push (static_cast<char> (val & 0xFF));
+    }
+
+    return !compiled_peak_coords.in_error ();
+  }
+
+  /* deltas should be compiled already before we compile tuple
+   * variation header cause we need to fill in the size of the
+   * serialized data for this tuple variation */
+  bool compile_tuple_var_header (const hb_map_t& axes_index_map,
+                                 unsigned points_data_length,
+                                 const hb_map_t& axes_old_index_tag_map,
+                                 const hb_hashmap_t<const hb_vector_t<char>*, unsigned>* shared_tuples_idx_map)
+  {
+    if (!compiled_deltas) return false;
+
+    unsigned cur_axis_count = axes_index_map.get_population ();
+    /* allocate enough memory: 1 peak + 2 intermediate coords + fixed header size */
+    unsigned alloc_len = 3 * cur_axis_count * (F2DOT14::static_size) + 4;
+    if (unlikely (!compiled_tuple_header.resize (alloc_len))) return false;
+
+    unsigned flag = 0;
+    /* skip the first 4 header bytes: variationDataSize+tupleIndex */
+    F2DOT14* p = reinterpret_cast<F2DOT14 *> (compiled_tuple_header.begin () + 4);
+    F2DOT14* end = reinterpret_cast<F2DOT14 *> (compiled_tuple_header.end ());
+    hb_array_t<F2DOT14> coords (p, end - p);
+
+    /* encode peak coords */
+    unsigned peak_count = 0;
+    unsigned *shared_tuple_idx;
+    if (shared_tuples_idx_map &&
+        shared_tuples_idx_map->has (&compiled_peak_coords, &shared_tuple_idx))
+    {
+      flag = *shared_tuple_idx;
+    }
+    else
+    {
+      peak_count = encode_peak_coords(coords, flag, axes_index_map, axes_old_index_tag_map);
+      if (!peak_count) return false;
+    }
+
+    /* encode interim coords, it's optional so returned num could be 0 */
+    unsigned interim_count = encode_interm_coords (coords.sub_array (peak_count), flag, axes_index_map, axes_old_index_tag_map);
+
+    /* pointdata length = 0 implies "use shared points" */
+    if (points_data_length)
+      flag |= TupleVariationHeader::TuppleIndex::PrivatePointNumbers;
+
+    unsigned serialized_data_size = points_data_length + compiled_deltas.length;
+    TupleVariationHeader *o = reinterpret_cast<TupleVariationHeader *> (compiled_tuple_header.begin ());
+    o->varDataSize = serialized_data_size;
+    o->tupleIndex = flag;
+
+    unsigned total_header_len = 4 + (peak_count + interim_count) * (F2DOT14::static_size);
+    return compiled_tuple_header.resize (total_header_len);
+  }
+
+  unsigned encode_peak_coords (hb_array_t<F2DOT14> peak_coords,
+                               unsigned& flag,
+                               const hb_map_t& axes_index_map,
+                               const hb_map_t& axes_old_index_tag_map) const
+  {
+    unsigned orig_axis_count = axes_old_index_tag_map.get_population ();
+    auto it = peak_coords.iter ();
+    unsigned count = 0;
+    for (unsigned i = 0; i < orig_axis_count; i++)
+    {
+      if (!axes_index_map.has (i)) /* axis pinned */
+        continue;
+      hb_tag_t axis_tag = axes_old_index_tag_map.get (i);
+      Triple *coords;
+      if (!axis_tuples.has (axis_tag, &coords))
+        (*it).set_int (0);
+      else
+        (*it).set_float (coords->middle);
+      it++;
+      count++;
+    }
+    flag |= TupleVariationHeader::TuppleIndex::EmbeddedPeakTuple;
+    return count;
+  }
+
+  /* if no need to encode intermediate coords, then just return p */
+  unsigned encode_interm_coords (hb_array_t<F2DOT14> coords,
+                                 unsigned& flag,
+                                 const hb_map_t& axes_index_map,
+                                 const hb_map_t& axes_old_index_tag_map) const
+  {
+    unsigned orig_axis_count = axes_old_index_tag_map.get_population ();
+    unsigned cur_axis_count = axes_index_map.get_population ();
+
+    auto start_coords_iter = coords.sub_array (0, cur_axis_count).iter ();
+    auto end_coords_iter = coords.sub_array (cur_axis_count).iter ();
+    bool encode_needed = false;
+    unsigned count = 0;
+    for (unsigned i = 0; i < orig_axis_count; i++)
+    {
+      if (!axes_index_map.has (i)) /* axis pinned */
+        continue;
+      hb_tag_t axis_tag = axes_old_index_tag_map.get (i);
+      Triple *coords;
+      float min_val = 0.f, val = 0.f, max_val = 0.f;
+      if (axis_tuples.has (axis_tag, &coords))
+      {
+        min_val = coords->minimum;
+        val = coords->middle;
+        max_val = coords->maximum;
+      }
+
+      (*start_coords_iter).set_float (min_val);
+      (*end_coords_iter).set_float (max_val);
+
+      start_coords_iter++;
+      end_coords_iter++;
+      count += 2;
+      if (min_val != hb_min (val, 0.f) || max_val != hb_max (val, 0.f))
+        encode_needed = true;
+    }
+
+    if (encode_needed)
+    {
+      flag |= TupleVariationHeader::TuppleIndex::IntermediateRegion;
+      return count;
+    }
+    return 0;
+  }
+
+  bool compile_deltas ()
+  {
+    hb_vector_t<int> rounded_deltas;
+    if (unlikely (!rounded_deltas.alloc (indices.length)))
+      return false;
+
+    for (unsigned i = 0; i < indices.length; i++)
+    {
+      if (!indices[i]) continue;
+      int rounded_delta = (int) roundf (deltas_x[i]);
+      rounded_deltas.push (rounded_delta);
+    }
+
+    if (!rounded_deltas) return false;
+    /* allocate enough memories 3 * num_deltas */
+    unsigned alloc_len = 3 * rounded_deltas.length;
+    if (deltas_y)
+      alloc_len *= 2;
+
+    if (unlikely (!compiled_deltas.resize (alloc_len))) return false;
+
+    unsigned i = 0;
+    unsigned encoded_len = encode_delta_run (i, compiled_deltas.as_array (), rounded_deltas);
+
+    if (deltas_y)
+    {
+      /* reuse the rounded_deltas vector, check that deltas_y have the same num of deltas as deltas_x */
+      unsigned j = 0;
+      for (unsigned idx = 0; idx < indices.length; idx++)
+      {
+        if (!indices[idx]) continue;
+        int rounded_delta = (int) roundf (deltas_y[idx]);
+
+        if (j >= rounded_deltas.length) return false;
+
+        rounded_deltas[j++] = rounded_delta;
+      }
+
+      if (j != rounded_deltas.length) return false;
+      /* reset i because we reuse rounded_deltas for deltas_y */
+      i = 0;
+      encoded_len += encode_delta_run (i, compiled_deltas.as_array ().sub_array (encoded_len), rounded_deltas);
+    }
+    return compiled_deltas.resize (encoded_len);
+  }
+
+  unsigned encode_delta_run (unsigned& i,
+                             hb_array_t<char> encoded_bytes,
+                             const hb_vector_t<int>& deltas) const
+  {
+    unsigned num_deltas = deltas.length;
+    unsigned encoded_len = 0;
+    while (i < num_deltas)
+    {
+      int val = deltas[i];
+      if (val == 0)
+        encoded_len += encode_delta_run_as_zeroes (i, encoded_bytes.sub_array (encoded_len), deltas);
+      else if (val >= -128 && val <= 127)
+        encoded_len += encode_delta_run_as_bytes (i, encoded_bytes.sub_array (encoded_len), deltas);
+      else
+        encoded_len += encode_delta_run_as_words (i, encoded_bytes.sub_array (encoded_len), deltas);
+    }
+    return encoded_len;
+  }
+
+  unsigned encode_delta_run_as_zeroes (unsigned& i,
+                                       hb_array_t<char> encoded_bytes,
+                                       const hb_vector_t<int>& deltas) const
+  {
+    unsigned num_deltas = deltas.length;
+    unsigned run_length = 0;
+    auto it = encoded_bytes.iter ();
+    unsigned encoded_len = 0;
+    while (i < num_deltas && deltas[i] == 0)
+    {
+      i++;
+      run_length++;
+    }
+
+    while (run_length >= 64)
+    {
+      *it++ = char (DELTAS_ARE_ZERO | 63);
+      run_length -= 64;
+      encoded_len++;
+    }
+
+    if (run_length)
+    {
+      *it++ = char (DELTAS_ARE_ZERO | (run_length - 1));
+      encoded_len++;
+    }
+    return encoded_len;
+  }
+
+  unsigned encode_delta_run_as_bytes (unsigned &i,
+                                      hb_array_t<char> encoded_bytes,
+                                      const hb_vector_t<int>& deltas) const
+  {
+    unsigned start = i;
+    unsigned num_deltas = deltas.length;
+    while (i < num_deltas)
+    {
+      int val = deltas[i];
+      if (val > 127 || val < -128)
+        break;
+
+      /* from fonttools: if there're 2 or more zeros in a sequence,
+       * it is better to start a new run to save bytes. */
+      if (val == 0 && i + 1 < num_deltas && deltas[i+1] == 0)
+        break;
+
+      i++;
+    }
+    unsigned run_length = i - start;
+
+    unsigned encoded_len = 0;
+    auto it = encoded_bytes.iter ();
+
+    while (run_length >= 64)
+    {
+      *it++ = 63;
+      encoded_len++;
+
+      for (unsigned j = 0; j < 64; j++)
+      {
+        *it++ = static_cast<char> (deltas[start + j]);
+        encoded_len++;
+      }
+
+      start += 64;
+      run_length -= 64;
+    }
+
+    if (run_length)
+    {
+      *it++ = run_length - 1;
+      encoded_len++;
+
+      while (start < i)
+      {
+        *it++ = static_cast<char> (deltas[start++]);
+        encoded_len++;
+      }
+    }
+
+    return encoded_len;
+  }
+
+  unsigned encode_delta_run_as_words (unsigned &i,
+                                      hb_array_t<char> encoded_bytes,
+                                      const hb_vector_t<int>& deltas) const
+  {
+    unsigned start = i;
+    unsigned num_deltas = deltas.length;
+    while (i < num_deltas)
+    {
+      int val = deltas[i];
+
+      /* start a new run for a single zero value*/
+      if (val == 0) break;
+
+      /* from fonttools: continue word-encoded run if there's only one
+       * single value in the range [-128, 127] because it is more compact.
+       * Only start a new run when there're 2 continuous such values. */
+      if (val >= -128 && val <= 127 &&
+          i + 1 < num_deltas &&
+          deltas[i+1] >= -128 && deltas[i+1] <= 127)
+        break;
+
+      i++;
+    }
+
+    unsigned run_length = i - start;
+    auto it = encoded_bytes.iter ();
+    unsigned encoded_len = 0;
+    while (run_length >= 64)
+    {
+      *it++ = (DELTAS_ARE_WORDS | 63);
+      encoded_len++;
+
+      for (unsigned j = 0; j < 64; j++)
+      {
+        int16_t delta_val = deltas[start + j];
+        *it++ = static_cast<char> (delta_val >> 8);
+        *it++ = static_cast<char> (delta_val & 0xFF);
+
+        encoded_len += 2;
+      }
+
+      start += 64;
+      run_length -= 64;
+    }
+
+    if (run_length)
+    {
+      *it++ = (DELTAS_ARE_WORDS | (run_length - 1));
+      encoded_len++;
+      while (start < i)
+      {
+        int16_t delta_val = deltas[start++];
+        *it++ = static_cast<char> (delta_val >> 8);
+        *it++ = static_cast<char> (delta_val & 0xFF);
+
+        encoded_len += 2;
+      }
+    }
+    return encoded_len;
+  }
+
+  bool calc_inferred_deltas (const contour_point_vector_t& orig_points)
+  {
+    unsigned point_count = orig_points.length;
+    if (point_count != indices.length)
+      return false;
+
+    unsigned ref_count = 0;
+    hb_vector_t<unsigned> end_points;
+
+    for (unsigned i = 0; i < point_count; i++)
+    {
+      if (indices.arrayZ[i])
+        ref_count++;
+      if (orig_points.arrayZ[i].is_end_point)
+        end_points.push (i);
+    }
+    /* all points are referenced, nothing to do */
+    if (ref_count == point_count)
+      return true;
+    if (unlikely (end_points.in_error ())) return false;
+
+    hb_set_t inferred_idxes;
+    unsigned start_point = 0;
+    for (unsigned end_point : end_points)
+    {
+      /* Check the number of unreferenced points in a contour. If no unref points or no ref points, nothing to do. */
+      unsigned unref_count = 0;
+      for (unsigned i = start_point; i < end_point + 1; i++)
+        unref_count += indices.arrayZ[i];
+      unref_count = (end_point - start_point + 1) - unref_count;
+
+      unsigned j = start_point;
+      if (unref_count == 0 || unref_count > end_point - start_point)
+        goto no_more_gaps;
+      for (;;)
+      {
+        /* Locate the next gap of unreferenced points between two referenced points prev and next.
+         * Note that a gap may wrap around at left (start_point) and/or at right (end_point).
+         */
+        unsigned int prev, next, i;
+        for (;;)
+        {
+          i = j;
+          j = next_index (i, start_point, end_point);
+          if (indices.arrayZ[i] && !indices.arrayZ[j]) break;
+        }
+        prev = j = i;
+        for (;;)
+        {
+          i = j;
+          j = next_index (i, start_point, end_point);
+          if (!indices.arrayZ[i] && indices.arrayZ[j]) break;
+        }
+        next = j;
+       /* Infer deltas for all unref points in the gap between prev and next */
+        i = prev;
+        for (;;)
+        {
+          i = next_index (i, start_point, end_point);
+          if (i == next) break;
+          deltas_x.arrayZ[i] = infer_delta (orig_points.arrayZ[i].x, orig_points.arrayZ[prev].x, orig_points.arrayZ[next].x,
+                                            deltas_x.arrayZ[prev], deltas_x.arrayZ[next]);
+          deltas_y.arrayZ[i] = infer_delta (orig_points.arrayZ[i].y, orig_points.arrayZ[prev].y, orig_points.arrayZ[next].y,
+                                            deltas_y.arrayZ[prev], deltas_y.arrayZ[next]);
+          inferred_idxes.add (i);
+          if (--unref_count == 0) goto no_more_gaps;
+        }
+      }
+    no_more_gaps:
+      start_point = end_point + 1;
+    }
+
+    for (unsigned i = 0; i < point_count; i++)
+    {
+      /* if points are not referenced and deltas are not inferred, set to 0.
+       * reference all points for gvar */
+      if ( !indices[i])
+      {
+        if (!inferred_idxes.has (i))
+        {
+          deltas_x.arrayZ[i] = 0.f;
+          deltas_y.arrayZ[i] = 0.f;
+        }
+        indices[i] = true;
+      }
+    }
+    return true;
+  }
+
+  static float infer_delta (float target_val, float prev_val, float next_val, float prev_delta, float next_delta)
+  {
+    if (prev_val == next_val)
+      return (prev_delta == next_delta) ? prev_delta : 0.f;
+    else if (target_val <= hb_min (prev_val, next_val))
+      return (prev_val < next_val) ? prev_delta : next_delta;
+    else if (target_val >= hb_max (prev_val, next_val))
+      return (prev_val > next_val) ? prev_delta : next_delta;
+
+    float r = (target_val - prev_val) / (next_val - prev_val);
+    return prev_delta + r * (next_delta - prev_delta);
+  }
+
+  static unsigned int next_index (unsigned int i, unsigned int start, unsigned int end)
+  { return (i >= end) ? start : (i + 1); }
+};
+
 struct TupleVariationData
 {
   bool sanitize (hb_sanitize_context_t *c) const
@@ -377,7 +1041,7 @@
   unsigned get_size (unsigned axis_count) const
   {
     unsigned total_size = min_size;
-    unsigned count = tupleVarCount;
+    unsigned count = tupleVarCount.get_count ();
     const TupleVariationHeader *tuple_var_header = &(get_tuple_var_header());
     for (unsigned i = 0; i < count; i++)
     {
@@ -391,8 +1055,485 @@
   const TupleVariationHeader &get_tuple_var_header (void) const
   { return StructAfter<TupleVariationHeader> (data); }
 
+  struct tuple_iterator_t;
+  struct tuple_variations_t
+  {
+    hb_vector_t<tuple_delta_t> tuple_vars;
+
+    private:
+    /* referenced point set->compiled point data map */
+    hb_hashmap_t<const hb_vector_t<bool>*, hb_bytes_t> point_data_map;
+    /* referenced point set-> count map, used in finding shared points */
+    hb_hashmap_t<const hb_vector_t<bool>*, unsigned> point_set_count_map;
+
+    /* empty for non-gvar tuples.
+     * shared_points_bytes is just a copy of some value in the point_data_map,
+     * which will be freed during map destruction. Save it for serialization, so
+     * no need to do find_shared_points () again */
+    hb_bytes_t shared_points_bytes;
+
+    /* total compiled byte size as TupleVariationData format, initialized to its
+     * min_size: 4 */
+    unsigned compiled_byte_size = 4;
+
+    public:
+    tuple_variations_t () = default;
+    tuple_variations_t (const tuple_variations_t&) = delete;
+    tuple_variations_t& operator=(const tuple_variations_t&) = delete;
+    tuple_variations_t (tuple_variations_t&&) = default;
+    tuple_variations_t& operator=(tuple_variations_t&&) = default;
+    ~tuple_variations_t () { fini (); }
+    void fini ()
+    {
+      for (auto _ : point_data_map.values ())
+        _.fini ();
+
+      point_set_count_map.fini ();
+      tuple_vars.fini ();
+    }
+
+    explicit operator bool () const { return bool (tuple_vars); }
+    unsigned get_var_count () const
+    {
+      unsigned count = tuple_vars.length;
+      if (shared_points_bytes.length)
+        count |= TupleVarCount::SharedPointNumbers;
+      return count;
+    }
+
+    unsigned get_compiled_byte_size () const
+    { return compiled_byte_size; }
+
+    bool create_from_tuple_var_data (tuple_iterator_t iterator,
+                                     unsigned tuple_var_count,
+                                     unsigned point_count,
+                                     bool is_gvar,
+                                     const hb_map_t *axes_old_index_tag_map,
+                                     const hb_vector_t<unsigned> &shared_indices,
+                                     const hb_array_t<const F2DOT14> shared_tuples)
+    {
+      do
+      {
+        const HBUINT8 *p = iterator.get_serialized_data ();
+        unsigned int length = iterator.current_tuple->get_data_size ();
+        if (unlikely (!iterator.var_data_bytes.check_range (p, length)))
+        { fini (); return false; }
+
+        hb_hashmap_t<hb_tag_t, Triple> axis_tuples;
+        if (!iterator.current_tuple->unpack_axis_tuples (iterator.get_axis_count (), shared_tuples, axes_old_index_tag_map, axis_tuples)
+            || axis_tuples.is_empty ())
+        { fini (); return false; }
+
+        hb_vector_t<unsigned> private_indices;
+        bool has_private_points = iterator.current_tuple->has_private_points ();
+        const HBUINT8 *end = p + length;
+        if (has_private_points &&
+            !TupleVariationData::unpack_points (p, private_indices, end))
+        { fini (); return false; }
+
+        const hb_vector_t<unsigned> &indices = has_private_points ? private_indices : shared_indices;
+        bool apply_to_all = (indices.length == 0);
+        unsigned num_deltas = apply_to_all ? point_count : indices.length;
+
+        hb_vector_t<int> deltas_x;
+
+        if (unlikely (!deltas_x.resize (num_deltas, false) ||
+                      !TupleVariationData::unpack_deltas (p, deltas_x, end)))
+        { fini (); return false; }
+
+        hb_vector_t<int> deltas_y;
+        if (is_gvar)
+        {
+          if (unlikely (!deltas_y.resize (num_deltas, false) ||
+                        !TupleVariationData::unpack_deltas (p, deltas_y, end)))
+          { fini (); return false; }
+        }
+
+        tuple_delta_t var;
+        var.axis_tuples = std::move (axis_tuples);
+        if (unlikely (!var.indices.resize (point_count) ||
+                      !var.deltas_x.resize (point_count, false)))
+        { fini (); return false; }
+
+        if (is_gvar && unlikely (!var.deltas_y.resize (point_count, false)))
+        { fini (); return false; }
+
+        for (unsigned i = 0; i < num_deltas; i++)
+        {
+          unsigned idx = apply_to_all ? i : indices[i];
+          if (idx >= point_count) continue;
+          var.indices[idx] = true;
+          var.deltas_x[idx] = static_cast<float> (deltas_x[i]);
+          if (is_gvar)
+            var.deltas_y[idx] = static_cast<float> (deltas_y[i]);
+        }
+        tuple_vars.push (std::move (var));
+      } while (iterator.move_to_next ());
+      return true;
+    }
+
+    bool create_from_item_var_data (const VarData &var_data,
+                                    const hb_vector_t<hb_hashmap_t<hb_tag_t, Triple>>& regions,
+                                    const hb_map_t& axes_old_index_tag_map,
+                                    const hb_inc_bimap_t* inner_map = nullptr)
+    {
+      /* NULL offset, to keep original varidx valid, just return */
+      if (&var_data == &Null (VarData))
+        return true;
+
+      unsigned num_regions = var_data.get_region_index_count ();
+      if (!tuple_vars.alloc (num_regions)) return false;
+
+      unsigned item_count = inner_map ? inner_map->get_population () : var_data.get_item_count ();
+      unsigned row_size = var_data.get_row_size ();
+      const HBUINT8 *delta_bytes = var_data.get_delta_bytes ();
+
+      for (unsigned r = 0; r < num_regions; r++)
+      {
+        /* In VarData, deltas are organized in rows, convert them into
+         * column(region) based tuples, resize deltas_x first */
+        tuple_delta_t tuple;
+        if (!tuple.deltas_x.resize (item_count, false) ||
+            !tuple.indices.resize (item_count, false))
+          return false;
+
+        for (unsigned i = 0; i < item_count; i++)
+        {
+          tuple.indices.arrayZ[i] = true;
+          tuple.deltas_x.arrayZ[i] = var_data.get_item_delta_fast (inner_map ? inner_map->backward (i) : i,
+                                                                   r, delta_bytes, row_size);
+        }
+
+        unsigned region_index = var_data.get_region_index (r);
+        if (region_index >= regions.length) return false;
+        tuple.axis_tuples = regions.arrayZ[region_index];
+
+        tuple_vars.push (std::move (tuple));
+      }
+      return !tuple_vars.in_error ();
+    }
+
+    private:
+    static int _cmp_axis_tag (const void *pa, const void *pb)
+    {
+      const hb_tag_t *a = (const hb_tag_t*) pa;
+      const hb_tag_t *b = (const hb_tag_t*) pb;
+      return (int)(*a) - (int)(*b);
+    }
+
+    bool change_tuple_variations_axis_limits (const hb_hashmap_t<hb_tag_t, Triple>& normalized_axes_location,
+                                              const hb_hashmap_t<hb_tag_t, TripleDistances>& axes_triple_distances)
+    {
+      /* sort axis_tag/axis_limits, make result deterministic */
+      hb_vector_t<hb_tag_t> axis_tags;
+      if (!axis_tags.alloc (normalized_axes_location.get_population ()))
+        return false;
+      for (auto t : normalized_axes_location.keys ())
+        axis_tags.push (t);
+
+      axis_tags.qsort (_cmp_axis_tag);
+      for (auto axis_tag : axis_tags)
+      {
+        Triple *axis_limit;
+        if (!normalized_axes_location.has (axis_tag, &axis_limit))
+          return false;
+        TripleDistances axis_triple_distances{1.f, 1.f};
+        if (axes_triple_distances.has (axis_tag))
+          axis_triple_distances = axes_triple_distances.get (axis_tag);
+
+        hb_vector_t<tuple_delta_t> new_vars;
+        for (const tuple_delta_t& var : tuple_vars)
+        {
+          hb_vector_t<tuple_delta_t> out = var.change_tuple_var_axis_limit (axis_tag, *axis_limit, axis_triple_distances);
+          if (!out) continue;
+
+          unsigned new_len = new_vars.length + out.length;
+
+          if (unlikely (!new_vars.alloc (new_len, false)))
+          { fini (); return false;}
+
+          for (unsigned i = 0; i < out.length; i++)
+            new_vars.push (std::move (out[i]));
+        }
+        tuple_vars.fini ();
+        tuple_vars = std::move (new_vars);
+      }
+      return true;
+    }
+
+    /* merge tuple variations with overlapping tents */
+    void merge_tuple_variations ()
+    {
+      hb_vector_t<tuple_delta_t> new_vars;
+      hb_hashmap_t<const hb_hashmap_t<hb_tag_t, Triple>*, unsigned> m;
+      unsigned i = 0;
+      for (const tuple_delta_t& var : tuple_vars)
+      {
+        /* if all axes are pinned, drop the tuple variation */
+        if (var.axis_tuples.is_empty ()) continue;
+
+        unsigned *idx;
+        if (m.has (&(var.axis_tuples), &idx))
+        {
+          new_vars[*idx] += var;
+        }
+        else
+        {
+          new_vars.push (var);
+          m.set (&(var.axis_tuples), i);
+          i++;
+        }
+      }
+      tuple_vars.fini ();
+      tuple_vars = std::move (new_vars);
+    }
+
+    hb_bytes_t compile_point_set (const hb_vector_t<bool> &point_indices)
+    {
+      unsigned num_points = 0;
+      for (bool i : point_indices)
+        if (i) num_points++;
+
+      unsigned indices_length = point_indices.length;
+      /* If the points set consists of all points in the glyph, it's encoded with a
+       * single zero byte */
+      if (num_points == indices_length)
+      {
+        char *p = (char *) hb_calloc (1, sizeof (char));
+        if (unlikely (!p)) return hb_bytes_t ();
+
+        return hb_bytes_t (p, 1);
+      }
+
+      /* allocate enough memories: 2 bytes for count + 3 bytes for each point */
+      unsigned num_bytes = 2 + 3 *num_points;
+      char *p = (char *) hb_calloc (num_bytes, sizeof (char));
+      if (unlikely (!p)) return hb_bytes_t ();
+
+      unsigned pos = 0;
+      /* binary data starts with the total number of reference points */
+      if (num_points < 0x80)
+        p[pos++] = num_points;
+      else
+      {
+        p[pos++] = ((num_points >> 8) | 0x80);
+        p[pos++] = num_points & 0xFF;
+      }
+
+      const unsigned max_run_length = 0x7F;
+      unsigned i = 0;
+      unsigned last_value = 0;
+      unsigned num_encoded = 0;
+      while (i < indices_length && num_encoded < num_points)
+      {
+        unsigned run_length = 0;
+        unsigned header_pos = pos;
+        p[pos++] = 0;
+
+        bool use_byte_encoding = false;
+        bool new_run = true;
+        while (i < indices_length && num_encoded < num_points &&
+               run_length <= max_run_length)
+        {
+          // find out next referenced point index
+          while (i < indices_length && !point_indices[i])
+            i++;
+
+          if (i >= indices_length) break;
+
+          unsigned cur_value = i;
+          unsigned delta = cur_value - last_value;
+
+          if (new_run)
+          {
+            use_byte_encoding = (delta <= 0xFF);
+            new_run = false;
+          }
+
+          if (use_byte_encoding && delta > 0xFF)
+            break;
+
+          if (use_byte_encoding)
+            p[pos++] = delta;
+          else
+          {
+            p[pos++] = delta >> 8;
+            p[pos++] = delta & 0xFF;
+          }
+          i++;
+          last_value = cur_value;
+          run_length++;
+          num_encoded++;
+        }
+
+        if (use_byte_encoding)
+          p[header_pos] = run_length - 1;
+        else
+          p[header_pos] = (run_length - 1) | 0x80;
+      }
+      return hb_bytes_t (p, pos);
+    }
+
+    /* compile all point set and store byte data in a point_set->hb_bytes_t hashmap,
+     * also update point_set->count map, which will be used in finding shared
+     * point set*/
+    bool compile_all_point_sets ()
+    {
+      for (const auto& tuple: tuple_vars)
+      {
+        const hb_vector_t<bool>* points_set = &(tuple.indices);
+        if (point_data_map.has (points_set))
+        {
+          unsigned *count;
+          if (unlikely (!point_set_count_map.has (points_set, &count) ||
+                        !point_set_count_map.set (points_set, (*count) + 1)))
+            return false;
+          continue;
+        }
+
+        hb_bytes_t compiled_data = compile_point_set (*points_set);
+        if (unlikely (compiled_data == hb_bytes_t ()))
+          return false;
+
+        if (!point_data_map.set (points_set, compiled_data) ||
+            !point_set_count_map.set (points_set, 1))
+          return false;
+      }
+      return true;
+    }
+
+    /* find shared points set which saves most bytes */
+    hb_bytes_t find_shared_points ()
+    {
+      unsigned max_saved_bytes = 0;
+      hb_bytes_t res{};
+
+      for (const auto& _ : point_data_map.iter ())
+      {
+        const hb_vector_t<bool>* points_set = _.first;
+        unsigned data_length = _.second.length;
+        unsigned *count;
+        if (unlikely (!point_set_count_map.has (points_set, &count) ||
+                      *count <= 1))
+          return hb_bytes_t ();
+
+        unsigned saved_bytes = data_length * ((*count) -1);
+        if (saved_bytes > max_saved_bytes)
+        {
+          max_saved_bytes = saved_bytes;
+          res = _.second;
+        }
+      }
+      return res;
+    }
+
+    bool calc_inferred_deltas (contour_point_vector_t& contour_points)
+    {
+      for (tuple_delta_t& var : tuple_vars)
+        if (!var.calc_inferred_deltas (contour_points))
+          return false;
+
+      return true;
+    }
+
+    public:
+    bool instantiate (const hb_hashmap_t<hb_tag_t, Triple>& normalized_axes_location,
+                      const hb_hashmap_t<hb_tag_t, TripleDistances>& axes_triple_distances,
+                      contour_point_vector_t* contour_points = nullptr)
+    {
+      if (!tuple_vars) return true;
+      if (!change_tuple_variations_axis_limits (normalized_axes_location, axes_triple_distances))
+        return false;
+      /* compute inferred deltas only for gvar */
+      if (contour_points)
+        if (!calc_inferred_deltas (*contour_points))
+          return false;
+
+      merge_tuple_variations ();
+      return !tuple_vars.in_error ();
+    }
+
+    bool compile_bytes (const hb_map_t& axes_index_map,
+                        const hb_map_t& axes_old_index_tag_map,
+                        bool use_shared_points,
+                        const hb_hashmap_t<const hb_vector_t<char>*, unsigned>* shared_tuples_idx_map = nullptr)
+    {
+      // compile points set and store data in hashmap
+      if (!compile_all_point_sets ())
+        return false;
+
+      if (use_shared_points)
+      {
+        shared_points_bytes = find_shared_points ();
+        compiled_byte_size += shared_points_bytes.length;
+      }
+      // compile delta and tuple var header for each tuple variation
+      for (auto& tuple: tuple_vars)
+      {
+        const hb_vector_t<bool>* points_set = &(tuple.indices);
+        hb_bytes_t *points_data;
+        if (unlikely (!point_data_map.has (points_set, &points_data)))
+          return false;
+
+        if (!tuple.compile_deltas ())
+          return false;
+
+        unsigned points_data_length = (*points_data != shared_points_bytes) ? points_data->length : 0;
+        if (!tuple.compile_tuple_var_header (axes_index_map, points_data_length, axes_old_index_tag_map,
+                                             shared_tuples_idx_map))
+          return false;
+        compiled_byte_size += tuple.compiled_tuple_header.length + points_data_length + tuple.compiled_deltas.length;
+      }
+      return true;
+    }
+
+    bool serialize_var_headers (hb_serialize_context_t *c, unsigned& total_header_len) const
+    {
+      TRACE_SERIALIZE (this);
+      for (const auto& tuple: tuple_vars)
+      {
+        tuple.compiled_tuple_header.as_array ().copy (c);
+        if (c->in_error ()) return_trace (false);
+        total_header_len += tuple.compiled_tuple_header.length;
+      }
+      return_trace (true);
+    }
+
+    bool serialize_var_data (hb_serialize_context_t *c, bool is_gvar) const
+    {
+      TRACE_SERIALIZE (this);
+      if (is_gvar)
+        shared_points_bytes.copy (c);
+
+      for (const auto& tuple: tuple_vars)
+      {
+        const hb_vector_t<bool>* points_set = &(tuple.indices);
+        hb_bytes_t *point_data;
+        if (!point_data_map.has (points_set, &point_data))
+          return_trace (false);
+
+        if (!is_gvar || *point_data != shared_points_bytes)
+          point_data->copy (c);
+
+        tuple.compiled_deltas.as_array ().copy (c);
+        if (c->in_error ()) return_trace (false);
+      }
+
+      /* padding for gvar */
+      if (is_gvar && (compiled_byte_size % 2))
+      {
+        HBUINT8 pad;
+        pad = 0;
+        if (!c->embed (pad)) return_trace (false);
+      }
+      return_trace (true);
+    }
+  };
+
   struct tuple_iterator_t
   {
+    unsigned get_axis_count () const { return axis_count; }
+
     void init (hb_bytes_t var_data_bytes_, unsigned int axis_count_, const void *table_base_)
     {
       var_data_bytes = var_data_bytes_;
@@ -516,13 +1657,6 @@
                              hb_vector_t<int> &deltas /* IN/OUT */,
                              const HBUINT8 *end)
   {
-    enum packed_delta_flag_t
-    {
-      DELTAS_ARE_ZERO      = 0x80,
-      DELTAS_ARE_WORDS     = 0x40,
-      DELTA_RUN_COUNT_MASK = 0x3F
-    };
-
     unsigned i = 0;
     unsigned count = deltas.length;
     while (i < count)
@@ -560,11 +1694,55 @@
 
   bool has_data () const { return tupleVarCount; }
 
+  bool decompile_tuple_variations (unsigned point_count,
+                                   bool is_gvar,
+                                   tuple_iterator_t iterator,
+                                   const hb_map_t *axes_old_index_tag_map,
+                                   const hb_vector_t<unsigned> &shared_indices,
+                                   const hb_array_t<const F2DOT14> shared_tuples,
+                                   tuple_variations_t& tuple_variations /* OUT */) const
+  {
+    return tuple_variations.create_from_tuple_var_data (iterator, tupleVarCount,
+                                                        point_count, is_gvar,
+                                                        axes_old_index_tag_map,
+                                                        shared_indices,
+                                                        shared_tuples);
+  }
+
+  bool serialize (hb_serialize_context_t *c,
+                  bool is_gvar,
+                  const tuple_variations_t& tuple_variations) const
+  {
+    TRACE_SERIALIZE (this);
+    /* empty tuple variations, just return and skip serialization. */
+    if (!tuple_variations) return_trace (true);
+
+    auto *out = c->start_embed (this);
+    if (unlikely (!c->extend_min (out))) return_trace (false);
+
+    if (!c->check_assign (out->tupleVarCount, tuple_variations.get_var_count (),
+                          HB_SERIALIZE_ERROR_INT_OVERFLOW)) return_trace (false);
+
+    unsigned total_header_len = 0;
+
+    if (!tuple_variations.serialize_var_headers (c, total_header_len))
+      return_trace (false);
+
+    unsigned data_offset = min_size + total_header_len;
+    if (!is_gvar) data_offset += 4;
+    if (!c->check_assign (out->data, data_offset, HB_SERIALIZE_ERROR_INT_OVERFLOW)) return_trace (false);
+
+    return tuple_variations.serialize_var_data (c, is_gvar);
+  }
+
   protected:
   struct TupleVarCount : HBUINT16
   {
+    friend struct tuple_variations_t;
     bool has_shared_point_numbers () const { return ((*this) & SharedPointNumbers); }
     unsigned int get_count () const { return (*this) & CountMask; }
+    TupleVarCount& operator = (uint16_t i) { HBUINT16::operator= (i); return *this; }
+    explicit operator bool () const { return get_count (); }
 
     protected:
     enum Flags
@@ -588,6 +1766,463 @@
   DEFINE_SIZE_MIN (4);
 };
 
+using tuple_variations_t = TupleVariationData::tuple_variations_t;
+struct item_variations_t
+{
+  using region_t = const hb_hashmap_t<hb_tag_t, Triple>*;
+  private:
+  /* each subtable is decompiled into a tuple_variations_t, in which all tuples
+   * have the same num of deltas (rows) */
+  hb_vector_t<tuple_variations_t> vars;
+
+  /* original region list, decompiled from item varstore, used when rebuilding
+   * region list after instantiation */
+  hb_vector_t<hb_hashmap_t<hb_tag_t, Triple>> orig_region_list;
+
+  /* region list: vector of Regions, maintain the original order for the regions
+   * that existed before instantiate (), append the new regions at the end.
+   * Regions are stored in each tuple already, save pointers only.
+   * When converting back to item varstore, unused regions will be pruned */
+  hb_vector_t<region_t> region_list;
+
+  /* region -> idx map after instantiation and pruning unused regions */
+  hb_hashmap_t<region_t, unsigned> region_map;
+
+  /* all delta rows after instantiation */
+  hb_vector_t<hb_vector_t<int>> delta_rows;
+  /* final optimized vector of encoding objects used to assemble the varstore */
+  hb_vector_t<delta_row_encoding_t> encodings;
+
+  /* old varidxes -> new var_idxes map */
+  hb_map_t varidx_map;
+
+  /* has long words */
+  bool has_long = false;
+
+  public:
+  bool has_long_word () const
+  { return has_long; }
+
+  const hb_vector_t<region_t>& get_region_list () const
+  { return region_list; }
+
+  const hb_vector_t<delta_row_encoding_t>& get_vardata_encodings () const
+  { return encodings; }
+
+  const hb_map_t& get_varidx_map () const
+  { return varidx_map; }
+
+  bool instantiate (const VariationStore& varStore,
+                    const hb_subset_plan_t *plan,
+                    bool optimize=true,
+                    bool use_no_variation_idx=true,
+                    const hb_array_t <const hb_inc_bimap_t> inner_maps = hb_array_t<const hb_inc_bimap_t> ())
+  {
+    if (!create_from_item_varstore (varStore, plan->axes_old_index_tag_map, inner_maps))
+      return false;
+    if (!instantiate_tuple_vars (plan->axes_location, plan->axes_triple_distances))
+      return false;
+    return as_item_varstore (optimize, use_no_variation_idx);
+  }
+
+  /* keep below APIs public only for unit test: test-item-varstore */
+  bool create_from_item_varstore (const VariationStore& varStore,
+                                  const hb_map_t& axes_old_index_tag_map,
+                                  const hb_array_t <const hb_inc_bimap_t> inner_maps = hb_array_t<const hb_inc_bimap_t> ())
+  {
+    const VarRegionList& regionList = varStore.get_region_list ();
+    if (!regionList.get_var_regions (axes_old_index_tag_map, orig_region_list))
+      return false;
+
+    unsigned num_var_data = varStore.get_sub_table_count ();
+    if (inner_maps && inner_maps.length != num_var_data) return false;
+    if (!vars.alloc (num_var_data)) return false;
+
+    for (unsigned i = 0; i < num_var_data; i++)
+    {
+      if (inner_maps && !inner_maps.arrayZ[i].get_population ())
+          continue;
+      tuple_variations_t var_data_tuples;
+      if (!var_data_tuples.create_from_item_var_data (varStore.get_sub_table (i),
+                                                      orig_region_list,
+                                                      axes_old_index_tag_map,
+                                                      inner_maps ? &(inner_maps.arrayZ[i]) : nullptr))
+        return false;
+
+      vars.push (std::move (var_data_tuples));
+    }
+    return !vars.in_error ();
+  }
+
+  bool instantiate_tuple_vars (const hb_hashmap_t<hb_tag_t, Triple>& normalized_axes_location,
+                               const hb_hashmap_t<hb_tag_t, TripleDistances>& axes_triple_distances)
+  {
+    for (tuple_variations_t& tuple_vars : vars)
+      if (!tuple_vars.instantiate (normalized_axes_location, axes_triple_distances))
+        return false;
+
+    if (!build_region_list ()) return false;
+    return true;
+  }
+
+  bool build_region_list ()
+  {
+    /* scan all tuples and collect all unique regions, prune unused regions */
+    hb_hashmap_t<region_t, unsigned> all_regions;
+    hb_hashmap_t<region_t, unsigned> used_regions;
+
+    /* use a vector when inserting new regions, make result deterministic */
+    hb_vector_t<region_t> all_unique_regions;
+    for (const tuple_variations_t& sub_table : vars)
+    {
+      for (const tuple_delta_t& tuple : sub_table.tuple_vars)
+      {
+        region_t r = &(tuple.axis_tuples);
+        if (!used_regions.has (r))
+        {
+          bool all_zeros = true;
+          for (float d : tuple.deltas_x)
+          {
+            int delta = (int) roundf (d);
+            if (delta != 0)
+            {
+              all_zeros = false;
+              break;
+            }
+          }
+          if (!all_zeros)
+          {
+            if (!used_regions.set (r, 1))
+              return false;
+          }
+        }
+        if (all_regions.has (r))
+          continue;
+        if (!all_regions.set (r, 1))
+          return false;
+        all_unique_regions.push (r);
+      }
+    }
+
+    if (!all_regions || !all_unique_regions) return false;
+    if (!region_list.alloc (all_regions.get_population ()))
+      return false;
+
+    unsigned idx = 0;
+    /* append the original regions that pre-existed */
+    for (const auto& r : orig_region_list)
+    {
+      if (!all_regions.has (&r) || !used_regions.has (&r))
+        continue;
+
+      region_list.push (&r);
+      if (!region_map.set (&r, idx))
+        return false;
+      all_regions.del (&r);
+      idx++;
+    }
+
+    /* append the new regions at the end */
+    for (const auto& r: all_unique_regions)
+    {
+      if (!all_regions.has (r) || !used_regions.has (r))
+        continue;
+      region_list.push (r);
+      if (!region_map.set (r, idx))
+        return false;
+      all_regions.del (r);
+      idx++;
+    }
+    return (!region_list.in_error ()) && (!region_map.in_error ());
+  }
+
+  /* main algorithm ported from fonttools VarStore_optimize() method, optimize
+   * varstore by default */
+
+  struct combined_gain_idx_tuple_t
+  {
+    int gain;
+    unsigned idx_1;
+    unsigned idx_2;
+
+    combined_gain_idx_tuple_t () = default;
+    combined_gain_idx_tuple_t (int gain_, unsigned i, unsigned j)
+        :gain (gain_), idx_1 (i), idx_2 (j) {}
+
+    bool operator < (const combined_gain_idx_tuple_t& o)
+    {
+      if (gain != o.gain)
+        return gain < o.gain;
+
+      if (idx_1 != o.idx_1)
+        return idx_1 < o.idx_1;
+
+      return idx_2 < o.idx_2;
+    }
+
+    bool operator <= (const combined_gain_idx_tuple_t& o)
+    {
+      if (*this < o) return true;
+      return gain == o.gain && idx_1 == o.idx_1 && idx_2 == o.idx_2;
+    }
+  };
+
+  bool as_item_varstore (bool optimize=true, bool use_no_variation_idx=true)
+  {
+    if (!region_list) return false;
+    unsigned num_cols = region_list.length;
+    /* pre-alloc a 2D vector for all sub_table's VarData rows */
+    unsigned total_rows = 0;
+    for (unsigned major = 0; major < vars.length; major++)
+    {
+      const tuple_variations_t& tuples = vars[major];
+      /* all tuples in each sub_table should have same num of deltas(num rows) */
+      total_rows += tuples.tuple_vars[0].deltas_x.length;
+    }
+
+    if (!delta_rows.resize (total_rows)) return false;
+    /* init all rows to [0]*num_cols */
+    for (unsigned i = 0; i < total_rows; i++)
+      if (!(delta_rows[i].resize (num_cols))) return false;
+
+    /* old VarIdxes -> full encoding_row mapping */
+    hb_hashmap_t<unsigned, const hb_vector_t<int>*> front_mapping;
+    unsigned start_row = 0;
+    hb_vector_t<delta_row_encoding_t> encoding_objs;
+    hb_hashmap_t<hb_vector_t<uint8_t>, unsigned> chars_idx_map;
+
+    /* delta_rows map, used for filtering out duplicate rows */
+    hb_hashmap_t<const hb_vector_t<int>*, unsigned> delta_rows_map;
+    for (unsigned major = 0; major < vars.length; major++)
+    {
+      /* deltas are stored in tuples(column based), convert them back into items
+       * (row based) delta */
+      const tuple_variations_t& tuples = vars[major];
+      unsigned num_rows = tuples.tuple_vars[0].deltas_x.length;
+      for (const tuple_delta_t& tuple: tuples.tuple_vars)
+      {
+        if (tuple.deltas_x.length != num_rows)
+          return false;
+
+        /* skip unused regions */
+        unsigned *col_idx;
+        if (!region_map.has (&(tuple.axis_tuples), &col_idx))
+          continue;
+
+        for (unsigned i = 0; i < num_rows; i++)
+        {
+          int rounded_delta = roundf (tuple.deltas_x[i]);
+          delta_rows[start_row + i][*col_idx] += rounded_delta;
+          if ((!has_long) && (rounded_delta < -65536 || rounded_delta > 65535))
+            has_long = true;
+        }
+      }
+
+      if (!optimize)
+      {
+        /* assemble a delta_row_encoding_t for this subtable, skip optimization so
+         * chars is not initialized, we only need delta rows for serialization */
+        delta_row_encoding_t obj;
+        for (unsigned r = start_row; r < start_row + num_rows; r++)
+          obj.add_row (&(delta_rows.arrayZ[r]));
+
+        encodings.push (std::move (obj));
+        start_row += num_rows;
+        continue;
+      }
+
+      for (unsigned minor = 0; minor < num_rows; minor++)
+      {
+        const hb_vector_t<int>& row = delta_rows[start_row + minor];
+        if (use_no_variation_idx)
+        {
+          bool all_zeros = true;
+          for (int delta : row)
+          {
+            if (delta != 0)
+            {
+              all_zeros = false;
+              break;
+            }
+          }
+          if (all_zeros)
+            continue;
+        }
+
+        if (!front_mapping.set ((major<<16) + minor, &row))
+          return false;
+
+        hb_vector_t<uint8_t> chars = delta_row_encoding_t::get_row_chars (row);
+        if (!chars) return false;
+
+        if (delta_rows_map.has (&row))
+          continue;
+
+        delta_rows_map.set (&row, 1);
+        unsigned *obj_idx;
+        if (chars_idx_map.has (chars, &obj_idx))
+        {
+          delta_row_encoding_t& obj = encoding_objs[*obj_idx];
+          if (!obj.add_row (&row))
+            return false;
+        }
+        else
+        {
+          if (!chars_idx_map.set (chars, encoding_objs.length))
+            return false;
+          delta_row_encoding_t obj (std::move (chars), &row);
+          encoding_objs.push (std::move (obj));
+        }
+      }
+
+      start_row += num_rows;
+    }
+
+    /* return directly if no optimization, maintain original VariationIndex so
+     * varidx_map would be empty */
+    if (!optimize) return !encodings.in_error ();
+
+    /* sort encoding_objs */
+    encoding_objs.qsort ();
+
+    /* main algorithm: repeatedly pick 2 best encodings to combine, and combine
+     * them */
+    hb_priority_queue_t<combined_gain_idx_tuple_t> queue;
+    unsigned num_todos = encoding_objs.length;
+    for (unsigned i = 0; i < num_todos; i++)
+    {
+      for (unsigned j = i + 1; j < num_todos; j++)
+      {
+        int combining_gain = encoding_objs.arrayZ[i].gain_from_merging (encoding_objs.arrayZ[j]);
+        if (combining_gain > 0)
+          queue.insert (combined_gain_idx_tuple_t (-combining_gain, i, j), 0);
+      }
+    }
+
+    hb_set_t removed_todo_idxes;
+    while (queue)
+    {
+      auto t = queue.pop_minimum ().first;
+      unsigned i = t.idx_1;
+      unsigned j = t.idx_2;
+
+      if (removed_todo_idxes.has (i) || removed_todo_idxes.has (j))
+        continue;
+
+      delta_row_encoding_t& encoding = encoding_objs.arrayZ[i];
+      delta_row_encoding_t& other_encoding = encoding_objs.arrayZ[j];
+
+      removed_todo_idxes.add (i);
+      removed_todo_idxes.add (j);
+
+      hb_vector_t<uint8_t> combined_chars;
+      if (!combined_chars.alloc (encoding.chars.length))
+        return false;
+
+      for (unsigned idx = 0; idx < encoding.chars.length; idx++)
+      {
+        uint8_t v = hb_max (encoding.chars.arrayZ[idx], other_encoding.chars.arrayZ[idx]);
+        combined_chars.push (v);
+      }
+
+      delta_row_encoding_t combined_encoding_obj (std::move (combined_chars));
+      for (const auto& row : hb_concat (encoding.items, other_encoding.items))
+        combined_encoding_obj.add_row (row);
+
+      for (unsigned idx = 0; idx < encoding_objs.length; idx++)
+      {
+        if (removed_todo_idxes.has (idx)) continue;
+
+        const delta_row_encoding_t& obj = encoding_objs.arrayZ[idx];
+        if (obj.chars == combined_chars)
+        {
+          for (const auto& row : obj.items)
+            combined_encoding_obj.add_row (row);
+
+          removed_todo_idxes.add (idx);
+          continue;
+        }
+
+        int combined_gain = combined_encoding_obj.gain_from_merging (obj);
+        if (combined_gain > 0)
+          queue.insert (combined_gain_idx_tuple_t (-combined_gain, idx, encoding_objs.length), 0);
+      }
+
+      encoding_objs.push (std::move (combined_encoding_obj));
+    }
+
+    int num_final_encodings = (int) encoding_objs.length - (int) removed_todo_idxes.get_population ();
+    if (num_final_encodings <= 0) return false;
+
+    if (!encodings.alloc (num_final_encodings)) return false;
+    for (unsigned i = 0; i < encoding_objs.length; i++)
+    {
+      if (removed_todo_idxes.has (i)) continue;
+      encodings.push (std::move (encoding_objs.arrayZ[i]));
+    }
+
+    /* sort again based on width, make result deterministic */
+    encodings.qsort (delta_row_encoding_t::cmp_width);
+
+    return compile_varidx_map (front_mapping);
+  }
+
+  private:
+  /* compile varidx_map for one VarData subtable (index specified by major) */
+  bool compile_varidx_map (const hb_hashmap_t<unsigned, const hb_vector_t<int>*>& front_mapping)
+  {
+    /* full encoding_row -> new VarIdxes mapping */
+    hb_hashmap_t<const hb_vector_t<int>*, unsigned> back_mapping;
+
+    for (unsigned major = 0; major < encodings.length; major++)
+    {
+      delta_row_encoding_t& encoding = encodings[major];
+      /* just sanity check, this shouldn't happen */
+      if (encoding.is_empty ())
+        return false;
+
+      unsigned num_rows = encoding.items.length;
+
+      /* sort rows, make result deterministic */
+      encoding.items.qsort (_cmp_row);
+
+      /* compile old to new var_idxes mapping */
+      for (unsigned minor = 0; minor < num_rows; minor++)
+      {
+        unsigned new_varidx = (major << 16) + minor;
+        back_mapping.set (encoding.items.arrayZ[minor], new_varidx);
+      }
+    }
+
+    for (auto _ : front_mapping.iter ())
+    {
+      unsigned old_varidx = _.first;
+      unsigned *new_varidx;
+      if (back_mapping.has (_.second, &new_varidx))
+        varidx_map.set (old_varidx, *new_varidx);
+      else
+        varidx_map.set (old_varidx, HB_OT_LAYOUT_NO_VARIATIONS_INDEX);
+    }
+    return !varidx_map.in_error ();
+  }
+
+  static int _cmp_row (const void *pa, const void *pb)
+  {
+    /* compare pointers of vectors(const hb_vector_t<int>*) that represent a row */
+    const hb_vector_t<int>** a = (const hb_vector_t<int>**) pa;
+    const hb_vector_t<int>** b = (const hb_vector_t<int>**) pb;
+
+    for (unsigned i = 0; i < (*b)->length; i++)
+    {
+      int va = (*a)->arrayZ[i];
+      int vb = (*b)->arrayZ[i];
+      if (va != vb)
+        return va < vb ? -1 : 1;
+    }
+    return 0;
+  }
+};
+
 } /* namespace OT */
 
 
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-cvar-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-cvar-table.hh
index 8a281dd..a44a8e99 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-cvar-table.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-cvar-table.hh
@@ -27,6 +27,7 @@
 #define HB_OT_VAR_CVAR_TABLE_HH
 
 #include "hb-ot-var-common.hh"
+#include "hb-ot-var-fvar-table.hh"
 
 
 namespace OT {
@@ -51,6 +52,27 @@
   const TupleVariationData* get_tuple_var_data (void) const
   { return &tupleVariationData; }
 
+  bool decompile_tuple_variations (unsigned axis_count,
+                                   unsigned point_count,
+                                   hb_blob_t *blob,
+                                   bool is_gvar,
+                                   const hb_map_t *axes_old_index_tag_map,
+                                   TupleVariationData::tuple_variations_t& tuple_variations /* OUT */) const
+  {
+    hb_vector_t<unsigned> shared_indices;
+    TupleVariationData::tuple_iterator_t iterator;
+    hb_bytes_t var_data_bytes = blob->as_bytes ().sub_array (4);
+    if (!TupleVariationData::get_tuple_iterator (var_data_bytes, axis_count, this,
+                                                 shared_indices, &iterator))
+      return false;
+
+    return tupleVariationData.decompile_tuple_variations (point_count, is_gvar, iterator,
+                                                          axes_old_index_tag_map,
+                                                          shared_indices,
+                                                          hb_array<const F2DOT14> (),
+                                                          tuple_variations);
+  }
+
   static bool calculate_cvt_deltas (unsigned axis_count,
                                     hb_array_t<int> coords,
                                     unsigned num_cvt_item,
@@ -105,6 +127,46 @@
     return true;
   }
 
+  bool serialize (hb_serialize_context_t *c,
+                  TupleVariationData::tuple_variations_t& tuple_variations) const
+  {
+    TRACE_SERIALIZE (this);
+    if (!tuple_variations) return_trace (false);
+    if (unlikely (!c->embed (version))) return_trace (false);
+
+    return_trace (tupleVariationData.serialize (c, false, tuple_variations));
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    if (c->plan->all_axes_pinned)
+      return_trace (false);
+
+    OT::TupleVariationData::tuple_variations_t tuple_variations;
+    unsigned axis_count = c->plan->axes_old_index_tag_map.get_population ();
+
+    const hb_tag_t cvt = HB_TAG('c','v','t',' ');
+    hb_blob_t *cvt_blob = hb_face_reference_table (c->plan->source, cvt);
+    unsigned point_count = hb_blob_get_length (cvt_blob) / FWORD::static_size;
+    hb_blob_destroy (cvt_blob);
+
+    if (!decompile_tuple_variations (axis_count, point_count,
+                                     c->source_blob, false,
+                                     &(c->plan->axes_old_index_tag_map),
+                                     tuple_variations))
+      return_trace (false);
+
+    if (!tuple_variations.instantiate (c->plan->axes_location, c->plan->axes_triple_distances))
+      return_trace (false);
+
+    if (!tuple_variations.compile_bytes (c->plan->axes_index_map, c->plan->axes_old_index_tag_map,
+                                         false /* do not use shared points */))
+      return_trace (false);
+
+    return_trace (serialize (c->serializer, tuple_variations));
+  }
+
   static bool add_cvt_and_apply_deltas (hb_subset_plan_t *plan,
                                         const TupleVariationData *tuple_var_data,
                                         const void *base)
@@ -126,7 +188,6 @@
       hb_blob_destroy (cvt_prime_blob);
       return false;
     }
-    hb_memset (cvt_deltas.arrayZ, 0, cvt_deltas.get_size ());
 
     if (!calculate_cvt_deltas (plan->normalized_coords.length, plan->normalized_coords.as_array (),
                                num_cvt_item, tuple_var_data, base, cvt_deltas))
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-fvar-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-fvar-table.hh
index 7737e0a..d60c3db 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-fvar-table.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-fvar-table.hh
@@ -39,6 +39,24 @@
 
 namespace OT {
 
+static bool axis_coord_pinned_or_within_axis_range (const hb_array_t<const F16DOT16> coords,
+                                                    unsigned axis_index,
+                                                    Triple axis_limit)
+{
+  float axis_coord = coords[axis_index].to_float ();
+  if (axis_limit.is_point ())
+  {
+    if (axis_limit.minimum != axis_coord)
+      return false;
+  }
+  else
+  {
+    if (axis_coord < axis_limit.minimum ||
+        axis_coord > axis_limit.maximum)
+      return false;
+  }
+  return true;
+}
 
 struct InstanceRecord
 {
@@ -47,6 +65,27 @@
   hb_array_t<const F16DOT16> get_coordinates (unsigned int axis_count) const
   { return coordinatesZ.as_array (axis_count); }
 
+  bool keep_instance (unsigned axis_count,
+                      const hb_map_t *axes_index_tag_map,
+                      const hb_hashmap_t<hb_tag_t, Triple> *axes_location) const
+  {
+    if (axes_location->is_empty ()) return true;
+    const hb_array_t<const F16DOT16> coords = get_coordinates (axis_count);
+    for (unsigned i = 0 ; i < axis_count; i++)
+    {
+      uint32_t *axis_tag;
+      if (!axes_index_tag_map->has (i, &axis_tag))
+        return false;
+      if (!axes_location->has (*axis_tag))
+        continue;
+
+      Triple axis_limit = axes_location->get (*axis_tag);
+      if (!axis_coord_pinned_or_within_axis_range (coords, i, axis_limit))
+        return false;
+    }
+    return true;
+  }
+
   bool subset (hb_subset_context_t *c,
                unsigned axis_count,
                bool has_postscript_nameid) const
@@ -56,19 +95,22 @@
     if (unlikely (!c->serializer->embed (flags))) return_trace (false);
 
     const hb_array_t<const F16DOT16> coords = get_coordinates (axis_count);
-    const hb_hashmap_t<hb_tag_t, float> *axes_location = &c->plan->user_axes_location;
+    const hb_hashmap_t<hb_tag_t, Triple> *axes_location = &c->plan->user_axes_location;
     for (unsigned i = 0 ; i < axis_count; i++)
     {
       uint32_t *axis_tag;
+      Triple *axis_limit;
       // only keep instances whose coordinates == pinned axis location
-      if (!c->plan->axes_old_index_tag_map.has (i, &axis_tag)) continue;
+      if (!c->plan->axes_old_index_tag_map.has (i, &axis_tag)) return_trace (false);
+      if (axes_location->has (*axis_tag, &axis_limit))
+      {
+        if (!axis_coord_pinned_or_within_axis_range (coords, i, *axis_limit))
+          return_trace (false);
 
-      if (axes_location->has (*axis_tag) &&
-          fabsf (axes_location->get (*axis_tag) - coords[i].to_float ()) > 0.001f)
-        return_trace (false);
-
-      if (!c->plan->axes_index_map.has (i))
-        continue;
+        //skip pinned axis
+        if (axis_limit->is_point ())
+          continue;
+      }
 
       if (!c->serializer->embed (coords[i]))
         return_trace (false);
@@ -186,6 +228,30 @@
     return defaultValue.to_float ();
   }
 
+  TripleDistances get_triple_distances () const
+  {
+    float min, default_, max;
+    get_coordinates (min, default_, max);
+    return TripleDistances (min, default_, max);
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    const hb_hashmap_t<hb_tag_t, Triple>& user_axes_location = c->plan->user_axes_location;
+    Triple *axis_limit;
+    if (user_axes_location.has (axisTag, &axis_limit))
+    {
+      out->minValue.set_float (axis_limit->minimum);
+      out->defaultValue.set_float (axis_limit->middle);
+      out->maxValue.set_float (axis_limit->maximum);
+    }
+    return_trace (true);
+  }
+
   public:
   Tag           axisTag;        /* Tag identifying the design variation for the axis. */
   protected:
@@ -216,7 +282,8 @@
                   axisSize == 20 && /* Assumed in our code. */
                   instanceSize >= axisCount * 4 + 4 &&
                   get_axes ().sanitize (c) &&
-                  c->check_range (get_instance (0), instanceCount, instanceSize));
+                  c->check_range (&StructAfter<InstanceRecord> (get_axes ()),
+                                  instanceCount, instanceSize));
   }
 
   unsigned int get_axis_count () const { return axisCount; }
@@ -314,21 +381,19 @@
     return axisCount;
   }
 
-  void collect_name_ids (hb_hashmap_t<hb_tag_t, float> *user_axes_location,
+  void collect_name_ids (hb_hashmap_t<hb_tag_t, Triple> *user_axes_location,
+                         hb_map_t *axes_old_index_tag_map,
                          hb_set_t *nameids  /* IN/OUT */) const
   {
     if (!has_data ()) return;
-    hb_map_t pinned_axes;
 
     auto axis_records = get_axes ();
     for (unsigned i = 0 ; i < (unsigned)axisCount; i++)
     {
       hb_tag_t axis_tag = axis_records[i].get_axis_tag ();
-      if (user_axes_location->has (axis_tag))
-      {
-        pinned_axes.set (i, axis_tag);
+      if (user_axes_location->has (axis_tag) &&
+          user_axes_location->get (axis_tag).is_point ())
         continue;
-      }
 
       nameids->add (axis_records[i].get_name_id ());
     }
@@ -337,16 +402,7 @@
     {
       const InstanceRecord *instance = get_instance (i);
 
-      if (hb_any (+ hb_enumerate (instance->get_coordinates (axisCount))
-                  | hb_filter (pinned_axes, hb_first)
-                  | hb_map ([&] (const hb_pair_t<unsigned, const F16DOT16&>& _)
-                            {
-                              hb_tag_t axis_tag = pinned_axes.get (_.first);
-                              float location = user_axes_location->get (axis_tag);
-                              if (fabs ((double)location - (double)_.second.to_float ()) > 0.001) return true;
-                              return false;
-                            })
-                  ))
+      if (!instance->keep_instance (axisCount, axes_old_index_tag_map, user_axes_location))
         continue;
 
       nameids->add (instance->subfamilyNameID);
@@ -384,21 +440,25 @@
     for (unsigned i = 0 ; i < (unsigned)axisCount; i++)
     {
       if (!c->plan->axes_index_map.has (i)) continue;
-      if (unlikely (!c->serializer->embed (axes_records[i])))
+      if (unlikely (!axes_records[i].subset (c)))
         return_trace (false);
     }
 
     if (!c->serializer->check_assign (out->firstAxis, get_size (), HB_SERIALIZE_ERROR_INT_OVERFLOW))
       return_trace (false);
 
+    unsigned num_retained_instances = 0;
     for (unsigned i = 0 ; i < (unsigned)instanceCount; i++)
     {
       const InstanceRecord *instance = get_instance (i);
       auto snap = c->serializer->snapshot ();
       if (!instance->subset (c, axisCount, has_postscript_nameid))
         c->serializer->revert (snap);
+      else
+        num_retained_instances++;
     }
-    return_trace (true);
+
+    return_trace (c->serializer->check_assign (out->instanceCount, num_retained_instances, HB_SERIALIZE_ERROR_INT_OVERFLOW));
   }
 
   public:
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-gvar-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-gvar-table.hh
index caf4a1c..fd32ef0 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-gvar-table.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-gvar-table.hh
@@ -39,61 +39,256 @@
 
 namespace OT {
 
-struct contour_point_t
-{
-  void init (float x_ = 0.f, float y_ = 0.f, bool is_end_point_ = false)
-  { flag = 0; x = x_; y = y_; is_end_point = is_end_point_; }
-
-  void translate (const contour_point_t &p) { x += p.x; y += p.y; }
-
-  float x = 0.f;
-  float y = 0.f;
-  uint8_t flag = 0;
-  bool is_end_point = false;
-};
-
-struct contour_point_vector_t : hb_vector_t<contour_point_t>
-{
-  void extend (const hb_array_t<contour_point_t> &a)
-  {
-    unsigned int old_len = length;
-    if (unlikely (!resize (old_len + a.length, false)))
-      return;
-    auto arrayZ = this->arrayZ + old_len;
-    unsigned count = a.length;
-    hb_memcpy (arrayZ, a.arrayZ, count * sizeof (arrayZ[0]));
-  }
-
-  void transform (const float (&matrix)[4])
-  {
-    if (matrix[0] == 1.f && matrix[1] == 0.f &&
-        matrix[2] == 0.f && matrix[3] == 1.f)
-      return;
-    auto arrayZ = this->arrayZ;
-    unsigned count = length;
-    for (unsigned i = 0; i < count; i++)
-    {
-      contour_point_t &p = arrayZ[i];
-      float x_ = p.x * matrix[0] + p.y * matrix[2];
-           p.y = p.x * matrix[1] + p.y * matrix[3];
-      p.x = x_;
-    }
-  }
-
-  void translate (const contour_point_t& delta)
-  {
-    if (delta.x == 0.f && delta.y == 0.f)
-      return;
-    auto arrayZ = this->arrayZ;
-    unsigned count = length;
-    for (unsigned i = 0; i < count; i++)
-      arrayZ[i].translate (delta);
-  }
-};
-
 struct GlyphVariationData : TupleVariationData
 {};
 
+struct glyph_variations_t
+{
+  using tuple_variations_t = TupleVariationData::tuple_variations_t;
+  hb_vector_t<tuple_variations_t> glyph_variations;
+
+  hb_vector_t<char> compiled_shared_tuples;
+  private:
+  unsigned shared_tuples_count = 0;
+
+  /* shared coords-> index map after instantiation */
+  hb_hashmap_t<const hb_vector_t<char>*, unsigned> shared_tuples_idx_map;
+
+  public:
+  unsigned compiled_shared_tuples_count () const
+  { return shared_tuples_count; }
+
+  unsigned compiled_byte_size () const
+  {
+    unsigned byte_size = 0;
+    for (const auto& _ : glyph_variations)
+      byte_size += _.get_compiled_byte_size ();
+
+    return byte_size;
+  }
+
+  bool create_from_glyphs_var_data (unsigned axis_count,
+                                    const hb_array_t<const F2DOT14> shared_tuples,
+                                    const hb_subset_plan_t *plan,
+                                    const hb_hashmap_t<hb_codepoint_t, hb_bytes_t>& new_gid_var_data_map)
+  {
+    if (unlikely (!glyph_variations.alloc (plan->new_to_old_gid_list.length, true)))
+      return false;
+
+    auto it = hb_iter (plan->new_to_old_gid_list);
+    for (auto &_ : it)
+    {
+      hb_codepoint_t new_gid = _.first;
+      contour_point_vector_t *all_contour_points;
+      if (!new_gid_var_data_map.has (new_gid) ||
+          !plan->new_gid_contour_points_map.has (new_gid, &all_contour_points))
+        return false;
+      hb_bytes_t var_data = new_gid_var_data_map.get (new_gid);
+
+      const GlyphVariationData* p = reinterpret_cast<const GlyphVariationData*> (var_data.arrayZ);
+      hb_vector_t<unsigned> shared_indices;
+      GlyphVariationData::tuple_iterator_t iterator;
+      tuple_variations_t tuple_vars;
+
+      /* in case variation data is empty, push an empty struct into the vector,
+       * keep the vector in sync with the new_to_old_gid_list */
+      if (!var_data || ! p->has_data () || !all_contour_points->length ||
+          !GlyphVariationData::get_tuple_iterator (var_data, axis_count,
+                                                   var_data.arrayZ,
+                                                   shared_indices, &iterator))
+      {
+        glyph_variations.push (std::move (tuple_vars));
+        continue;
+      }
+
+      if (!p->decompile_tuple_variations (all_contour_points->length, true /* is_gvar */,
+                                          iterator, &(plan->axes_old_index_tag_map),
+                                          shared_indices, shared_tuples,
+                                          tuple_vars /* OUT */))
+        return false;
+      glyph_variations.push (std::move (tuple_vars));
+    }
+    return !glyph_variations.in_error () && glyph_variations.length == plan->new_to_old_gid_list.length;
+  }
+
+  bool instantiate (const hb_subset_plan_t *plan)
+  {
+    unsigned count = plan->new_to_old_gid_list.length;
+    for (unsigned i = 0; i < count; i++)
+    {
+      hb_codepoint_t new_gid = plan->new_to_old_gid_list[i].first;
+      contour_point_vector_t *all_points;
+      if (!plan->new_gid_contour_points_map.has (new_gid, &all_points))
+        return false;
+      if (!glyph_variations[i].instantiate (plan->axes_location, plan->axes_triple_distances, all_points))
+        return false;
+    }
+    return true;
+  }
+
+  bool compile_bytes (const hb_map_t& axes_index_map,
+                      const hb_map_t& axes_old_index_tag_map)
+  {
+    if (!compile_shared_tuples (axes_index_map, axes_old_index_tag_map))
+      return false;
+    for (tuple_variations_t& vars: glyph_variations)
+      if (!vars.compile_bytes (axes_index_map, axes_old_index_tag_map,
+                               true, /* use shared points*/
+                               &shared_tuples_idx_map))
+        return false;
+
+    return true;
+  }
+
+  bool compile_shared_tuples (const hb_map_t& axes_index_map,
+                              const hb_map_t& axes_old_index_tag_map)
+  {
+    /* key is pointer to compiled_peak_coords inside each tuple, hashing
+     * function will always deref pointers first */
+    hb_hashmap_t<const hb_vector_t<char>*, unsigned> coords_count_map;
+
+    /* count the num of shared coords */
+    for (tuple_variations_t& vars: glyph_variations)
+    {
+      for (tuple_delta_t& var : vars.tuple_vars)
+      {
+        if (!var.compile_peak_coords (axes_index_map, axes_old_index_tag_map))
+          return false;
+        unsigned* count;
+        if (coords_count_map.has (&(var.compiled_peak_coords), &count))
+          coords_count_map.set (&(var.compiled_peak_coords), *count + 1);
+        else
+          coords_count_map.set (&(var.compiled_peak_coords), 1);
+      }
+    }
+
+    if (!coords_count_map || coords_count_map.in_error ())
+      return false;
+
+    /* add only those coords that are used more than once into the vector and sort */
+    hb_vector_t<const hb_vector_t<char>*> shared_coords;
+    if (unlikely (!shared_coords.alloc (coords_count_map.get_population ())))
+      return false;
+
+    for (const auto _ : coords_count_map.iter ())
+    {
+      if (_.second == 1) continue;
+      shared_coords.push (_.first);
+    }
+
+    /* no shared tuples: no coords are used more than once */
+    if (!shared_coords) return true;
+    /* sorting based on the coords frequency first (high to low), then compare
+     * the coords bytes */
+    hb_qsort (shared_coords.arrayZ, shared_coords.length, sizeof (hb_vector_t<char>*), _cmp_coords, (void *) (&coords_count_map));
+
+    /* build shared_coords->idx map and shared tuples byte array */
+
+    shared_tuples_count = hb_min (0xFFFu + 1, shared_coords.length);
+    unsigned len = shared_tuples_count * (shared_coords[0]->length);
+    if (unlikely (!compiled_shared_tuples.alloc (len)))
+      return false;
+
+    for (unsigned i = 0; i < shared_tuples_count; i++)
+    {
+      shared_tuples_idx_map.set (shared_coords[i], i);
+      /* add a concat() in hb_vector_t? */
+      for (char c : shared_coords[i]->iter ())
+        compiled_shared_tuples.push (c);
+    }
+
+    return true;
+  }
+
+  static int _cmp_coords (const void *pa, const void *pb, void *arg)
+  {
+    const hb_hashmap_t<const hb_vector_t<char>*, unsigned>* coords_count_map =
+        reinterpret_cast<const hb_hashmap_t<const hb_vector_t<char>*, unsigned>*> (arg);
+
+    /* shared_coords is hb_vector_t<const hb_vector_t<char>*> so casting pa/pb
+     * to be a pointer to a pointer */
+    const hb_vector_t<char>** a = reinterpret_cast<const hb_vector_t<char>**> (const_cast<void*>(pa));
+    const hb_vector_t<char>** b = reinterpret_cast<const hb_vector_t<char>**> (const_cast<void*>(pb));
+
+    bool has_a = coords_count_map->has (*a);
+    bool has_b = coords_count_map->has (*b);
+
+    if (has_a && has_b)
+    {
+      unsigned a_num = coords_count_map->get (*a);
+      unsigned b_num = coords_count_map->get (*b);
+
+      if (a_num != b_num)
+        return b_num - a_num;
+
+      return (*b)->as_array().cmp ((*a)->as_array ());
+    }
+    else if (has_a) return -1;
+    else if (has_b) return 1;
+    else return 0;
+  }
+
+  template<typename Iterator,
+           hb_requires (hb_is_iterator (Iterator))>
+  bool serialize_glyph_var_data (hb_serialize_context_t *c,
+                                 Iterator it,
+                                 bool long_offset,
+                                 unsigned num_glyphs,
+                                 char* glyph_var_data_offsets /* OUT: glyph var data offsets array */) const
+  {
+    TRACE_SERIALIZE (this);
+
+    if (long_offset)
+    {
+      ((HBUINT32 *) glyph_var_data_offsets)[0] = 0;
+      glyph_var_data_offsets += 4;
+    }
+    else
+    {
+      ((HBUINT16 *) glyph_var_data_offsets)[0] = 0;
+      glyph_var_data_offsets += 2;
+    }
+    unsigned glyph_offset = 0;
+    hb_codepoint_t last_gid = 0;
+    unsigned idx = 0;
+
+    TupleVariationData* cur_glyph = c->start_embed<TupleVariationData> ();
+    if (!cur_glyph) return_trace (false);
+    for (auto &_ : it)
+    {
+      hb_codepoint_t gid = _.first;
+      if (long_offset)
+        for (; last_gid < gid; last_gid++)
+          ((HBUINT32 *) glyph_var_data_offsets)[last_gid] = glyph_offset;
+      else
+        for (; last_gid < gid; last_gid++)
+          ((HBUINT16 *) glyph_var_data_offsets)[last_gid] = glyph_offset / 2;
+
+      if (idx >= glyph_variations.length) return_trace (false);
+      if (!cur_glyph->serialize (c, true, glyph_variations[idx])) return_trace (false);
+      TupleVariationData* next_glyph = c->start_embed<TupleVariationData> ();
+      glyph_offset += (char *) next_glyph - (char *) cur_glyph;
+
+      if (long_offset)
+        ((HBUINT32 *) glyph_var_data_offsets)[gid] = glyph_offset;
+      else
+        ((HBUINT16 *) glyph_var_data_offsets)[gid] = glyph_offset / 2;
+
+      last_gid++;
+      idx++;
+      cur_glyph = next_glyph;
+    }
+
+    if (long_offset)
+      for (; last_gid < num_glyphs; last_gid++)
+        ((HBUINT32 *) glyph_var_data_offsets)[last_gid] = glyph_offset;
+    else
+      for (; last_gid < num_glyphs; last_gid++)
+        ((HBUINT16 *) glyph_var_data_offsets)[last_gid] = glyph_offset / 2;
+    return_trace (true);
+  }
+};
+
 struct gvar
 {
   static constexpr hb_tag_t tableTag = HB_OT_TAG_gvar;
@@ -112,9 +307,101 @@
   bool sanitize (hb_sanitize_context_t *c) const
   { return sanitize_shallow (c); }
 
+  bool decompile_glyph_variations (hb_subset_context_t *c,
+                                   glyph_variations_t& glyph_vars /* OUT */) const
+  {
+    hb_hashmap_t<hb_codepoint_t, hb_bytes_t> new_gid_var_data_map;
+    auto it = hb_iter (c->plan->new_to_old_gid_list);
+    if (it->first == 0 && !(c->plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE))
+    {
+      new_gid_var_data_map.set (0, hb_bytes_t ());
+      it++;
+    }
+
+    for (auto &_ : it)
+    {
+      hb_codepoint_t new_gid = _.first;
+      hb_codepoint_t old_gid = _.second;
+      hb_bytes_t var_data_bytes = get_glyph_var_data_bytes (c->source_blob, glyphCountX, old_gid);
+      new_gid_var_data_map.set (new_gid, var_data_bytes);
+    }
+
+    if (new_gid_var_data_map.in_error ()) return false;
+
+    hb_array_t<const F2DOT14> shared_tuples = (this+sharedTuples).as_array ((unsigned) sharedTupleCount * (unsigned) axisCount);
+    return glyph_vars.create_from_glyphs_var_data (axisCount, shared_tuples, c->plan, new_gid_var_data_map);
+  }
+
+  template<typename Iterator,
+           hb_requires (hb_is_iterator (Iterator))>
+  bool serialize (hb_serialize_context_t *c,
+                  const glyph_variations_t& glyph_vars,
+                  Iterator it,
+                  unsigned axis_count,
+                  unsigned num_glyphs) const
+  {
+    TRACE_SERIALIZE (this);
+    gvar *out = c->allocate_min<gvar> ();
+    if (unlikely (!out)) return_trace (false);
+
+    out->version.major = 1;
+    out->version.minor = 0;
+    out->axisCount = axis_count;
+    out->glyphCountX = hb_min (0xFFFFu, num_glyphs);
+
+    unsigned glyph_var_data_size = glyph_vars.compiled_byte_size ();
+    bool long_offset = glyph_var_data_size & ~0xFFFFu;
+    out->flags = long_offset ? 1 : 0;
+
+    HBUINT8 *glyph_var_data_offsets = c->allocate_size<HBUINT8> ((long_offset ? 4 : 2) * (num_glyphs + 1), false);
+    if (!glyph_var_data_offsets) return_trace (false);
+
+    /* shared tuples */
+    unsigned shared_tuple_count = glyph_vars.compiled_shared_tuples_count ();
+    out->sharedTupleCount = shared_tuple_count;
+
+    if (!shared_tuple_count)
+      out->sharedTuples = 0;
+    else
+    {
+      hb_array_t<const char> shared_tuples = glyph_vars.compiled_shared_tuples.as_array ().copy (c);
+      if (!shared_tuples.arrayZ) return_trace (false);
+      out->sharedTuples = shared_tuples.arrayZ - (char *) out;
+    }
+
+    char *glyph_var_data = c->start_embed<char> ();
+    if (!glyph_var_data) return_trace (false);
+    out->dataZ = glyph_var_data - (char *) out;
+
+    return_trace (glyph_vars.serialize_glyph_var_data (c, it, long_offset, num_glyphs,
+                                                       (char *) glyph_var_data_offsets));
+  }
+
+  bool instantiate (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    glyph_variations_t glyph_vars;
+    if (!decompile_glyph_variations (c, glyph_vars))
+      return_trace (false);
+
+    if (!glyph_vars.instantiate (c->plan)) return_trace (false);
+    if (!glyph_vars.compile_bytes (c->plan->axes_index_map, c->plan->axes_old_index_tag_map))
+      return_trace (false);
+
+    unsigned axis_count = c->plan->axes_index_map.get_population ();
+    unsigned num_glyphs = c->plan->num_output_glyphs ();
+    auto it = hb_iter (c->plan->new_to_old_gid_list);
+    return_trace (serialize (c->serializer, glyph_vars, it, axis_count, num_glyphs));
+  }
+
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
+    if (c->plan->all_axes_pinned)
+      return_trace (false);
+
+    if (c->plan->normalized_coords)
+      return_trace (instantiate (c));
 
     unsigned glyph_count = version.to_int () ? c->plan->source->get_num_glyphs () : 0;
 
@@ -129,20 +416,20 @@
     unsigned int num_glyphs = c->plan->num_output_glyphs ();
     out->glyphCountX = hb_min (0xFFFFu, num_glyphs);
 
+    auto it = hb_iter (c->plan->new_to_old_gid_list);
+    if (it->first == 0 && !(c->plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE))
+      it++;
     unsigned int subset_data_size = 0;
-    for (hb_codepoint_t gid = (c->plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE) ? 0 : 1;
-         gid < num_glyphs;
-         gid++)
+    for (auto &_ : it)
     {
-      hb_codepoint_t old_gid;
-      if (!c->plan->old_gid_for_new_gid (gid, &old_gid)) continue;
+      hb_codepoint_t old_gid = _.second;
       subset_data_size += get_glyph_var_data_bytes (c->source_blob, glyph_count, old_gid).length;
     }
 
     bool long_offset = subset_data_size & ~0xFFFFu;
     out->flags = long_offset ? 1 : 0;
 
-    HBUINT8 *subset_offsets = c->serializer->allocate_size<HBUINT8> ((long_offset ? 4 : 2) * (num_glyphs + 1));
+    HBUINT8 *subset_offsets = c->serializer->allocate_size<HBUINT8> ((long_offset ? 4 : 2) * (num_glyphs + 1), false);
     if (!subset_offsets) return_trace (false);
 
     /* shared tuples */
@@ -157,36 +444,61 @@
       hb_memcpy (tuples, this+sharedTuples, shared_tuple_size);
     }
 
-    char *subset_data = c->serializer->allocate_size<char> (subset_data_size);
+    char *subset_data = c->serializer->allocate_size<char> (subset_data_size, false);
     if (!subset_data) return_trace (false);
     out->dataZ = subset_data - (char *) out;
 
-    unsigned int glyph_offset = 0;
-    for (hb_codepoint_t gid = (c->plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE) ? 0 : 1;
-         gid < num_glyphs;
-         gid++)
+
+    if (long_offset)
     {
-      hb_codepoint_t old_gid;
-      hb_bytes_t var_data_bytes = c->plan->old_gid_for_new_gid (gid, &old_gid)
-                                ? get_glyph_var_data_bytes (c->source_blob,
+      ((HBUINT32 *) subset_offsets)[0] = 0;
+      subset_offsets += 4;
+    }
+    else
+    {
+      ((HBUINT16 *) subset_offsets)[0] = 0;
+      subset_offsets += 2;
+    }
+    unsigned int glyph_offset = 0;
+
+    hb_codepoint_t last = 0;
+    it = hb_iter (c->plan->new_to_old_gid_list);
+    if (it->first == 0 && !(c->plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE))
+      it++;
+    for (auto &_ : it)
+    {
+      hb_codepoint_t gid = _.first;
+      hb_codepoint_t old_gid = _.second;
+
+      if (long_offset)
+        for (; last < gid; last++)
+          ((HBUINT32 *) subset_offsets)[last] = glyph_offset;
+      else
+        for (; last < gid; last++)
+          ((HBUINT16 *) subset_offsets)[last] = glyph_offset / 2;
+
+      hb_bytes_t var_data_bytes = get_glyph_var_data_bytes (c->source_blob,
                                                             glyph_count,
-                                                            old_gid)
-                                : hb_bytes_t ();
+                                                            old_gid);
+
+      hb_memcpy (subset_data, var_data_bytes.arrayZ, var_data_bytes.length);
+      subset_data += var_data_bytes.length;
+      glyph_offset += var_data_bytes.length;
 
       if (long_offset)
         ((HBUINT32 *) subset_offsets)[gid] = glyph_offset;
       else
         ((HBUINT16 *) subset_offsets)[gid] = glyph_offset / 2;
 
-      if (var_data_bytes.length > 0)
-        hb_memcpy (subset_data, var_data_bytes.arrayZ, var_data_bytes.length);
-      subset_data += var_data_bytes.length;
-      glyph_offset += var_data_bytes.length;
+      last++; // Skip over gid
     }
+
     if (long_offset)
-      ((HBUINT32 *) subset_offsets)[num_glyphs] = glyph_offset;
+      for (; last < num_glyphs; last++)
+        ((HBUINT32 *) subset_offsets)[last] = glyph_offset;
     else
-      ((HBUINT16 *) subset_offsets)[num_glyphs] = glyph_offset / 2;
+      for (; last < num_glyphs; last++)
+        ((HBUINT16 *) subset_offsets)[last] = glyph_offset / 2;
 
     return_trace (true);
   }
@@ -235,21 +547,24 @@
       for (unsigned i = 0; i < count; i++)
       {
         hb_array_t<const F2DOT14> tuple = shared_tuples.sub_array (axis_count * i, axis_count);
-        int idx = -1;
+        int idx1 = -1, idx2 = -1;
         for (unsigned j = 0; j < axis_count; j++)
         {
-          F2DOT14 peak = tuple.arrayZ[j];
+          const F2DOT14 &peak = tuple.arrayZ[j];
           if (peak.to_int () != 0)
           {
-            if (idx != -1)
+            if (idx1 == -1)
+              idx1 = j;
+            else if (idx2 == -1)
+              idx2 = j;
+            else
             {
-              idx = -1;
+              idx1 = idx2 = -1;
               break;
             }
-            idx = j;
           }
         }
-        shared_tuple_active_idx[i] = idx;
+        shared_tuple_active_idx.arrayZ[i] = {idx1, idx2};
       }
     }
     ~accelerator_t () { table.destroy (); }
@@ -285,10 +600,9 @@
     public:
     bool apply_deltas_to_points (hb_codepoint_t glyph,
                                  hb_array_t<int> coords,
-                                 const hb_array_t<contour_point_t> points) const
+                                 const hb_array_t<contour_point_t> points,
+                                 bool phantom_only = false) const
     {
-      if (!coords) return true;
-
       if (unlikely (glyph >= glyphCount)) return true;
 
       hb_bytes_t var_data_bytes = table->get_glyph_var_data_bytes (table.get_blob (), glyphCount, glyph);
@@ -311,16 +625,17 @@
       hb_vector_t<unsigned> end_points; // Populated lazily
 
       unsigned num_coords = table->axisCount;
-      hb_array_t<const F2DOT14> shared_tuples = (table+table->sharedTuples).as_array (table->sharedTupleCount * table->axisCount);
+      hb_array_t<const F2DOT14> shared_tuples = (table+table->sharedTuples).as_array (table->sharedTupleCount * num_coords);
 
       hb_vector_t<unsigned int> private_indices;
       hb_vector_t<int> x_deltas;
       hb_vector_t<int> y_deltas;
+      unsigned count = points.length;
       bool flush = false;
       do
       {
         float scalar = iterator.current_tuple->calculate_scalar (coords, num_coords, shared_tuples,
-                                                                 shared_tuple_active_idx.in_error () ? nullptr : &shared_tuple_active_idx);
+                                                                 &shared_tuple_active_idx);
         if (scalar == 0.f) continue;
         const HBUINT8 *p = iterator.get_serialized_data ();
         unsigned int length = iterator.current_tuple->get_data_size ();
@@ -329,8 +644,10 @@
 
         if (!deltas)
         {
-          if (unlikely (!deltas_vec.resize (points.length))) return false;
+          if (unlikely (!deltas_vec.resize (count, false))) return false;
           deltas = deltas_vec.as_array ();
+          hb_memset (deltas.arrayZ + (phantom_only ? count - 4 : 0), 0,
+                     (phantom_only ? 4 : count) * sizeof (deltas[0]));
         }
 
         const HBUINT8 *end = p + length;
@@ -350,7 +667,7 @@
 
         if (!apply_to_all)
         {
-          if (!orig_points)
+          if (!orig_points && !phantom_only)
           {
             orig_points_vec.extend (points);
             if (unlikely (orig_points_vec.in_error ())) return false;
@@ -359,15 +676,17 @@
 
           if (flush)
           {
-            for (unsigned int i = 0; i < points.length; i++)
+            for (unsigned int i = phantom_only ? count - 4 : 0; i < count; i++)
               points.arrayZ[i].translate (deltas.arrayZ[i]);
             flush = false;
 
           }
-          hb_memset (deltas.arrayZ, 0, deltas.get_size ());
+          hb_memset (deltas.arrayZ + (phantom_only ? count - 4 : 0), 0,
+                     (phantom_only ? 4 : count) * sizeof (deltas[0]));
         }
 
-        if (scalar != 1.0f)
+        if (HB_OPTIMIZE_SIZE_VAL)
+        {
           for (unsigned int i = 0; i < num_deltas; i++)
           {
             unsigned int pt_index;
@@ -378,34 +697,68 @@
               pt_index = indices[i];
               if (unlikely (pt_index >= deltas.length)) continue;
             }
+            if (phantom_only && pt_index < count - 4) continue;
             auto &delta = deltas.arrayZ[pt_index];
             delta.flag = 1;     /* this point is referenced, i.e., explicit deltas specified */
             delta.x += x_deltas.arrayZ[i] * scalar;
             delta.y += y_deltas.arrayZ[i] * scalar;
           }
+        }
         else
-          for (unsigned int i = 0; i < num_deltas; i++)
+        {
+          /* Ouch. Four cases... for optimization. */
+          if (scalar != 1.0f)
           {
-            unsigned int pt_index;
             if (apply_to_all)
-              pt_index = i;
+              for (unsigned int i = phantom_only ? count - 4 : 0; i < count; i++)
+              {
+                unsigned int pt_index = i;
+                auto &delta = deltas.arrayZ[pt_index];
+                delta.x += x_deltas.arrayZ[i] * scalar;
+                delta.y += y_deltas.arrayZ[i] * scalar;
+              }
             else
-            {
-              pt_index = indices[i];
-              if (unlikely (pt_index >= deltas.length)) continue;
-            }
-            auto &delta = deltas.arrayZ[pt_index];
-            delta.flag = 1;     /* this point is referenced, i.e., explicit deltas specified */
-            delta.x += x_deltas.arrayZ[i];
-            delta.y += y_deltas.arrayZ[i];
+              for (unsigned int i = 0; i < num_deltas; i++)
+              {
+                unsigned int pt_index = indices[i];
+                if (unlikely (pt_index >= deltas.length)) continue;
+                if (phantom_only && pt_index < count - 4) continue;
+                auto &delta = deltas.arrayZ[pt_index];
+                delta.flag = 1; /* this point is referenced, i.e., explicit deltas specified */
+                delta.x += x_deltas.arrayZ[i] * scalar;
+                delta.y += y_deltas.arrayZ[i] * scalar;
+              }
           }
+          else
+          {
+            if (apply_to_all)
+              for (unsigned int i = phantom_only ? count - 4 : 0; i < count; i++)
+              {
+                unsigned int pt_index = i;
+                auto &delta = deltas.arrayZ[pt_index];
+                delta.x += x_deltas.arrayZ[i];
+                delta.y += y_deltas.arrayZ[i];
+              }
+            else
+              for (unsigned int i = 0; i < num_deltas; i++)
+              {
+                unsigned int pt_index = indices[i];
+                if (unlikely (pt_index >= deltas.length)) continue;
+                if (phantom_only && pt_index < count - 4) continue;
+                auto &delta = deltas.arrayZ[pt_index];
+                delta.flag = 1; /* this point is referenced, i.e., explicit deltas specified */
+                delta.x += x_deltas.arrayZ[i];
+                delta.y += y_deltas.arrayZ[i];
+              }
+          }
+        }
 
         /* infer deltas for unreferenced points */
-        if (!apply_to_all)
+        if (!apply_to_all && !phantom_only)
         {
           if (!end_points)
           {
-            for (unsigned i = 0; i < points.length; ++i)
+            for (unsigned i = 0; i < count; ++i)
               if (points.arrayZ[i].is_end_point)
                 end_points.push (i);
             if (unlikely (end_points.in_error ())) return false;
@@ -465,8 +818,10 @@
       } while (iterator.move_to_next ());
 
       if (flush)
-        for (unsigned int i = 0; i < points.length; i++)
+      {
+        for (unsigned int i = phantom_only ? count - 4 : 0; i < count; i++)
           points.arrayZ[i].translate (deltas.arrayZ[i]);
+      }
 
       return true;
     }
@@ -476,7 +831,7 @@
     private:
     hb_blob_ptr_t<gvar> table;
     unsigned glyphCount;
-    hb_vector_t<signed> shared_tuple_active_idx;
+    hb_vector_t<hb_pair_t<int, int>> shared_tuple_active_idx;
   };
 
   protected:
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-hvar-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-hvar-table.hh
index 9fc3752..c1b40dc 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-hvar-table.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-hvar-table.hh
@@ -45,7 +45,8 @@
   void init (const DeltaSetIndexMap  &index_map,
              hb_inc_bimap_t          &outer_map,
              hb_vector_t<hb_set_t *> &inner_sets,
-             const hb_subset_plan_t  *plan)
+             const hb_subset_plan_t  *plan,
+             bool bypass_empty = true)
   {
     map_count = 0;
     outer_bit_count = 0;
@@ -53,55 +54,51 @@
     max_inners.init ();
     output_map.init ();
 
-    if (&index_map == &Null (DeltaSetIndexMap)) return;
+    if (bypass_empty && !index_map.get_map_count ()) return;
 
     unsigned int        last_val = (unsigned int)-1;
-    hb_codepoint_t      last_gid = (hb_codepoint_t)-1;
-    hb_codepoint_t      gid = (hb_codepoint_t) hb_min (index_map.get_map_count (), plan->num_output_glyphs ());
+    hb_codepoint_t      last_gid = HB_CODEPOINT_INVALID;
 
     outer_bit_count = (index_map.get_width () * 8) - index_map.get_inner_bit_count ();
     max_inners.resize (inner_sets.length);
     for (unsigned i = 0; i < inner_sets.length; i++) max_inners[i] = 0;
 
     /* Search backwards for a map value different from the last map value */
-    for (; gid > 0; gid--)
+    auto &new_to_old_gid_list = plan->new_to_old_gid_list;
+    unsigned count = new_to_old_gid_list.length;
+    for (unsigned j = count; j; j--)
     {
-      hb_codepoint_t    old_gid;
-      if (!plan->old_gid_for_new_gid (gid - 1, &old_gid))
-      {
-        if (last_gid == (hb_codepoint_t) -1)
-          continue;
-        else
-          break;
-      }
+      hb_codepoint_t gid = new_to_old_gid_list.arrayZ[j - 1].first;
+      hb_codepoint_t old_gid = new_to_old_gid_list.arrayZ[j - 1].second;
 
       unsigned int v = index_map.map (old_gid);
-      if (last_gid == (hb_codepoint_t) -1)
+      if (last_gid == HB_CODEPOINT_INVALID)
       {
         last_val = v;
         last_gid = gid;
         continue;
       }
-      if (v != last_val) break;
+      if (v != last_val)
+        break;
 
       last_gid = gid;
     }
 
     if (unlikely (last_gid == (hb_codepoint_t)-1)) return;
-    map_count = last_gid;
-    for (gid = 0; gid < map_count; gid++)
+    map_count = last_gid + 1;
+    for (auto _ : plan->new_to_old_gid_list)
     {
-      hb_codepoint_t    old_gid;
-      if (plan->old_gid_for_new_gid (gid, &old_gid))
-      {
-        unsigned int v = index_map.map (old_gid);
-        unsigned int outer = v >> 16;
-        unsigned int inner = v & 0xFFFF;
-        outer_map.add (outer);
-        if (inner > max_inners[outer]) max_inners[outer] = inner;
-        if (outer >= inner_sets.length) return;
-        inner_sets[outer]->add (inner);
-      }
+      hb_codepoint_t gid = _.first;
+      if (gid >= map_count) break;
+
+      hb_codepoint_t old_gid = _.second;
+      unsigned int v = index_map.map (old_gid);
+      unsigned int outer = v >> 16;
+      unsigned int inner = v & 0xFFFF;
+      outer_map.add (outer);
+      if (inner > max_inners[outer]) max_inners[outer] = inner;
+      if (outer >= inner_sets.length) return;
+      inner_sets[outer]->add (inner);
     }
   }
 
@@ -116,8 +113,6 @@
               const hb_vector_t<hb_inc_bimap_t> &inner_maps,
               const hb_subset_plan_t *plan)
   {
-    if (input_map == &Null (DeltaSetIndexMap)) return;
-
     for (unsigned int i = 0; i < max_inners.length; i++)
     {
       if (inner_maps[i].get_population () == 0) continue;
@@ -125,21 +120,50 @@
       if (bit_count > inner_bit_count) inner_bit_count = bit_count;
     }
 
-    output_map.resize (map_count);
-    for (hb_codepoint_t gid = 0; gid < output_map.length; gid++)
+    if (unlikely (!output_map.resize (map_count))) return;
+    for (const auto &_ : plan->new_to_old_gid_list)
     {
-      hb_codepoint_t    old_gid;
-      if (plan->old_gid_for_new_gid (gid, &old_gid))
-      {
-        uint32_t v = input_map->map (old_gid);
-        unsigned int outer = v >> 16;
-        output_map[gid] = (outer_map[outer] << 16) | (inner_maps[outer][v & 0xFFFF]);
-      }
-      else
-        output_map[gid] = 0;    /* Map unused glyph to outer/inner=0/0 */
+      hb_codepoint_t new_gid = _.first;
+      hb_codepoint_t old_gid = _.second;
+
+      if (unlikely (new_gid >= map_count)) break;
+
+      uint32_t v = input_map->map (old_gid);
+      unsigned int outer = v >> 16;
+      output_map.arrayZ[new_gid] = (outer_map[outer] << 16) | (inner_maps[outer][v & 0xFFFF]);
     }
   }
 
+  bool remap_after_instantiation (const hb_subset_plan_t *plan,
+                                  const hb_map_t& varidx_map)
+  {
+    /* recalculate bit_count after remapping */
+    outer_bit_count = 1;
+    inner_bit_count = 1;
+
+    for (const auto &_ : plan->new_to_old_gid_list)
+    {
+      hb_codepoint_t new_gid = _.first;
+      if (unlikely (new_gid >= map_count)) break;
+
+      uint32_t v = output_map.arrayZ[new_gid];
+      uint32_t *new_varidx;
+      if (!varidx_map.has (v, &new_varidx))
+        return false;
+
+      output_map.arrayZ[new_gid] = *new_varidx;
+
+      unsigned outer = (*new_varidx) >> 16;
+      unsigned bit_count = (outer == 0) ? 1 : hb_bit_storage (outer);
+      outer_bit_count = hb_max (bit_count, outer_bit_count);
+
+      unsigned inner = (*new_varidx) & 0xFFFF;
+      bit_count = (inner == 0) ? 1 : hb_bit_storage (inner);
+      inner_bit_count = hb_max (bit_count, inner_bit_count);
+    }
+    return true;
+  }
+
   unsigned int get_inner_bit_count () const { return inner_bit_count; }
   unsigned int get_width ()           const { return ((outer_bit_count + inner_bit_count + 7) / 8); }
   unsigned int get_map_count ()       const { return map_count; }
@@ -180,7 +204,7 @@
     if (unlikely (!index_map_plans.length || !inner_sets.length || !inner_maps.length)) return;
 
     bool retain_adv_map = false;
-    index_map_plans[0].init (*index_maps[0], outer_map, inner_sets, plan);
+    index_map_plans[0].init (*index_maps[0], outer_map, inner_sets, plan, false);
     if (index_maps[0] == &Null (DeltaSetIndexMap))
     {
       retain_adv_map = plan->flags & HB_SUBSET_FLAGS_RETAIN_GIDS;
@@ -197,12 +221,10 @@
 
     if (retain_adv_map)
     {
-      for (hb_codepoint_t gid = 0; gid < plan->num_output_glyphs (); gid++)
+      for (const auto &_ : plan->new_to_old_gid_list)
       {
-        if (inner_sets[0]->has (gid))
-          inner_maps[0].add (gid);
-        else
-          inner_maps[0].skip ();
+        hb_codepoint_t old_gid = _.second;
+        inner_maps[0].add (old_gid);
       }
     }
     else
@@ -219,6 +241,16 @@
       index_map_plans[i].remap (index_maps[i], outer_map, inner_maps, plan);
   }
 
+  /* remap */
+  bool remap_index_map_plans (const hb_subset_plan_t *plan,
+                              const hb_map_t& varidx_map)
+  {
+    for (unsigned i = 0; i < index_map_plans.length; i++)
+      if (!index_map_plans[i].remap_after_instantiation (plan, varidx_map))
+        return false;
+    return true;
+  }
+
   void fini ()
   {
     for (unsigned int i = 0; i < inner_sets.length; i++)
@@ -297,6 +329,9 @@
   bool _subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
+    if (c->plan->all_axes_pinned)
+      return_trace (false);
+
     hvarvvar_subset_plan_t      hvar_plan;
     hb_vector_t<const DeltaSetIndexMap *>
                                 index_maps;
@@ -310,11 +345,37 @@
     out->version.major = 1;
     out->version.minor = 0;
 
-    if (unlikely (!out->varStore
-                      .serialize_serialize (c->serializer,
-                                            hvar_plan.var_store,
-                                            hvar_plan.inner_maps.as_array ())))
+    if (c->plan->normalized_coords)
+    {
+      item_variations_t item_vars;
+      if (!item_vars.instantiate (this+varStore, c->plan,
+                                  advMap == 0 ? false : true,
+                                  false, /* use_no_variation_idx = false */
+                                  hvar_plan.inner_maps.as_array ()))
+        return_trace (false);
+
+      if (!out->varStore.serialize_serialize (c->serializer,
+                                              item_vars.has_long_word (),
+                                              c->plan->axis_tags,
+                                              item_vars.get_region_list (),
+                                              item_vars.get_vardata_encodings ()))
+        return_trace (false);
+
+      /* if varstore is optimized, remap output_map */
+      if (advMap)
+      {
+        if (!hvar_plan.remap_index_map_plans (c->plan, item_vars.get_varidx_map ()))
+          return_trace (false);
+      }
+    }
+    else
+    {
+      if (unlikely (!out->varStore
+                    .serialize_serialize (c->serializer,
+                                          hvar_plan.var_store,
+                                          hvar_plan.inner_maps.as_array ())))
       return_trace (false);
+    }
 
     return_trace (out->T::serialize_index_maps (c->serializer,
                                                 hvar_plan.index_map_plans.as_array ()));
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-mvar-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-mvar-table.hh
index c7c2fc1..ced04d8 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-var-mvar-table.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-var-mvar-table.hh
@@ -27,7 +27,7 @@
 #ifndef HB_OT_VAR_MVAR_TABLE_HH
 #define HB_OT_VAR_MVAR_TABLE_HH
 
-#include "hb-ot-layout-common.hh"
+#include "hb-ot-var-common.hh"
 
 
 namespace OT {
@@ -41,6 +41,19 @@
     return_trace (c->check_struct (this));
   }
 
+  bool subset (hb_subset_context_t *c,
+               const hb_map_t& varidx_map) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (*this);
+    if (unlikely (!out)) return_trace (false);
+
+    hb_codepoint_t *new_idx;
+    return_trace (c->serializer->check_assign (out->varIdx,
+                                               (varidx_map.has (varIdx, &new_idx)) ? *new_idx : HB_OT_LAYOUT_NO_VARIATIONS_INDEX,
+                                               HB_SERIALIZE_ERROR_INT_OVERFLOW));
+  }
+
   public:
   Tag           valueTag;       /* Four-byte tag identifying a font-wide measure. */
   VarIdx        varIdx;         /* Outer/inner index into VariationStore item. */
@@ -73,6 +86,47 @@
                                   valueRecordSize));
   }
 
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+#ifdef HB_NO_VAR
+    return_trace (false);
+#endif
+
+    if (c->plan->all_axes_pinned)
+      return_trace (false);
+
+    MVAR *out = c->serializer->start_embed (*this);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+    out->version = version;
+    out->reserved = reserved;
+    out->valueRecordSize = valueRecordSize;
+    out->valueRecordCount = valueRecordCount;
+
+    item_variations_t item_vars;
+    const VariationStore& src_var_store = this+varStore;
+
+    if (!item_vars.instantiate (src_var_store, c->plan))
+      return_trace (false);
+
+    /* serialize varstore */
+    if (!out->varStore.serialize_serialize (c->serializer, item_vars.has_long_word (),
+                                            c->plan->axis_tags,
+                                            item_vars.get_region_list (),
+                                            item_vars.get_vardata_encodings ()))
+      return_trace (false);
+
+    /* serialize value records array */
+    unsigned value_rec_count = valueRecordCount;
+    const VariationValueRecord *record = reinterpret_cast<const VariationValueRecord*> (valuesZ.arrayZ);
+    for (unsigned i = 0; i < value_rec_count; i++)
+    {
+      if (!record->subset (c, item_vars.get_varidx_map ())) return_trace (false);
+      record++;
+    }
+    return_trace (true);
+  }
+
   float get_var (hb_tag_t tag,
                  const int *coords, unsigned int coord_count) const
   {
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ot-vorg-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ot-vorg-table.hh
index 75e65c8..dd30399 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ot-vorg-table.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ot-vorg-table.hh
@@ -90,7 +90,7 @@
   bool subset (hb_subset_context_t *c) const
   {
     TRACE_SUBSET (this);
-    VORG *vorg_prime = c->serializer->start_embed<VORG> ();
+    auto *vorg_prime = c->serializer->start_embed<VORG> ();
     if (unlikely (!c->serializer->check_success (vorg_prime))) return_trace (false);
 
     auto it =
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-paint.cc b/src/java.desktop/share/native/libharfbuzz/hb-paint.cc
index d09c83d..6f2a296 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-paint.cc
+++ b/src/java.desktop/share/native/libharfbuzz/hb-paint.cc
@@ -54,6 +54,12 @@
 hb_paint_pop_transform_nil (hb_paint_funcs_t *funcs, void *paint_data,
                             void *user_data) {}
 
+static hb_bool_t
+hb_paint_color_glyph_nil (hb_paint_funcs_t *funcs, void *paint_data,
+                          hb_codepoint_t glyph,
+                          hb_font_t *font,
+                          void *user_data) { return false; }
+
 static void
 hb_paint_push_clip_glyph_nil (hb_paint_funcs_t *funcs, void *paint_data,
                               hb_codepoint_t glyph,
@@ -474,6 +480,25 @@
 }
 
 /**
+ * hb_paint_color_glyph:
+ * @funcs: paint functions
+ * @paint_data: associated data passed by the caller
+ * @glyph: the glyph ID
+ * @font: the font
+ *
+ * Perform a "color-glyph" paint operation.
+ *
+ * Since: 8.2.0
+ */
+hb_bool_t
+hb_paint_color_glyph (hb_paint_funcs_t *funcs, void *paint_data,
+                      hb_codepoint_t glyph,
+                      hb_font_t *font)
+{
+  return funcs->color_glyph (paint_data, glyph, font);
+}
+
+/**
  * hb_paint_push_clip_glyph:
  * @funcs: paint functions
  * @paint_data: associated data passed by the caller
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-paint.h b/src/java.desktop/share/native/libharfbuzz/hb-paint.h
index 96fec72..6215488 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-paint.h
+++ b/src/java.desktop/share/native/libharfbuzz/hb-paint.h
@@ -137,6 +137,26 @@
                                                void *user_data);
 
 /**
+ * hb_paint_color_glyph_func_t:
+ * @funcs: paint functions object
+ * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph()
+ * @glyph: the glyph ID
+ * @font: the font
+ * @user_data: User data pointer passed to hb_paint_funcs_set_color_glyph_func()
+ *
+ * A virtual method for the #hb_paint_funcs_t to render a color glyph by glyph index.
+ *
+ * Return value: %true if the glyph was painted, %false otherwise.
+ *
+ * Since: 8.2.0
+ */
+typedef hb_bool_t (*hb_paint_color_glyph_func_t) (hb_paint_funcs_t *funcs,
+                                                  void *paint_data,
+                                                  hb_codepoint_t glyph,
+                                                  hb_font_t *font,
+                                                  void *user_data);
+
+/**
  * hb_paint_push_clip_glyph_func_t:
  * @funcs: paint functions object
  * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph()
@@ -724,6 +744,23 @@
                                        hb_destroy_func_t              destroy);
 
 /**
+ * hb_paint_funcs_set_color_glyph_func:
+ * @funcs: A paint functions struct
+ * @func: (closure user_data) (destroy destroy) (scope notified): The color-glyph callback
+ * @user_data: Data to pass to @func
+ * @destroy: (nullable): Function to call when @user_data is no longer needed
+ *
+ * Sets the color-glyph callback on the paint functions struct.
+ *
+ * Since: 8.2.0
+ */
+HB_EXTERN void
+hb_paint_funcs_set_color_glyph_func (hb_paint_funcs_t                *funcs,
+                                     hb_paint_color_glyph_func_t     func,
+                                     void                            *user_data,
+                                     hb_destroy_func_t                destroy);
+
+/**
  * hb_paint_funcs_set_push_clip_glyph_func:
  * @funcs: A paint functions struct
  * @func: (closure user_data) (destroy destroy) (scope notified): The push-clip-glyph callback
@@ -922,6 +959,11 @@
 HB_EXTERN void
 hb_paint_pop_transform (hb_paint_funcs_t *funcs, void *paint_data);
 
+HB_EXTERN hb_bool_t
+hb_paint_color_glyph (hb_paint_funcs_t *funcs, void *paint_data,
+                      hb_codepoint_t glyph,
+                      hb_font_t *font);
+
 HB_EXTERN void
 hb_paint_push_clip_glyph (hb_paint_funcs_t *funcs, void *paint_data,
                           hb_codepoint_t glyph,
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-paint.hh b/src/java.desktop/share/native/libharfbuzz/hb-paint.hh
index 2f81b5f..fbf4a08 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-paint.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-paint.hh
@@ -32,6 +32,7 @@
 #define HB_PAINT_FUNCS_IMPLEMENT_CALLBACKS \
   HB_PAINT_FUNC_IMPLEMENT (push_transform) \
   HB_PAINT_FUNC_IMPLEMENT (pop_transform) \
+  HB_PAINT_FUNC_IMPLEMENT (color_glyph) \
   HB_PAINT_FUNC_IMPLEMENT (push_clip_glyph) \
   HB_PAINT_FUNC_IMPLEMENT (push_clip_rectangle) \
   HB_PAINT_FUNC_IMPLEMENT (pop_clip) \
@@ -77,6 +78,13 @@
   void pop_transform (void *paint_data)
   { func.pop_transform (this, paint_data,
                         !user_data ? nullptr : user_data->pop_transform); }
+  bool color_glyph (void *paint_data,
+                    hb_codepoint_t glyph,
+                    hb_font_t *font)
+  { return func.color_glyph (this, paint_data,
+                             glyph,
+                             font,
+                             !user_data ? nullptr : user_data->push_clip_glyph); }
   void push_clip_glyph (void *paint_data,
                         hb_codepoint_t glyph,
                         hb_font_t *font)
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-pool.hh b/src/java.desktop/share/native/libharfbuzz/hb-pool.hh
index 66de27f..613c78d 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-pool.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-pool.hh
@@ -58,7 +58,7 @@
     if (unlikely (!next))
     {
       if (unlikely (!chunks.alloc (chunks.length + 1))) return nullptr;
-      chunk_t *chunk = (chunk_t *) hb_calloc (1, sizeof (chunk_t));
+      chunk_t *chunk = (chunk_t *) hb_malloc (sizeof (chunk_t));
       if (unlikely (!chunk)) return nullptr;
       chunks.push (chunk);
       next = chunk->thread ();
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-priority-queue.hh b/src/java.desktop/share/native/libharfbuzz/hb-priority-queue.hh
index bf1b282..2c8ccbf 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-priority-queue.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-priority-queue.hh
@@ -42,10 +42,11 @@
  * priority of its children. The heap is stored in an array, with the
  * children of node i stored at indices 2i + 1 and 2i + 2.
  */
+template <typename K>
 struct hb_priority_queue_t
 {
  private:
-  typedef hb_pair_t<int64_t, unsigned> item_t;
+  typedef hb_pair_t<K, unsigned> item_t;
   hb_vector_t<item_t> heap;
 
  public:
@@ -54,13 +55,19 @@
 
   bool in_error () const { return heap.in_error (); }
 
-  void insert (int64_t priority, unsigned value)
+#ifndef HB_OPTIMIZE_SIZE
+  HB_ALWAYS_INLINE
+#endif
+  void insert (K priority, unsigned value)
   {
     heap.push (item_t (priority, value));
     if (unlikely (heap.in_error ())) return;
     bubble_up (heap.length - 1);
   }
 
+#ifndef HB_OPTIMIZE_SIZE
+  HB_ALWAYS_INLINE
+#endif
   item_t pop_minimum ()
   {
     assert (!is_empty ());
@@ -106,8 +113,10 @@
     return 2 * index + 2;
   }
 
+  HB_ALWAYS_INLINE
   void bubble_down (unsigned index)
   {
+    repeat:
     assert (index < heap.length);
 
     unsigned left = left_child (index);
@@ -123,19 +132,21 @@
         && (!has_right || heap.arrayZ[index].first <= heap.arrayZ[right].first))
       return;
 
+    unsigned child;
     if (!has_right || heap.arrayZ[left].first < heap.arrayZ[right].first)
-    {
-      swap (index, left);
-      bubble_down (left);
-      return;
-    }
+      child = left;
+    else
+      child = right;
 
-    swap (index, right);
-    bubble_down (right);
+    swap (index, child);
+    index = child;
+    goto repeat;
   }
 
+  HB_ALWAYS_INLINE
   void bubble_up (unsigned index)
   {
+    repeat:
     assert (index < heap.length);
 
     if (index == 0) return;
@@ -145,7 +156,8 @@
       return;
 
     swap (index, parent_index);
-    bubble_up (parent_index);
+    index = parent_index;
+    goto repeat;
   }
 
   void swap (unsigned a, unsigned b)
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-repacker.hh b/src/java.desktop/share/native/libharfbuzz/hb-repacker.hh
index cd57ade..e9cd376 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-repacker.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-repacker.hh
@@ -79,7 +79,12 @@
   //                pass after this processing is done. Not super necessary as splits are
   //                only done where overflow is likely, so de-dup probably will get undone
   //                later anyways.
-  for (unsigned lookup_index : ext_context.lookups.keys ())
+
+  // The loop below can modify the contents of ext_context.lookups if new subtables are added
+  // to a lookup during a split. So save the initial set of lookup indices so the iteration doesn't
+  // risk access free'd memory if ext_context.lookups gets resized.
+  hb_set_t lookup_indices(ext_context.lookups.keys ());
+  for (unsigned lookup_index : lookup_indices)
   {
     graph::Lookup* lookup = ext_context.lookups.get(lookup_index);
     if (!lookup->split_subtables_if_needed (ext_context, lookup_index))
@@ -114,11 +119,15 @@
   // TODO(grieger): skip this for the 24 bit case.
   if (!ext_context.lookups) return true;
 
+  unsigned total_lookup_table_sizes = 0;
   hb_vector_t<lookup_size_t> lookup_sizes;
   lookup_sizes.alloc (ext_context.lookups.get_population (), true);
 
   for (unsigned lookup_index : ext_context.lookups.keys ())
   {
+    const auto& lookup_v = ext_context.graph.vertices_[lookup_index];
+    total_lookup_table_sizes += lookup_v.table_size ();
+
     const graph::Lookup* lookup = ext_context.lookups.get(lookup_index);
     hb_set_t visited;
     lookup_sizes.push (lookup_size_t {
@@ -131,14 +140,16 @@
   lookup_sizes.qsort ();
 
   size_t lookup_list_size = ext_context.graph.vertices_[ext_context.lookup_list_index].table_size ();
-  size_t l2_l3_size = lookup_list_size; // Lookup List + Lookups
-  size_t l3_l4_size = 0; // Lookups + SubTables
+  size_t l2_l3_size = lookup_list_size + total_lookup_table_sizes; // Lookup List + Lookups
+  size_t l3_l4_size = total_lookup_table_sizes; // Lookups + SubTables
   size_t l4_plus_size = 0; // SubTables + their descendants
 
   // Start by assuming all lookups are using extension subtables, this size will be removed later
   // if it's decided to not make a lookup extension.
   for (auto p : lookup_sizes)
   {
+    // TODO(garretrieger): this overestimates the extension subtables size because some extension subtables may be
+    //                     reused. However, we can't correct this until we have connected component analysis in place.
     unsigned subtables_size = p.num_subtables * 8;
     l3_l4_size += subtables_size;
     l4_plus_size += subtables_size;
@@ -159,8 +170,7 @@
       size_t subtables_size = ext_context.graph.find_subgraph_size (p.lookup_index, visited, 1) - lookup_size;
       size_t remaining_size = p.size - subtables_size - lookup_size;
 
-      l2_l3_size   += lookup_size;
-      l3_l4_size   += lookup_size + subtables_size;
+      l3_l4_size   += subtables_size;
       l3_l4_size   -= p.num_subtables * 8;
       l4_plus_size += subtables_size + remaining_size;
 
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-sanitize.hh b/src/java.desktop/share/native/libharfbuzz/hb-sanitize.hh
index 5949afb..3a6ec4f 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-sanitize.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-sanitize.hh
@@ -122,12 +122,14 @@
 {
   hb_sanitize_context_t () :
         start (nullptr), end (nullptr),
+        length (0),
         max_ops (0), max_subtables (0),
         recursion_depth (0),
         writable (false), edit_count (0),
         blob (nullptr),
         num_glyphs (65536),
-        num_glyphs_set (false) {}
+        num_glyphs_set (false),
+        lazy_some_gpos (false) {}
 
   const char *get_name () { return "SANITIZE"; }
   template <typename T, typename F>
@@ -155,6 +157,19 @@
   dispatch (const T &obj, Ts&&... ds) HB_AUTO_RETURN
   ( _dispatch (obj, hb_prioritize, std::forward<Ts> (ds)...) )
 
+  hb_sanitize_context_t (hb_blob_t *b) : hb_sanitize_context_t ()
+  {
+    init (b);
+
+    if (blob)
+      start_processing ();
+  }
+
+  ~hb_sanitize_context_t ()
+  {
+    if (blob)
+      end_processing ();
+  }
 
   void init (hb_blob_t *b)
   {
@@ -180,11 +195,15 @@
 
     const char *obj_start = (const char *) obj;
     if (unlikely (obj_start < this->start || this->end <= obj_start))
+    {
       this->start = this->end = nullptr;
+      this->length = 0;
+    }
     else
     {
       this->start = obj_start;
       this->end   = obj_start + hb_min (size_t (this->end - obj_start), obj->get_size ());
+      this->length = this->end - this->start;
     }
   }
 
@@ -192,6 +211,7 @@
   {
     this->start = this->blob->data;
     this->end = this->start + this->blob->length;
+    this->length = this->end - this->start;
     assert (this->start <= this->end); /* Must not overflow. */
   }
 
@@ -224,6 +244,7 @@
     hb_blob_destroy (this->blob);
     this->blob = nullptr;
     this->start = this->end = nullptr;
+    this->length = 0;
   }
 
   unsigned get_edit_count () { return edit_count; }
@@ -237,18 +258,20 @@
       this->max_ops = -1;
       return false;
     }
-    return (this->max_ops -= (int) count) > 0;
+    this->max_ops -= (int) count;
+    return true;
   }
 
+#ifndef HB_OPTIMIZE_SIZE
+  HB_ALWAYS_INLINE
+#endif
   bool check_range (const void *base,
                     unsigned int len) const
   {
     const char *p = (const char *) base;
-    bool ok = !len ||
-              (this->start <= p &&
-               p <= this->end &&
-               (unsigned int) (this->end - p) >= len &&
-               (this->max_ops -= len) > 0);
+    bool ok = (uintptr_t) (p - this->start) <= this->length &&
+              (unsigned int) (this->end - p) >= len &&
+              ((this->max_ops -= len) > 0);
 
     DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0,
                      "check_range [%p..%p]"
@@ -259,6 +282,43 @@
 
     return likely (ok);
   }
+#ifndef HB_OPTIMIZE_SIZE
+  HB_ALWAYS_INLINE
+#endif
+  bool check_range_fast (const void *base,
+                         unsigned int len) const
+  {
+    const char *p = (const char *) base;
+    bool ok = ((uintptr_t) (p - this->start) <= this->length &&
+               (unsigned int) (this->end - p) >= len);
+
+    DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0,
+                     "check_range_fast [%p..%p]"
+                     " (%u bytes) in [%p..%p] -> %s",
+                     p, p + len, len,
+                     this->start, this->end,
+                     ok ? "OK" : "OUT-OF-RANGE");
+
+    return likely (ok);
+  }
+
+#ifndef HB_OPTIMIZE_SIZE
+  HB_ALWAYS_INLINE
+#endif
+  bool check_point (const void *base) const
+  {
+    const char *p = (const char *) base;
+    bool ok = (uintptr_t) (p - this->start) <= this->length;
+
+    DEBUG_MSG_LEVEL (SANITIZE, p, this->debug_depth+1, 0,
+                     "check_point [%p]"
+                     " in [%p..%p] -> %s",
+                     p,
+                     this->start, this->end,
+                     ok ? "OK" : "OUT-OF-RANGE");
+
+    return likely (ok);
+  }
 
   template <typename T>
   bool check_range (const T *base,
@@ -282,6 +342,20 @@
   }
 
   template <typename T>
+  HB_ALWAYS_INLINE
+  bool check_array_sized (const T *base, unsigned int len, unsigned len_size) const
+  {
+    if (len_size >= 4)
+    {
+      if (unlikely (hb_unsigned_mul_overflows (len, hb_static_size (T), &len)))
+        return false;
+    }
+    else
+      len = len * hb_static_size (T);
+    return this->check_range (base, len);
+  }
+
+  template <typename T>
   bool check_array (const T *base, unsigned int len) const
   {
     return this->check_range (base, len, hb_static_size (T));
@@ -292,7 +366,7 @@
                     unsigned int a,
                     unsigned int b) const
   {
-    return this->check_range (base, a, b, hb_static_size (T));
+    return this->check_range (base, hb_static_size (T), a, b);
   }
 
   bool check_start_recursion (int max_depth)
@@ -308,8 +382,16 @@
   }
 
   template <typename Type>
+#ifndef HB_OPTIMIZE_SIZE
+  HB_ALWAYS_INLINE
+#endif
   bool check_struct (const Type *obj) const
-  { return likely (this->check_range (obj, obj->min_size)); }
+  {
+    if (sizeof (uintptr_t) == sizeof (uint32_t))
+      return likely (this->check_range_fast (obj, obj->min_size));
+    else
+      return likely (this->check_point ((const char *) obj + obj->min_size));
+  }
 
   bool may_edit (const void *base, unsigned int len)
   {
@@ -371,7 +453,7 @@
         edit_count = 0;
         sane = t->sanitize (this);
         if (edit_count) {
-          DEBUG_MSG_FUNC (SANITIZE, start, "requested %u edits in second round; FAILLING", edit_count);
+          DEBUG_MSG_FUNC (SANITIZE, start, "requested %u edits in second round; FAILING", edit_count);
           sane = false;
         }
       }
@@ -416,6 +498,7 @@
   }
 
   const char *start, *end;
+  unsigned length;
   mutable int max_ops, max_subtables;
   private:
   int recursion_depth;
@@ -424,6 +507,8 @@
   hb_blob_t *blob;
   unsigned int num_glyphs;
   bool  num_glyphs_set;
+  public:
+  bool lazy_some_gpos;
 };
 
 struct hb_sanitize_with_object_t
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-serialize.hh b/src/java.desktop/share/native/libharfbuzz/hb-serialize.hh
index b4f0c48..675eb03 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-serialize.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-serialize.hh
@@ -113,7 +113,7 @@
     {
       // Virtual links aren't considered for equality since they don't affect the functionality
       // of the object.
-      return hb_bytes_t (head, tail - head).hash () ^
+      return hb_bytes_t (head, hb_min (128, tail - head)).hash () ^
           real_links.as_bytes ().hash ();
     }
 
@@ -172,8 +172,14 @@
   };
 
   snapshot_t snapshot ()
-  { return snapshot_t {
-      head, tail, current, current->real_links.length, current->virtual_links.length, errors }; }
+  {
+    return snapshot_t {
+      head, tail, current,
+      current ? current->real_links.length : 0,
+      current ? current->virtual_links.length : 0,
+      errors
+     };
+  }
 
   hb_serialize_context_t (void *start_, unsigned int size) :
     start ((char *) start_),
@@ -260,7 +266,8 @@
            propagate_error (std::forward<Ts> (os)...); }
 
   /* To be called around main operation. */
-  template <typename Type>
+  template <typename Type=char>
+  __attribute__((returns_nonnull))
   Type *start_serialize ()
   {
     DEBUG_MSG_LEVEL (SERIALIZE, this->start, 0, +1,
@@ -303,6 +310,7 @@
   }
 
   template <typename Type = void>
+  __attribute__((returns_nonnull))
   Type *push ()
   {
     if (unlikely (in_error ())) return start_embed<Type> ();
@@ -323,6 +331,8 @@
   {
     object_t *obj = current;
     if (unlikely (!obj)) return;
+    // Allow cleanup when we've error'd out on int overflows which don't compromise
+    // the serializer state.
     if (unlikely (in_error() && !only_overflow ())) return;
 
     current = current->next;
@@ -340,7 +350,9 @@
   {
     object_t *obj = current;
     if (unlikely (!obj)) return 0;
-    if (unlikely (in_error())) return 0;
+    // Allow cleanup when we've error'd out on int overflows which don't compromise
+    // the serializer state.
+    if (unlikely (in_error()  && !only_overflow ())) return 0;
 
     current = current->next;
     obj->tail = head;
@@ -405,8 +417,11 @@
     // Overflows that happened after the snapshot will be erased by the revert.
     if (unlikely (in_error () && !only_overflow ())) return;
     assert (snap.current == current);
-    current->real_links.shrink (snap.num_real_links);
-    current->virtual_links.shrink (snap.num_virtual_links);
+    if (current)
+    {
+      current->real_links.shrink (snap.num_real_links);
+      current->virtual_links.shrink (snap.num_virtual_links);
+    }
     errors = snap.errors;
     revert (snap.head, snap.tail);
   }
@@ -563,13 +578,15 @@
   {
     unsigned int l = length () % alignment;
     if (l)
-      allocate_size<void> (alignment - l);
+      (void) allocate_size<void> (alignment - l);
   }
 
   template <typename Type = void>
+  __attribute__((returns_nonnull))
   Type *start_embed (const Type *obj HB_UNUSED = nullptr) const
   { return reinterpret_cast<Type *> (this->head); }
   template <typename Type>
+  __attribute__((returns_nonnull))
   Type *start_embed (const Type &obj) const
   { return start_embed (std::addressof (obj)); }
 
@@ -597,6 +614,7 @@
   }
 
   template <typename Type>
+  HB_NODISCARD
   Type *allocate_size (size_t size, bool clear = true)
   {
     if (unlikely (in_error ())) return nullptr;
@@ -618,6 +636,7 @@
   { return this->allocate_size<Type> (Type::min_size); }
 
   template <typename Type>
+  HB_NODISCARD
   Type *embed (const Type *obj)
   {
     unsigned int size = obj->get_size ();
@@ -627,6 +646,7 @@
     return ret;
   }
   template <typename Type>
+  HB_NODISCARD
   Type *embed (const Type &obj)
   { return embed (std::addressof (obj)); }
   char *embed (const char *obj, unsigned size)
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-set-digest.hh b/src/java.desktop/share/native/libharfbuzz/hb-set-digest.hh
index d3f5915..c1e107b 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-set-digest.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-set-digest.hh
@@ -45,10 +45,16 @@
  * a lookup's or subtable's Coverage table(s), and then when we
  * want to apply the lookup or subtable to a glyph, before trying
  * to apply, we ask the filter if the glyph may be covered. If it's
- * not, we return early.
+ * not, we return early.  We can also match a digest against another
+ * digest.
  *
- * We use these filters both at the lookup-level, and then again,
- * at the subtable-level. Both have performance win.
+ * We use these filters at three levels:
+ *   - If the digest for all the glyphs in the buffer as a whole
+ *     does not match the digest for the lookup, skip the lookup.
+ *   - For each glyph, if it doesn't match the lookup digest,
+ *     skip it.
+ *   - For each glyph, if it doesn't match the subtable digest,
+ *     skip it.
  *
  * The main filter we use is a combination of three bits-pattern
  * filters. A bits-pattern filter checks a number of bits (5 or 6)
@@ -82,14 +88,19 @@
 
   bool add_range (hb_codepoint_t a, hb_codepoint_t b)
   {
+    if (mask == (mask_t) -1) return false;
     if ((b >> shift) - (a >> shift) >= mask_bits - 1)
+    {
       mask = (mask_t) -1;
-    else {
+      return false;
+    }
+    else
+    {
       mask_t ma = mask_for (a);
       mask_t mb = mask_for (b);
       mask |= mb + (mb - ma) - (mb < ma);
+      return true;
     }
-    return true;
   }
 
   template <typename T>
@@ -148,8 +159,7 @@
 
   bool add_range (hb_codepoint_t a, hb_codepoint_t b)
   {
-    return head.add_range (a, b) &&
-           tail.add_range (a, b);
+    return (int) head.add_range (a, b) | (int) tail.add_range (a, b);
   }
   template <typename T>
   void add_array (const T *array, unsigned int count, unsigned int stride=sizeof(T))
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-set.cc b/src/java.desktop/share/native/libharfbuzz/hb-set.cc
index 3f03d67..6d45840 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-set.cc
+++ b/src/java.desktop/share/native/libharfbuzz/hb-set.cc
@@ -200,7 +200,7 @@
 void
 hb_set_clear (hb_set_t *set)
 {
-  /* Immutible-safe. */
+  /* Immutable-safe. */
   set->clear ();
 }
 
@@ -251,7 +251,7 @@
 hb_set_add (hb_set_t       *set,
             hb_codepoint_t  codepoint)
 {
-  /* Immutible-safe. */
+  /* Immutable-safe. */
   set->add (codepoint);
 }
 
@@ -272,7 +272,7 @@
                          const hb_codepoint_t *sorted_codepoints,
                          unsigned int          num_codepoints)
 {
-  /* Immutible-safe. */
+  /* Immutable-safe. */
   set->add_sorted_array (sorted_codepoints,
                          num_codepoints,
                          sizeof(hb_codepoint_t));
@@ -294,7 +294,7 @@
                   hb_codepoint_t  first,
                   hb_codepoint_t  last)
 {
-  /* Immutible-safe. */
+  /* Immutable-safe. */
   set->add_range (first, last);
 }
 
@@ -311,7 +311,7 @@
 hb_set_del (hb_set_t       *set,
             hb_codepoint_t  codepoint)
 {
-  /* Immutible-safe. */
+  /* Immutable-safe. */
   set->del (codepoint);
 }
 
@@ -334,7 +334,7 @@
                   hb_codepoint_t  first,
                   hb_codepoint_t  last)
 {
-  /* Immutible-safe. */
+  /* Immutable-safe. */
   set->del_range (first, last);
 }
 
@@ -405,7 +405,7 @@
 hb_set_set (hb_set_t       *set,
             const hb_set_t *other)
 {
-  /* Immutible-safe. */
+  /* Immutable-safe. */
   set->set (*other);
 }
 
@@ -422,7 +422,7 @@
 hb_set_union (hb_set_t       *set,
               const hb_set_t *other)
 {
-  /* Immutible-safe. */
+  /* Immutable-safe. */
   set->union_ (*other);
 }
 
@@ -439,7 +439,7 @@
 hb_set_intersect (hb_set_t       *set,
                   const hb_set_t *other)
 {
-  /* Immutible-safe. */
+  /* Immutable-safe. */
   set->intersect (*other);
 }
 
@@ -456,7 +456,7 @@
 hb_set_subtract (hb_set_t       *set,
                  const hb_set_t *other)
 {
-  /* Immutible-safe. */
+  /* Immutable-safe. */
   set->subtract (*other);
 }
 
@@ -474,7 +474,7 @@
 hb_set_symmetric_difference (hb_set_t       *set,
                              const hb_set_t *other)
 {
-  /* Immutible-safe. */
+  /* Immutable-safe. */
   set->symmetric_difference (*other);
 }
 
@@ -489,7 +489,7 @@
 void
 hb_set_invert (hb_set_t *set)
 {
-  /* Immutible-safe. */
+  /* Immutable-safe. */
   set->invert ();
 }
 
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-set.h b/src/java.desktop/share/native/libharfbuzz/hb-set.h
index e20f37e..25ea1ca 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-set.h
+++ b/src/java.desktop/share/native/libharfbuzz/hb-set.h
@@ -43,7 +43,7 @@
  *
  * Since: 0.9.21
  */
-#define HB_SET_VALUE_INVALID ((hb_codepoint_t) -1)
+#define HB_SET_VALUE_INVALID HB_CODEPOINT_INVALID
 
 /**
  * hb_set_t:
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-set.hh b/src/java.desktop/share/native/libharfbuzz/hb-set.hh
index afebc1a..4aa6826 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-set.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-set.hh
@@ -115,7 +115,7 @@
   /* Sink interface. */
   hb_sparseset_t& operator << (hb_codepoint_t v)
   { add (v); return *this; }
-  hb_sparseset_t& operator << (const hb_pair_t<hb_codepoint_t, hb_codepoint_t>& range)
+  hb_sparseset_t& operator << (const hb_codepoint_pair_t& range)
   { add_range (range.first, range.second); return *this; }
 
   bool intersects (hb_codepoint_t first, hb_codepoint_t last) const
@@ -174,7 +174,7 @@
 
   hb_set_t& operator << (hb_codepoint_t v)
   { sparseset::operator<< (v); return *this; }
-  hb_set_t& operator << (const hb_pair_t<hb_codepoint_t, hb_codepoint_t>& range)
+  hb_set_t& operator << (const hb_codepoint_pair_t& range)
   { sparseset::operator<< (range); return *this; }
 };
 
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-shape.cc b/src/java.desktop/share/native/libharfbuzz/hb-shape.cc
index 6dbbf73..2f7d335 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-shape.cc
+++ b/src/java.desktop/share/native/libharfbuzz/hb-shape.cc
@@ -220,7 +220,7 @@
   assert (buffer->ensure (text.length));
   buffer->have_positions = false;
   buffer->len = text.length;
-  memcpy (buffer->info, text.arrayZ, text.length * sizeof (buffer->info[0]));
+  hb_memcpy (buffer->info, text.arrayZ, text.length * sizeof (buffer->info[0]));
   hb_buffer_set_content_type (buffer, HB_BUFFER_CONTENT_TYPE_UNICODE);
 }
 
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-shaper-list.hh b/src/java.desktop/share/native/libharfbuzz/hb-shaper-list.hh
index 4158b70..f079caf 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-shaper-list.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-shaper-list.hh
@@ -33,6 +33,11 @@
 
 /* v--- Add new shapers in the right place here. */
 
+#ifdef HAVE_WASM
+/* Only picks up fonts that have a "Wasm" table. */
+HB_SHAPER_IMPLEMENT (wasm)
+#endif
+
 #ifdef HAVE_GRAPHITE2
 /* Only picks up fonts that have a "Silf" table. */
 HB_SHAPER_IMPLEMENT (graphite2)
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-static.cc b/src/java.desktop/share/native/libharfbuzz/hb-static.cc
index 041d378..abdfda9 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-static.cc
+++ b/src/java.desktop/share/native/libharfbuzz/hb-static.cc
@@ -31,6 +31,7 @@
 
 #include "hb-aat-layout-common.hh"
 #include "hb-aat-layout-feat-table.hh"
+#include "hb-cff-interp-common.hh"
 #include "hb-ot-layout-common.hh"
 #include "hb-ot-cmap-table.hh"
 #include "OT/Color/COLR/COLR.hh"
@@ -58,6 +59,8 @@
 /* hb_map_t */
 
 const hb_codepoint_t minus_1 = -1;
+static const unsigned char static_endchar_str[] = {OpCode_endchar};
+const unsigned char *endchar_str = static_endchar_str;
 
 /* hb_face_t */
 
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-accelerator.hh b/src/java.desktop/share/native/libharfbuzz/hb-subset-accelerator.hh
index df6423a..c2cb714 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-subset-accelerator.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-accelerator.hh
@@ -42,7 +42,9 @@
 
 namespace OT {
 struct SubtableUnicodesCache;
-};
+struct cff1_subset_accelerator_t;
+struct cff2_subset_accelerator_t;
+}
 
 struct hb_subset_accelerator_t
 {
@@ -51,15 +53,17 @@
     return &_hb_subset_accelerator_user_data_key;
   }
 
-  static hb_subset_accelerator_t* create(const hb_map_t& unicode_to_gid_,
-                                         const hb_multimap_t gid_to_unicodes_,
+  static hb_subset_accelerator_t* create(hb_face_t *source,
+                                         const hb_map_t& unicode_to_gid_,
                                          const hb_set_t& unicodes_,
                                          bool has_seac_) {
     hb_subset_accelerator_t* accel =
         (hb_subset_accelerator_t*) hb_calloc (1, sizeof(hb_subset_accelerator_t));
 
-    new (accel) hb_subset_accelerator_t (unicode_to_gid_,
-                                         gid_to_unicodes_,
+    if (unlikely (!accel)) return accel;
+
+    new (accel) hb_subset_accelerator_t (source,
+                                         unicode_to_gid_,
                                          unicodes_,
                                          has_seac_);
 
@@ -77,36 +81,36 @@
     hb_free (accel);
   }
 
-  hb_subset_accelerator_t (const hb_map_t& unicode_to_gid_,
-                           const hb_multimap_t& gid_to_unicodes_,
+  hb_subset_accelerator_t (hb_face_t *source,
+                           const hb_map_t& unicode_to_gid_,
                            const hb_set_t& unicodes_,
                            bool has_seac_) :
     unicode_to_gid(unicode_to_gid_),
-    gid_to_unicodes (gid_to_unicodes_),
     unicodes(unicodes_),
     cmap_cache(nullptr),
     destroy_cmap_cache(nullptr),
     has_seac(has_seac_),
-    cff_accelerator(nullptr),
-    destroy_cff_accelerator(nullptr) {}
-
-  ~hb_subset_accelerator_t ()
+    source(hb_face_reference (source))
   {
-    if (cff_accelerator && destroy_cff_accelerator)
-      destroy_cff_accelerator ((void*) cff_accelerator);
-
-    if (cmap_cache && destroy_cmap_cache)
-      destroy_cmap_cache ((void*) cmap_cache);
+    gid_to_unicodes.alloc (unicode_to_gid.get_population ());
+    for (const auto &_ : unicode_to_gid)
+    {
+      auto unicode = _.first;
+      auto gid = _.second;
+      gid_to_unicodes.add (gid, unicode);
+    }
   }
 
+  HB_INTERNAL ~hb_subset_accelerator_t ();
+
   // Generic
 
   mutable hb_mutex_t sanitized_table_cache_lock;
   mutable hb_hashmap_t<hb_tag_t, hb::unique_ptr<hb_blob_t>> sanitized_table_cache;
 
-  const hb_map_t unicode_to_gid;
-  const hb_multimap_t gid_to_unicodes;
-  const hb_set_t unicodes;
+  hb_map_t unicode_to_gid;
+  hb_multimap_t gid_to_unicodes;
+  hb_set_t unicodes;
 
   // cmap
   const OT::SubtableUnicodesCache* cmap_cache;
@@ -114,8 +118,6 @@
 
   // CFF
   bool has_seac;
-  const CFF::cff_subset_accelerator_t* cff_accelerator;
-  hb_destroy_func_t destroy_cff_accelerator;
 
   // TODO(garretrieger): cumulative glyf checksum map
 
@@ -126,6 +128,13 @@
            unicodes.in_error () ||
            sanitized_table_cache.in_error ();
   }
+
+  hb_face_t *source;
+#ifndef HB_NO_SUBSET_CFF
+  // These have to be immediately after source:
+  mutable hb_face_lazy_loader_t<OT::cff1_subset_accelerator_t, 1> cff1_accel;
+  mutable hb_face_lazy_loader_t<OT::cff2_subset_accelerator_t, 2> cff2_accel;
+#endif
 };
 
 
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-cff-common.cc b/src/java.desktop/share/native/libharfbuzz/hb-subset-cff-common.cc
index 349d849..41b1236 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-subset-cff-common.cc
+++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-cff-common.cc
@@ -68,24 +68,35 @@
     /* use hb_set to determine the subset of font dicts */
     hb_set_t set;
     hb_codepoint_t prev_fd = CFF_UNDEF_CODE;
-    for (hb_codepoint_t i = 0; i < subset_num_glyphs; i++)
+    hb_pair_t<unsigned, hb_codepoint_t> last_range {0, 0};
+    auto it = hb_iter (plan->new_to_old_gid_list);
+    auto _ = *it;
+    for (hb_codepoint_t gid = 0; gid < subset_num_glyphs; gid++)
     {
-      hb_codepoint_t glyph;
-      hb_codepoint_t fd;
-      if (!plan->old_gid_for_new_gid (i, &glyph))
+      hb_codepoint_t old_glyph;
+      if (gid == _.first)
+      {
+        old_glyph = _.second;
+        _ = *++it;
+      }
+      else
       {
         /* fonttools retains FDSelect & font dicts for missing glyphs. do the same */
-        glyph = i;
+        old_glyph = gid;
       }
-      fd = src.get_fd (glyph);
-      set.add (fd);
+      if (old_glyph >= last_range.second)
+        last_range = src.get_fd_range (old_glyph);
+      unsigned fd = last_range.first;
 
       if (fd != prev_fd)
       {
+        set.add (fd);
         num_ranges++;
         prev_fd = fd;
-        code_pair_t pair = { fd, i };
-        fdselect_ranges.push (pair);
+        fdselect_ranges.push (code_pair_t { fd, gid });
+
+        if (gid == old_glyph)
+          gid = hb_min (_.first - 1, last_range.second - 1);
       }
     }
 
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-cff-common.hh b/src/java.desktop/share/native/libharfbuzz/hb-subset-cff-common.hh
index 73a58ea..4213f7e 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-subset-cff-common.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-cff-common.hh
@@ -480,6 +480,7 @@
       const hb_vector_t<parsed_cs_str_vec_t>& parsed_local_subrs) {
     cff_subset_accelerator_t* accel =
         (cff_subset_accelerator_t*) hb_malloc (sizeof(cff_subset_accelerator_t));
+    if (unlikely (!accel)) return nullptr;
     new (accel) cff_subset_accelerator_t (original_blob,
                                           parsed_charstrings,
                                           parsed_global_subrs,
@@ -510,15 +511,21 @@
     original_blob = hb_blob_reference (original_blob_);
   }
 
-  ~cff_subset_accelerator_t() {
+  ~cff_subset_accelerator_t()
+  {
     hb_blob_destroy (original_blob);
-    hb_map_destroy (glyph_to_sid_map.get_relaxed ());
+    auto *mapping = glyph_to_sid_map.get_relaxed ();
+    if (mapping)
+    {
+      mapping->~glyph_to_sid_map_t ();
+      hb_free (mapping);
+    }
   }
 
   parsed_cs_str_vec_t parsed_charstrings;
   parsed_cs_str_vec_t parsed_global_subrs;
   hb_vector_t<parsed_cs_str_vec_t> parsed_local_subrs;
-  mutable hb_atomic_ptr_t<hb_map_t> glyph_to_sid_map = nullptr;
+  mutable hb_atomic_ptr_t<glyph_to_sid_map_t> glyph_to_sid_map;
 
  private:
   hb_blob_t* original_blob;
@@ -600,9 +607,8 @@
      * no optimization based on usage counts. fonttools doesn't appear doing that either.
      */
 
-    resize (closure->get_population ());
-    hb_codepoint_t old_num = HB_SET_VALUE_INVALID;
-    while (hb_set_next (closure, &old_num))
+    alloc (closure->get_population ());
+    for (auto old_num : *closure)
       add (old_num);
 
     if (get_population () < 1240)
@@ -672,8 +678,8 @@
   {
     unsigned fd_count = acc.fdCount;
     const cff_subset_accelerator_t* cff_accelerator = nullptr;
-    if (plan->accelerator && plan->accelerator->cff_accelerator) {
-      cff_accelerator = plan->accelerator->cff_accelerator;
+    if (acc.cff_accelerator) {
+      cff_accelerator = acc.cff_accelerator;
       fd_count = cff_accelerator->parsed_local_subrs.length;
     }
 
@@ -709,14 +715,13 @@
     }
 
     /* phase 1 & 2 */
-    for (unsigned int i = 0; i < plan->num_output_glyphs (); i++)
+    for (auto _ : plan->new_to_old_gid_list)
     {
-      hb_codepoint_t  glyph;
-      if (!plan->old_gid_for_new_gid (i, &glyph))
-        continue;
+      hb_codepoint_t new_glyph = _.first;
+      hb_codepoint_t old_glyph = _.second;
 
-      const hb_ubytes_t str = (*acc.charStrings)[glyph];
-      unsigned int fd = acc.fdSelect->get_fd (glyph);
+      const hb_ubytes_t str = (*acc.charStrings)[old_glyph];
+      unsigned int fd = acc.fdSelect->get_fd (old_glyph);
       if (unlikely (fd >= acc.fdCount))
         return false;
 
@@ -725,9 +730,9 @@
         // parsed string already exists in accelerator, copy it and move
         // on.
         if (cached_charstrings)
-          cached_charstrings[i] = &cff_accelerator->parsed_charstrings[glyph];
+          cached_charstrings[new_glyph] = &cff_accelerator->parsed_charstrings[old_glyph];
         else
-          parsed_charstrings[i] = cff_accelerator->parsed_charstrings[glyph];
+          parsed_charstrings[new_glyph] = cff_accelerator->parsed_charstrings[old_glyph];
 
         continue;
       }
@@ -735,8 +740,8 @@
       ENV env (str, acc, fd);
       cs_interpreter_t<ENV, OPSET, subr_subset_param_t> interp (env);
 
-      parsed_charstrings[i].alloc (str.length);
-      subr_subset_param_t  param (&parsed_charstrings[i],
+      parsed_charstrings[new_glyph].alloc (str.length);
+      subr_subset_param_t  param (&parsed_charstrings[new_glyph],
                                   &parsed_global_subrs_storage,
                                   &parsed_local_subrs_storage[fd],
                                   &closures.global_closure,
@@ -747,12 +752,12 @@
         return false;
 
       /* complete parsed string esp. copy CFF1 width or CFF2 vsindex to the parsed charstring for encoding */
-      SUBSETTER::complete_parsed_str (interp.env, param, parsed_charstrings[i]);
+      SUBSETTER::complete_parsed_str (interp.env, param, parsed_charstrings[new_glyph]);
 
       /* mark hint ops and arguments for drop */
       if ((plan->flags & HB_SUBSET_FLAGS_NO_HINTING) || plan->inprogress_accelerator)
       {
-        subr_subset_param_t  param (&parsed_charstrings[i],
+        subr_subset_param_t  param (&parsed_charstrings[new_glyph],
                                     &parsed_global_subrs_storage,
                                     &parsed_local_subrs_storage[fd],
                                     &closures.global_closure,
@@ -760,21 +765,21 @@
                                     plan->flags & HB_SUBSET_FLAGS_NO_HINTING);
 
         drop_hints_param_t  drop;
-        if (drop_hints_in_str (parsed_charstrings[i], param, drop))
+        if (drop_hints_in_str (parsed_charstrings[new_glyph], param, drop))
         {
-          parsed_charstrings[i].set_hint_dropped ();
+          parsed_charstrings[new_glyph].set_hint_dropped ();
           if (drop.vsindex_dropped)
-            parsed_charstrings[i].set_vsindex_dropped ();
+            parsed_charstrings[new_glyph].set_vsindex_dropped ();
         }
       }
 
-      /* Doing this here one by one instead of compacting all at the en
+      /* Doing this here one by one instead of compacting all at the end
        * has massive peak-memory saving.
        *
        * The compacting both saves memory and makes further operations
        * faster.
        */
-      parsed_charstrings[i].compact ();
+      parsed_charstrings[new_glyph].compact ();
     }
 
     /* Since parsed strings were loaded from accelerator, we still need
@@ -797,23 +802,40 @@
 
   bool encode_charstrings (str_buff_vec_t &buffArray, bool encode_prefix = true) const
   {
-    if (unlikely (!buffArray.resize_exact (plan->num_output_glyphs ())))
+    unsigned num_glyphs = plan->num_output_glyphs ();
+    if (unlikely (!buffArray.resize_exact (num_glyphs)))
       return false;
-    for (unsigned int i = 0; i < plan->num_output_glyphs (); i++)
+    hb_codepoint_t last = 0;
+    for (auto _ : plan->new_to_old_gid_list)
     {
-      hb_codepoint_t  glyph;
-      if (!plan->old_gid_for_new_gid (i, &glyph))
-      {
-        /* add an endchar only charstring for a missing glyph if CFF1 */
-        if (endchar_op != OpCode_Invalid) buffArray.arrayZ[i].push (endchar_op);
-        continue;
-      }
-      unsigned int  fd = acc.fdSelect->get_fd (glyph);
+      hb_codepoint_t gid = _.first;
+      hb_codepoint_t old_glyph = _.second;
+
+      if (endchar_op != OpCode_Invalid)
+        for (; last < gid; last++)
+        {
+          // Hack to point vector to static string.
+          auto &b = buffArray.arrayZ[last];
+          b.length = 1;
+          b.arrayZ = const_cast<unsigned char *>(endchar_str);
+        }
+
+      last++; // Skip over gid
+      unsigned int  fd = acc.fdSelect->get_fd (old_glyph);
       if (unlikely (fd >= acc.fdCount))
         return false;
-      if (unlikely (!encode_str (get_parsed_charstring (i), fd, buffArray.arrayZ[i], encode_prefix)))
+      if (unlikely (!encode_str (get_parsed_charstring (gid), fd, buffArray.arrayZ[gid], encode_prefix)))
         return false;
     }
+    if (endchar_op != OpCode_Invalid)
+      for (; last < num_glyphs; last++)
+      {
+        // Hack to point vector to static string.
+        auto &b = buffArray.arrayZ[last];
+        b.length = 1;
+        b.arrayZ = const_cast<unsigned char *>(endchar_str);
+      }
+
     return true;
   }
 
@@ -980,24 +1002,23 @@
                             const hb_vector_t<parsed_cs_str_vec_t>& local_subrs)
   {
     closures.reset ();
-    for (unsigned int i = 0; i < plan->num_output_glyphs (); i++)
+    for (auto _ : plan->new_to_old_gid_list)
     {
-      hb_codepoint_t  glyph;
-      if (!plan->old_gid_for_new_gid (i, &glyph))
-        continue;
-      unsigned int fd = acc.fdSelect->get_fd (glyph);
+      hb_codepoint_t new_glyph = _.first;
+      hb_codepoint_t old_glyph = _.second;
+      unsigned int fd = acc.fdSelect->get_fd (old_glyph);
       if (unlikely (fd >= acc.fdCount))
         return false;
 
       // Note: const cast is safe here because the collect_subr_refs_in_str only performs a
       //       closure and does not modify any of the charstrings.
-      subr_subset_param_t  param (const_cast<parsed_cs_str_t*> (&get_parsed_charstring (i)),
+      subr_subset_param_t  param (const_cast<parsed_cs_str_t*> (&get_parsed_charstring (new_glyph)),
                                   const_cast<parsed_cs_str_vec_t*> (&global_subrs),
                                   const_cast<parsed_cs_str_vec_t*> (&local_subrs[fd]),
                                   &closures.global_closure,
                                   &closures.local_closures[fd],
                                   plan->flags & HB_SUBSET_FLAGS_NO_HINTING);
-      collect_subr_refs_in_str (get_parsed_charstring (i), param);
+      collect_subr_refs_in_str (get_parsed_charstring (new_glyph), param);
     }
 
     return true;
@@ -1105,14 +1126,11 @@
 
     compact_parsed_subrs ();
 
-    plan->inprogress_accelerator->cff_accelerator =
+    acc.cff_accelerator =
         cff_subset_accelerator_t::create(acc.blob,
                                          parsed_charstrings,
                                          parsed_global_subrs_storage,
                                          parsed_local_subrs_storage);
-    plan->inprogress_accelerator->destroy_cff_accelerator =
-        cff_subset_accelerator_t::destroy;
-
   }
 
   const parsed_cs_str_t& get_parsed_charstring (unsigned i) const
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-cff1.cc b/src/java.desktop/share/native/libharfbuzz/hb-subset-cff1.cc
index dd15975..780bf34 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-subset-cff1.cc
+++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-cff1.cc
@@ -32,36 +32,59 @@
 #include "hb-ot-cff1-table.hh"
 #include "hb-set.h"
 #include "hb-bimap.hh"
-#include "hb-subset-cff1.hh"
 #include "hb-subset-plan.hh"
 #include "hb-subset-cff-common.hh"
 #include "hb-cff1-interp-cs.hh"
 
 using namespace CFF;
 
-struct remap_sid_t : hb_inc_bimap_t
+struct remap_sid_t
 {
+  unsigned get_population () const { return vector.length; }
+
+  void alloc (unsigned size)
+  {
+    map.alloc (size);
+    vector.alloc (size, true);
+  }
+
+  bool in_error () const
+  { return map.in_error () || vector.in_error (); }
+
   unsigned int add (unsigned int sid)
   {
-    if ((sid != CFF_UNDEF_SID) && !is_std_std (sid))
-      return offset_sid (hb_inc_bimap_t::add (unoffset_sid (sid)));
-    else
+    if (is_std_str (sid) || (sid == CFF_UNDEF_SID))
       return sid;
+
+    sid = unoffset_sid (sid);
+    unsigned v = next;
+    if (map.set (sid, v, false))
+    {
+      vector.push (sid);
+      next++;
+    }
+    else
+      v = map.get (sid); // already exists
+    return offset_sid (v);
   }
 
   unsigned int operator[] (unsigned int sid) const
   {
-    if (is_std_std (sid) || (sid == CFF_UNDEF_SID))
+    if (is_std_str (sid) || (sid == CFF_UNDEF_SID))
       return sid;
-    else
-      return offset_sid (get (unoffset_sid (sid)));
+
+    return offset_sid (map.get (unoffset_sid (sid)));
   }
 
   static const unsigned int num_std_strings = 391;
 
-  static bool is_std_std (unsigned int sid) { return sid < num_std_strings; }
+  static bool is_std_str (unsigned int sid) { return sid < num_std_strings; }
   static unsigned int offset_sid (unsigned int sid) { return sid + num_std_strings; }
   static unsigned int unoffset_sid (unsigned int sid) { return sid - num_std_strings; }
+  unsigned next = 0;
+
+  hb_map_t map;
+  hb_vector_t<unsigned> vector;
 };
 
 struct cff1_sub_table_info_t : cff_sub_table_info_t
@@ -271,16 +294,17 @@
   /* replace the first glyph ID in the "glyph" field each range with a nLeft value */
   bool complete (unsigned int last_glyph)
   {
-    bool two_byte = false;
+    hb_codepoint_t all_glyphs = 0;
     unsigned count = this->length;
     for (unsigned int i = count; i; i--)
     {
       code_pair_t &pair = arrayZ[i - 1];
       unsigned int nLeft = last_glyph - pair.glyph - 1;
-      two_byte |= nLeft >= 0x100;
+      all_glyphs |= nLeft;
       last_glyph = pair.glyph;
       pair.glyph = nLeft;
     }
+    bool two_byte = all_glyphs >= 0x100;
     return two_byte;
   }
 };
@@ -391,8 +415,10 @@
   }
 };
 
-struct cff_subset_plan {
-  cff_subset_plan ()
+namespace OT {
+struct cff1_subset_plan
+{
+  cff1_subset_plan ()
   {
     for (unsigned int i = 0; i < name_dict_values_t::ValCount; i++)
       topDictModSIDs[i] = CFF_UNDEF_SID;
@@ -402,7 +428,7 @@
   {
     const Encoding *encoding = acc.encoding;
     unsigned int  size0, size1;
-    hb_codepoint_t  code, last_code = CFF_UNDEF_CODE;
+    unsigned code, last_code = CFF_UNDEF_CODE - 1;
     hb_vector_t<hb_codepoint_t> supp_codes;
 
     if (unlikely (!subset_enc_code_ranges.resize (0)))
@@ -413,39 +439,42 @@
 
     supp_codes.init ();
 
+    code_pair_t glyph_to_sid_cache {0, HB_CODEPOINT_INVALID};
     subset_enc_num_codes = plan->num_output_glyphs () - 1;
     unsigned int glyph;
-    for (glyph = 1; glyph < plan->num_output_glyphs (); glyph++)
+    auto it = hb_iter (plan->new_to_old_gid_list);
+    if (it->first == 0) it++;
+    auto _ = *it;
+    for (glyph = 1; glyph < num_glyphs; glyph++)
     {
-      hb_codepoint_t  old_glyph;
-      if (!plan->old_gid_for_new_gid (glyph, &old_glyph))
+      hb_codepoint_t old_glyph;
+      if (glyph == _.first)
       {
-        /* Retain the code for the old missing glyph ID */
+        old_glyph = _.second;
+        _ = *++it;
+      }
+      else
+      {
+        /* Retain the SID for the old missing glyph ID */
         old_glyph = glyph;
       }
-      code = acc.glyph_to_code (old_glyph);
+      code = acc.glyph_to_code (old_glyph, &glyph_to_sid_cache);
       if (code == CFF_UNDEF_CODE)
       {
         subset_enc_num_codes = glyph - 1;
         break;
       }
 
-      if ((last_code == CFF_UNDEF_CODE) || (code != last_code + 1))
-      {
-        code_pair_t pair = { code, glyph };
-        subset_enc_code_ranges.push (pair);
-      }
+      if (code != last_code + 1)
+        subset_enc_code_ranges.push (code_pair_t {code, glyph});
       last_code = code;
 
       if (encoding != &Null (Encoding))
       {
-        hb_codepoint_t  sid = acc.glyph_to_sid (old_glyph);
+        hb_codepoint_t  sid = acc.glyph_to_sid (old_glyph, &glyph_to_sid_cache);
         encoding->get_supplement_codes (sid, supp_codes);
         for (unsigned int i = 0; i < supp_codes.length; i++)
-        {
-          code_pair_t pair = { supp_codes[i], sid };
-          subset_enc_supp_codes.push (pair);
-        }
+          subset_enc_supp_codes.push (code_pair_t {supp_codes[i], sid});
       }
     }
     supp_codes.fini ();
@@ -462,65 +491,93 @@
       subset_enc_format = 1;
   }
 
-  void plan_subset_charset (const OT::cff1::accelerator_subset_t &acc, hb_subset_plan_t *plan)
+  bool plan_subset_charset (const OT::cff1::accelerator_subset_t &acc, hb_subset_plan_t *plan)
   {
     unsigned int  size0, size_ranges;
-    hb_codepoint_t  sid, last_sid = CFF_UNDEF_CODE;
+    unsigned last_sid = CFF_UNDEF_CODE - 1;
 
     if (unlikely (!subset_charset_ranges.resize (0)))
     {
       plan->check_success (false);
-      return;
+      return false;
     }
 
-    hb_map_t *glyph_to_sid_map = (plan->accelerator && plan->accelerator->cff_accelerator) ?
-                                  plan->accelerator->cff_accelerator->glyph_to_sid_map :
-                                  nullptr;
+    code_pair_t glyph_to_sid_cache {0, HB_CODEPOINT_INVALID};
+
+    unsigned num_glyphs = plan->num_output_glyphs ();
+
+    if (unlikely (!subset_charset_ranges.alloc (hb_min (num_glyphs,
+                                                        acc.num_charset_entries))))
+    {
+      plan->check_success (false);
+      return false;
+    }
+
+    glyph_to_sid_map_t *glyph_to_sid_map = acc.cff_accelerator ?
+                                           acc.cff_accelerator->glyph_to_sid_map.get_acquire () :
+                                           nullptr;
     bool created_map = false;
-    if (!glyph_to_sid_map &&
-        ((plan->accelerator && plan->accelerator->cff_accelerator) ||
-         plan->num_output_glyphs () > plan->source->get_num_glyphs () / 8.))
+    if (!glyph_to_sid_map && acc.cff_accelerator)
     {
       created_map = true;
       glyph_to_sid_map = acc.create_glyph_to_sid_map ();
     }
 
-    unsigned int glyph;
-    for (glyph = 1; glyph < plan->num_output_glyphs (); glyph++)
+    auto it = hb_iter (plan->new_to_old_gid_list);
+    if (it->first == 0) it++;
+    auto _ = *it;
+    bool not_is_cid = !acc.is_CID ();
+    bool skip = !not_is_cid && glyph_to_sid_map;
+    if (not_is_cid)
+      sidmap.alloc (num_glyphs);
+    for (hb_codepoint_t glyph = 1; glyph < num_glyphs; glyph++)
     {
-      hb_codepoint_t  old_glyph;
-      if (!plan->old_gid_for_new_gid (glyph, &old_glyph))
+      hb_codepoint_t old_glyph;
+      if (glyph == _.first)
+      {
+        old_glyph = _.second;
+        _ = *++it;
+      }
+      else
       {
         /* Retain the SID for the old missing glyph ID */
         old_glyph = glyph;
       }
-      sid = glyph_to_sid_map ? glyph_to_sid_map->get (old_glyph) : acc.glyph_to_sid (old_glyph);
+      unsigned sid = glyph_to_sid_map ?
+                     glyph_to_sid_map->arrayZ[old_glyph].code :
+                     acc.glyph_to_sid (old_glyph, &glyph_to_sid_cache);
 
-      if (!acc.is_CID ())
+      if (not_is_cid)
         sid = sidmap.add (sid);
 
-      if ((last_sid == CFF_UNDEF_CODE) || (sid != last_sid + 1))
+      if (sid != last_sid + 1)
+        subset_charset_ranges.push (code_pair_t {sid, glyph});
+
+      if (glyph == old_glyph && skip)
       {
-        code_pair_t pair = { sid, glyph };
-        subset_charset_ranges.push (pair);
+        glyph = hb_min (_.first - 1, glyph_to_sid_map->arrayZ[old_glyph].glyph);
+        sid += glyph - old_glyph;
       }
       last_sid = sid;
     }
 
     if (created_map)
     {
-      if (!(plan->accelerator && plan->accelerator->cff_accelerator) ||
-          !plan->accelerator->cff_accelerator->glyph_to_sid_map.cmpexch (nullptr, glyph_to_sid_map))
-        hb_map_destroy (glyph_to_sid_map);
+      if ((!plan->accelerator && acc.cff_accelerator) ||
+          !acc.cff_accelerator->glyph_to_sid_map.cmpexch (nullptr, glyph_to_sid_map))
+      {
+        glyph_to_sid_map->~glyph_to_sid_map_t ();
+        hb_free (glyph_to_sid_map);
+      }
     }
 
-    bool two_byte = subset_charset_ranges.complete (glyph);
+    bool two_byte = subset_charset_ranges.complete (num_glyphs);
 
-    size0 = Charset0::min_size + HBUINT16::static_size * (plan->num_output_glyphs () - 1);
+    size0 = Charset0::get_size (plan->num_output_glyphs ());
     if (!two_byte)
-      size_ranges = Charset1::min_size + Charset1_Range::static_size * subset_charset_ranges.length;
+      size_ranges = Charset1::get_size_for_ranges (subset_charset_ranges.length);
     else
-      size_ranges = Charset2::min_size + Charset2_Range::static_size * subset_charset_ranges.length;
+      size_ranges = Charset2::get_size_for_ranges (subset_charset_ranges.length);
 
     if (size0 < size_ranges)
       subset_charset_format = 0;
@@ -528,19 +585,18 @@
       subset_charset_format = 1;
     else
       subset_charset_format = 2;
+
+    return true;
   }
 
   bool collect_sids_in_dicts (const OT::cff1::accelerator_subset_t &acc)
   {
-    sidmap.reset ();
-
     for (unsigned int i = 0; i < name_dict_values_t::ValCount; i++)
     {
       unsigned int sid = acc.topDict.nameSIDs[i];
       if (sid != CFF_UNDEF_SID)
       {
-        (void)sidmap.add (sid);
-        topDictModSIDs[i] = sidmap[sid];
+        topDictModSIDs[i] = sidmap.add (sid);
       }
     }
 
@@ -564,19 +620,18 @@
     drop_hints = plan->flags & HB_SUBSET_FLAGS_NO_HINTING;
     desubroutinize = plan->flags & HB_SUBSET_FLAGS_DESUBROUTINIZE;
 
-    /* check whether the subset renumbers any glyph IDs */
-    gid_renum = false;
-    for (hb_codepoint_t new_glyph = 0; new_glyph < plan->num_output_glyphs (); new_glyph++)
-    {
-      if (!plan->old_gid_for_new_gid(new_glyph, &old_glyph))
-        continue;
-      if (new_glyph != old_glyph) {
-        gid_renum = true;
-        break;
+    subset_charset = !acc.is_predef_charset ();
+    if (!subset_charset)
+      /* check whether the subset renumbers any glyph IDs */
+      for (const auto &_ : plan->new_to_old_gid_list)
+      {
+        if (_.first != _.second)
+        {
+          subset_charset = true;
+          break;
+        }
       }
-    }
 
-    subset_charset = gid_renum || !acc.is_predef_charset ();
     subset_encoding = !acc.is_CID() && !acc.is_predef_encoding ();
 
     /* top dict INDEX */
@@ -618,7 +673,8 @@
       if (unlikely (sidmap.get_population () > 0x8000)) /* assumption: a dict won't reference that many strings */
         return false;
 
-      if (subset_charset) plan_subset_charset (acc, plan);
+      if (subset_charset && !plan_subset_charset (acc, plan))
+        return false;
 
       topdict_mod.reassignSIDs (sidmap);
     }
@@ -682,8 +738,9 @@
       ;
     }
 
-    return ((subset_charstrings.length == plan->num_output_glyphs ())
-           && (fontdicts_mod.length == subset_fdcount));
+    return !plan->in_error () &&
+           (subset_charstrings.length == plan->num_output_glyphs ()) &&
+           (fontdicts_mod.length == subset_fdcount);
   }
 
   cff1_top_dict_values_mod_t    topdict_mod;
@@ -722,24 +779,22 @@
 
   bool          desubroutinize = false;
 };
+} // namespace OT
 
-static bool _serialize_cff1 (hb_serialize_context_t *c,
-                             cff_subset_plan &plan,
-                             const OT::cff1::accelerator_subset_t  &acc,
-                             unsigned int num_glyphs)
+bool
+OT::cff1::accelerator_subset_t::serialize (hb_serialize_context_t *c,
+                                           struct OT::cff1_subset_plan &plan) const
 {
   /* private dicts & local subrs */
-  for (int i = (int)acc.privateDicts.length; --i >= 0 ;)
+  for (int i = (int) privateDicts.length; --i >= 0 ;)
   {
     if (plan.fdmap.has (i))
     {
       objidx_t  subrs_link = 0;
       if (plan.subset_localsubrs[i].length > 0)
       {
-        CFF1Subrs *dest = c->start_embed <CFF1Subrs> ();
-        if (unlikely (!dest)) return false;
-        c->push ();
-        if (likely (dest && dest->serialize (c, plan.subset_localsubrs[i])))
+        auto *dest = c->push <CFF1Subrs> ();
+        if (likely (dest->serialize (c, plan.subset_localsubrs[i])))
           subrs_link = c->pop_pack ();
         else
         {
@@ -748,12 +803,10 @@
         }
       }
 
-      PrivateDict *pd = c->start_embed<PrivateDict> ();
-      if (unlikely (!pd)) return false;
-      c->push ();
+      auto *pd = c->push<PrivateDict> ();
       cff1_private_dict_op_serializer_t privSzr (plan.desubroutinize, plan.drop_hints);
       /* N.B. local subrs immediately follows its corresponding private dict. i.e., subr offset == private dict size */
-      if (likely (pd->serialize (c, acc.privateDicts[i], privSzr, subrs_link)))
+      if (likely (pd->serialize (c, privateDicts[i], privSzr, subrs_link)))
       {
         unsigned fd = plan.fdmap[i];
         plan.fontdicts_mod[fd].privateDictInfo.size = c->length ();
@@ -767,21 +820,20 @@
     }
   }
 
-  if (!acc.is_CID ())
+  if (!is_CID ())
     plan.info.privateDictInfo = plan.fontdicts_mod[0].privateDictInfo;
 
   /* CharStrings */
   {
     c->push<CFF1CharStrings> ();
 
-    unsigned total_size = CFF1CharStrings::total_size (plan.subset_charstrings);
+    unsigned data_size = 0;
+    unsigned total_size = CFF1CharStrings::total_size (plan.subset_charstrings, &data_size);
     if (unlikely (!c->start_zerocopy (total_size)))
        return false;
 
-    CFF1CharStrings  *cs = c->start_embed<CFF1CharStrings> ();
-    if (unlikely (!cs)) return false;
-
-    if (likely (cs->serialize (c, plan.subset_charstrings)))
+    auto *cs = c->start_embed<CFF1CharStrings> ();
+    if (likely (cs->serialize (c, plan.subset_charstrings, &data_size)))
       plan.info.char_strings_link = c->pop_pack (false);
     else
     {
@@ -791,11 +843,9 @@
   }
 
   /* FDArray (FD Index) */
-  if (acc.fdArray != &Null (CFF1FDArray))
+  if (fdArray != &Null (CFF1FDArray))
   {
-    CFF1FDArray *fda = c->start_embed<CFF1FDArray> ();
-    if (unlikely (!fda)) return false;
-    c->push ();
+    auto *fda = c->push<CFF1FDArray> ();
     cff1_font_dict_op_serializer_t  fontSzr;
     auto it = + hb_zip (+ hb_iter (plan.fontdicts_mod), + hb_iter (plan.fontdicts_mod));
     if (likely (fda->serialize (c, it, fontSzr)))
@@ -808,10 +858,10 @@
   }
 
   /* FDSelect */
-  if (acc.fdSelect != &Null (CFF1FDSelect))
+  if (fdSelect != &Null (CFF1FDSelect))
   {
     c->push ();
-    if (likely (hb_serialize_cff_fdselect (c, num_glyphs, *acc.fdSelect, acc.fdCount,
+    if (likely (hb_serialize_cff_fdselect (c, plan.num_glyphs, *fdSelect, fdCount,
                                            plan.subset_fdselect_format, plan.info.fd_select.size,
                                            plan.subset_fdselect_ranges)))
       plan.info.fd_select.link = c->pop_pack ();
@@ -825,9 +875,7 @@
   /* Charset */
   if (plan.subset_charset)
   {
-    Charset *dest = c->start_embed<Charset> ();
-    if (unlikely (!dest)) return false;
-    c->push ();
+    auto *dest = c->push<Charset> ();
     if (likely (dest->serialize (c,
                                  plan.subset_charset_format,
                                  plan.num_glyphs,
@@ -843,9 +891,7 @@
   /* Encoding */
   if (plan.subset_encoding)
   {
-    Encoding *dest = c->start_embed<Encoding> ();
-    if (unlikely (!dest)) return false;
-    c->push ();
+    auto *dest = c->push<Encoding> ();
     if (likely (dest->serialize (c,
                                  plan.subset_enc_format,
                                  plan.subset_enc_num_codes,
@@ -861,9 +907,7 @@
 
   /* global subrs */
   {
-    c->push ();
-    CFF1Subrs *dest = c->start_embed <CFF1Subrs> ();
-    if (unlikely (!dest)) return false;
+    auto *dest = c->push <CFF1Subrs> ();
     if (likely (dest->serialize (c, plan.subset_globalsubrs)))
       c->pop_pack (false);
     else
@@ -875,10 +919,9 @@
 
   /* String INDEX */
   {
-    CFF1StringIndex *dest = c->start_embed<CFF1StringIndex> ();
-    if (unlikely (!dest)) return false;
-    c->push ();
-    if (likely (dest->serialize (c, *acc.stringIndex, plan.sidmap)))
+    auto *dest = c->push<CFF1StringIndex> ();
+    if (likely (!plan.sidmap.in_error () &&
+                dest->serialize (c, *stringIndex, plan.sidmap.vector)))
       c->pop_pack ();
     else
     {
@@ -898,14 +941,12 @@
   cff->offSize = 4; /* unused? */
 
   /* name INDEX */
-  if (unlikely (!(*acc.nameIndex).copy (c))) return false;
+  if (unlikely (!c->embed (*nameIndex))) return false;
 
   /* top dict INDEX */
   {
     /* serialize singleton TopDict */
-    TopDict *top = c->start_embed<TopDict> ();
-    if (!top) return false;
-    c->push ();
+    auto *top = c->push<TopDict> ();
     cff1_top_dict_op_serializer_t topSzr;
     unsigned top_size = 0;
     top_dict_modifiers_t  modifier (plan.info, plan.topDictModSIDs);
@@ -920,36 +961,23 @@
       return false;
     }
     /* serialize INDEX header for above */
-    CFF1Index *dest = c->start_embed<CFF1Index> ();
-    if (!dest) return false;
-    return dest->serialize_header (c, hb_iter (hb_array_t<unsigned> (&top_size, 1)));
+    auto *dest = c->start_embed<CFF1Index> ();
+    return dest->serialize_header (c, hb_iter (&top_size, 1), top_size);
   }
 }
 
-static bool
-_hb_subset_cff1 (const OT::cff1::accelerator_subset_t  &acc,
-                hb_subset_context_t     *c)
+bool
+OT::cff1::accelerator_subset_t::subset (hb_subset_context_t *c) const
 {
-  cff_subset_plan cff_plan;
+  cff1_subset_plan cff_plan;
 
-  if (unlikely (!cff_plan.create (acc, c->plan)))
+  if (unlikely (!cff_plan.create (*this, c->plan)))
   {
     DEBUG_MSG(SUBSET, nullptr, "Failed to generate a cff subsetting plan.");
     return false;
   }
 
-  return _serialize_cff1 (c->serializer, cff_plan, acc, c->plan->num_output_glyphs ());
-}
-
-bool
-hb_subset_cff1 (hb_subset_context_t *c)
-{
-  OT::cff1::accelerator_subset_t acc;
-  acc.init (c->plan->source);
-  bool result = likely (acc.is_valid ()) && _hb_subset_cff1 (acc, c);
-  acc.fini ();
-
-  return result;
+  return serialize (c->serializer, cff_plan);
 }
 
 
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-cff1.hh b/src/java.desktop/share/native/libharfbuzz/hb-subset-cff1.hh
deleted file mode 100644
index aaf5def..0000000
--- a/src/java.desktop/share/native/libharfbuzz/hb-subset-cff1.hh
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright © 2018 Adobe Inc.
- *
- *  This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Adobe Author(s): Michiharu Ariza
- */
-
-#ifndef HB_SUBSET_CFF1_HH
-#define HB_SUBSET_CFF1_HH
-
-#include "hb.hh"
-
-#include "hb-subset-plan.hh"
-
-HB_INTERNAL bool
-hb_subset_cff1 (hb_subset_context_t *c);
-
-#endif /* HB_SUBSET_CFF1_HH */
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-cff2.cc b/src/java.desktop/share/native/libharfbuzz/hb-subset-cff2.cc
index ae3cf1f..1f9bc20 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-subset-cff2.cc
+++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-cff2.cc
@@ -31,7 +31,6 @@
 #include "hb-open-type.hh"
 #include "hb-ot-cff2-table.hh"
 #include "hb-set.h"
-#include "hb-subset-cff2.hh"
 #include "hb-subset-plan.hh"
 #include "hb-subset-cff-common.hh"
 #include "hb-cff2-interp-cs.hh"
@@ -422,11 +421,17 @@
 };
 
 
+namespace OT {
 struct cff2_subset_plan
 {
   bool create (const OT::cff2::accelerator_subset_t &acc,
               hb_subset_plan_t *plan)
   {
+    /* make sure notdef is first */
+    hb_codepoint_t old_glyph;
+    if (!plan->old_gid_for_new_gid (0, &old_glyph) || (old_glyph != 0)) return false;
+
+    num_glyphs = plan->num_output_glyphs ();
     orig_fdcount = acc.fdArray->count;
 
     drop_hints = plan->flags & HB_SUBSET_FLAGS_NO_HINTING;
@@ -489,6 +494,7 @@
 
   cff2_sub_table_info_t info;
 
+  unsigned int    num_glyphs;
   unsigned int    orig_fdcount = 0;
   unsigned int    subset_fdcount = 1;
   unsigned int    subset_fdselect_size = 0;
@@ -505,18 +511,18 @@
   bool      drop_hints = false;
   bool      desubroutinize = false;
 };
+} // namespace OT
 
-static bool _serialize_cff2 (hb_serialize_context_t *c,
-                             cff2_subset_plan &plan,
-                             const OT::cff2::accelerator_subset_t  &acc,
-                             unsigned int num_glyphs,
-                             hb_array_t<int> normalized_coords)
+bool
+OT::cff2::accelerator_subset_t::serialize (hb_serialize_context_t *c,
+                                           struct cff2_subset_plan &plan,
+                                           hb_array_t<int> normalized_coords) const
 {
   /* private dicts & local subrs */
   hb_vector_t<table_info_t>  private_dict_infos;
   if (unlikely (!private_dict_infos.resize (plan.subset_fdcount))) return false;
 
-  for (int i = (int)acc.privateDicts.length; --i >= 0 ;)
+  for (int i = (int)privateDicts.length; --i >= 0 ;)
   {
     if (plan.fdmap.has (i))
     {
@@ -524,9 +530,7 @@
 
       if (plan.subset_localsubrs[i].length > 0)
       {
-        CFF2Subrs *dest = c->start_embed <CFF2Subrs> ();
-        if (unlikely (!dest)) return false;
-        c->push ();
+        auto *dest = c->push <CFF2Subrs> ();
         if (likely (dest->serialize (c, plan.subset_localsubrs[i])))
           subrs_link = c->pop_pack (false);
         else
@@ -535,12 +539,10 @@
           return false;
         }
       }
-      PrivateDict *pd = c->start_embed<PrivateDict> ();
-      if (unlikely (!pd)) return false;
-      c->push ();
+      auto *pd = c->push<PrivateDict> ();
       cff2_private_dict_op_serializer_t privSzr (plan.desubroutinize, plan.drop_hints, plan.pinned,
-                                                 acc.varStore, normalized_coords);
-      if (likely (pd->serialize (c, acc.privateDicts[i], privSzr, subrs_link)))
+                                                 varStore, normalized_coords);
+      if (likely (pd->serialize (c, privateDicts[i], privSzr, subrs_link)))
       {
         unsigned fd = plan.fdmap[i];
         private_dict_infos[fd].size = c->length ();
@@ -558,14 +560,13 @@
   {
     c->push ();
 
-    unsigned total_size = CFF2CharStrings::total_size (plan.subset_charstrings);
+    unsigned data_size = 0;
+    unsigned total_size = CFF2CharStrings::total_size (plan.subset_charstrings, &data_size);
     if (unlikely (!c->start_zerocopy (total_size)))
        return false;
 
-    CFF2CharStrings  *cs = c->start_embed<CFF2CharStrings> ();
-    if (unlikely (!cs)) return false;
-
-    if (likely (cs->serialize (c, plan.subset_charstrings)))
+    auto *cs = c->start_embed<CFF2CharStrings> ();
+    if (likely (cs->serialize (c, plan.subset_charstrings, &data_size)))
       plan.info.char_strings_link = c->pop_pack (false);
     else
     {
@@ -575,10 +576,10 @@
   }
 
   /* FDSelect */
-  if (acc.fdSelect != &Null (CFF2FDSelect))
+  if (fdSelect != &Null (CFF2FDSelect))
   {
     c->push ();
-    if (likely (hb_serialize_cff_fdselect (c, num_glyphs, *(const FDSelect *)acc.fdSelect,
+    if (likely (hb_serialize_cff_fdselect (c, plan.num_glyphs, *(const FDSelect *)fdSelect,
                                            plan.orig_fdcount,
                                            plan.subset_fdselect_format, plan.subset_fdselect_size,
                                            plan.subset_fdselect_ranges)))
@@ -592,27 +593,32 @@
 
   /* FDArray (FD Index) */
   {
-    c->push ();
-    CFF2FDArray *fda = c->start_embed<CFF2FDArray> ();
-    if (unlikely (!fda)) return false;
+    auto *fda = c->push<CFF2FDArray> ();
     cff_font_dict_op_serializer_t fontSzr;
     auto it =
-    + hb_zip (+ hb_iter (acc.fontDicts)
+    + hb_zip (+ hb_iter (fontDicts)
               | hb_filter ([&] (const cff2_font_dict_values_t &_)
-                { return plan.fdmap.has (&_ - &acc.fontDicts[0]); }),
+                { return plan.fdmap.has (&_ - &fontDicts[0]); }),
               hb_iter (private_dict_infos))
     ;
-    if (unlikely (!fda->serialize (c, it, fontSzr))) return false;
+    if (unlikely (!fda->serialize (c, it, fontSzr)))
+    {
+      c->pop_discard ();
+      return false;
+    }
     plan.info.fd_array_link = c->pop_pack (false);
   }
 
   /* variation store */
-  if (acc.varStore != &Null (CFF2VariationStore) &&
+  if (varStore != &Null (CFF2VariationStore) &&
       !plan.pinned)
   {
-    c->push ();
-    CFF2VariationStore *dest = c->start_embed<CFF2VariationStore> ();
-    if (unlikely (!dest || !dest->serialize (c, acc.varStore))) return false;
+    auto *dest = c->push<CFF2VariationStore> ();
+    if (unlikely (!dest->serialize (c, varStore)))
+    {
+      c->pop_discard ();
+      return false;
+    }
     plan.info.var_store_link = c->pop_pack (false);
   }
 
@@ -628,34 +634,25 @@
   {
     TopDict &dict = cff2 + cff2->topDict;
     cff2_top_dict_op_serializer_t topSzr;
-    if (unlikely (!dict.serialize (c, acc.topDict, topSzr, plan.info))) return false;
+    if (unlikely (!dict.serialize (c, topDict, topSzr, plan.info))) return false;
     cff2->topDictSize = c->head - (const char *)&dict;
   }
 
   /* global subrs */
   {
-    CFF2Subrs *dest = c->start_embed <CFF2Subrs> ();
-    if (unlikely (!dest)) return false;
+    auto *dest = c->start_embed <CFF2Subrs> ();
     return dest->serialize (c, plan.subset_globalsubrs);
   }
 }
 
-static bool
-_hb_subset_cff2 (const OT::cff2::accelerator_subset_t  &acc,
-                 hb_subset_context_t    *c)
+bool
+OT::cff2::accelerator_subset_t::subset (hb_subset_context_t *c) const
 {
   cff2_subset_plan cff2_plan;
 
-  if (unlikely (!cff2_plan.create (acc, c->plan))) return false;
-  return _serialize_cff2 (c->serializer, cff2_plan, acc, c->plan->num_output_glyphs (),
-                          c->plan->normalized_coords.as_array ());
-}
-
-bool
-hb_subset_cff2 (hb_subset_context_t *c)
-{
-  OT::cff2::accelerator_subset_t acc (c->plan->source);
-  return acc.is_valid () && _hb_subset_cff2 (acc, c);
+  if (unlikely (!cff2_plan.create (*this, c->plan))) return false;
+  return serialize (c->serializer, cff2_plan,
+                    c->plan->normalized_coords.as_array ());
 }
 
 #endif
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-cff2.hh b/src/java.desktop/share/native/libharfbuzz/hb-subset-cff2.hh
deleted file mode 100644
index f10556d..0000000
--- a/src/java.desktop/share/native/libharfbuzz/hb-subset-cff2.hh
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright © 2018 Adobe Inc.
- *
- *  This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Adobe Author(s): Michiharu Ariza
- */
-
-#ifndef HB_SUBSET_CFF2_HH
-#define HB_SUBSET_CFF2_HH
-
-#include "hb.hh"
-
-#include "hb-subset-plan.hh"
-
-HB_INTERNAL bool
-hb_subset_cff2 (hb_subset_context_t *c);
-
-#endif /* HB_SUBSET_CFF2_HH */
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-input.cc b/src/java.desktop/share/native/libharfbuzz/hb-subset-input.cc
index 3cdb89a..8c67f7f 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-subset-input.cc
+++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-input.cc
@@ -69,14 +69,11 @@
   sets.drop_tables->add_array (default_drop_tables, ARRAY_LENGTH (default_drop_tables));
 
   hb_tag_t default_no_subset_tables[] = {
-    HB_TAG ('a', 'v', 'a', 'r'),
     HB_TAG ('g', 'a', 's', 'p'),
     HB_TAG ('f', 'p', 'g', 'm'),
     HB_TAG ('p', 'r', 'e', 'p'),
     HB_TAG ('V', 'D', 'M', 'X'),
     HB_TAG ('D', 'S', 'I', 'G'),
-    HB_TAG ('M', 'V', 'A', 'R'),
-    HB_TAG ('c', 'v', 'a', 'r'),
   };
   sets.no_subset_tables->add_array (default_no_subset_tables,
                                          ARRAY_LENGTH (default_no_subset_tables));
@@ -438,7 +435,8 @@
   if (!hb_ot_var_find_axis_info (face, axis_tag, &axis_info))
     return false;
 
-  return input->axes_location.set (axis_tag, axis_info.default_value);
+  float default_val = axis_info.default_value;
+  return input->axes_location.set (axis_tag, Triple (default_val, default_val, default_val));
 }
 
 /**
@@ -468,8 +466,59 @@
     return false;
 
   float val = hb_clamp(axis_value, axis_info.min_value, axis_info.max_value);
-  return input->axes_location.set (axis_tag, val);
+  return input->axes_location.set (axis_tag, Triple (val, val, val));
 }
+
+#ifdef HB_EXPERIMENTAL_API
+/**
+ * hb_subset_input_set_axis_range: (skip)
+ * @input: a #hb_subset_input_t object.
+ * @face: a #hb_face_t object.
+ * @axis_tag: Tag of the axis
+ * @axis_min_value: Minimum value of the axis variation range to set
+ * @axis_max_value: Maximum value of the axis variation range to set
+ * @axis_def_value: Default value of the axis variation range to set, in case of
+ * null, it'll be determined automatically
+ *
+ * Restricting the range of variation on an axis in the given subset input object.
+ * New min/default/max values will be clamped if they're not within the fvar axis range.
+ * If the new default value is null:
+ * If the fvar axis default value is within the new range, then new default
+ * value is the same as original default value.
+ * If the fvar axis default value is not within the new range, the new default
+ * value will be changed to the new min or max value, whichever is closer to the fvar
+ * axis default.
+ *
+ * Note: input min value can not be bigger than input max value. If the input
+ * default value is not within the new min/max range, it'll be clamped.
+ * Note: currently it supports gvar and cvar tables only.
+ *
+ * Return value: `true` if success, `false` otherwise
+ *
+ * XSince: EXPERIMENTAL
+ **/
+HB_EXTERN hb_bool_t
+hb_subset_input_set_axis_range (hb_subset_input_t  *input,
+                                hb_face_t          *face,
+                                hb_tag_t            axis_tag,
+                                float               axis_min_value,
+                                float               axis_max_value,
+                                float              *axis_def_value /* IN, maybe NULL */)
+{
+  if (axis_min_value > axis_max_value)
+    return false;
+
+  hb_ot_var_axis_info_t axis_info;
+  if (!hb_ot_var_find_axis_info (face, axis_tag, &axis_info))
+    return false;
+
+  float new_min_val = hb_clamp(axis_min_value, axis_info.min_value, axis_info.max_value);
+  float new_max_val = hb_clamp(axis_max_value, axis_info.min_value, axis_info.max_value);
+  float new_default_val = axis_def_value ? *axis_def_value : axis_info.default_value;
+  new_default_val = hb_clamp(new_default_val, new_min_val, new_max_val);
+  return input->axes_location.set (axis_tag, Triple (new_min_val, new_default_val, new_max_val));
+}
+#endif
 #endif
 
 /**
@@ -520,6 +569,37 @@
   return new_source;
 }
 
+/**
+ * hb_subset_input_old_to_new_glyph_mapping:
+ * @input: a #hb_subset_input_t object.
+ *
+ * Returns a map which can be used to provide an explicit mapping from old to new glyph
+ * id's in the produced subset. The caller should populate the map as desired.
+ * If this map is left empty then glyph ids will be automatically mapped to new
+ * values by the subsetter. If populated, the mapping must be unique. That
+ * is no two original glyph ids can be mapped to the same new id.
+ * Additionally, if a mapping is provided then the retain gids option cannot
+ * be enabled.
+ *
+ * Any glyphs that are retained in the subset which are not specified
+ * in this mapping will be assigned glyph ids after the highest glyph
+ * id in the mapping.
+ *
+ * Note: this will accept and apply non-monotonic mappings, however this
+ * may result in unsorted Coverage tables. Such fonts may not work for all
+ * use cases (for example ots will reject unsorted coverage tables). So it's
+ * recommended, if possible, to supply a monotonic mapping.
+ *
+ * Return value: (transfer none): pointer to the #hb_map_t of the custom glyphs ID map.
+ *
+ * Since: 7.3.0
+ **/
+HB_EXTERN hb_map_t*
+hb_subset_input_old_to_new_glyph_mapping (hb_subset_input_t *input)
+{
+  return &input->glyph_map;
+}
+
 #ifdef HB_EXPERIMENTAL_API
 /**
  * hb_subset_input_override_name_table:
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-input.hh b/src/java.desktop/share/native/libharfbuzz/hb-subset-input.hh
index 2995322..c026868 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-subset-input.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-input.hh
@@ -35,6 +35,7 @@
 #include "hb-set.hh"
 #include "hb-cplusplus.hh"
 #include "hb-font.hh"
+#include "hb-subset-instancer-solver.hh"
 
 struct hb_ot_name_record_ids_t
 {
@@ -118,7 +119,8 @@
   // If set loca format will always be the long version.
   bool force_long_loca = false;
 
-  hb_hashmap_t<hb_tag_t, float> axes_location;
+  hb_hashmap_t<hb_tag_t, Triple> axes_location;
+  hb_map_t glyph_map;
 #ifdef HB_EXPERIMENTAL_API
   hb_hashmap_t<hb_ot_name_record_ids_t, hb_bytes_t> name_table_overrides;
 #endif
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.cc b/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.cc
new file mode 100644
index 0000000..8ec36e3
--- /dev/null
+++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.cc
@@ -0,0 +1,429 @@
+/*
+ * Copyright © 2023  Behdad Esfahbod
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#include "hb-subset-instancer-solver.hh"
+
+/* This file is a straight port of the following:
+ *
+ * https://github.com/fonttools/fonttools/blob/f73220816264fc383b8a75f2146e8d69e455d398/Lib/fontTools/varLib/instancer/solver.py
+ *
+ * Where that file returns None for a triple, we return Triple{}.
+ * This should be safe.
+ */
+
+constexpr static float EPSILON = 1.f / (1 << 14);
+constexpr static float MAX_F2DOT14 = float (0x7FFF) / (1 << 14);
+
+static inline Triple _reverse_negate(const Triple &v)
+{ return {-v.maximum, -v.middle, -v.minimum}; }
+
+
+static inline float supportScalar (float coord, const Triple &tent)
+{
+  /* Copied from VarRegionAxis::evaluate() */
+  float start = tent.minimum, peak = tent.middle, end = tent.maximum;
+
+  if (unlikely (start > peak || peak > end))
+    return 1.;
+  if (unlikely (start < 0 && end > 0 && peak != 0))
+    return 1.;
+
+  if (peak == 0 || coord == peak)
+    return 1.;
+
+  if (coord <= start || end <= coord)
+    return 0.;
+
+  /* Interpolate */
+  if (coord < peak)
+    return (coord - start) / (peak - start);
+  else
+    return  (end - coord) / (end - peak);
+}
+
+static inline result_t
+_solve (Triple tent, Triple axisLimit, bool negative = false)
+{
+  float axisMin = axisLimit.minimum;
+  float axisDef = axisLimit.middle;
+  float axisMax = axisLimit.maximum;
+  float lower = tent.minimum;
+  float peak  = tent.middle;
+  float upper = tent.maximum;
+
+  // Mirror the problem such that axisDef <= peak
+  if (axisDef > peak)
+  {
+    result_t vec = _solve (_reverse_negate (tent),
+                           _reverse_negate (axisLimit),
+                           !negative);
+
+    for (auto &p : vec)
+      p = hb_pair (p.first, _reverse_negate (p.second));
+
+    return vec;
+  }
+  // axisDef <= peak
+
+  /* case 1: The whole deltaset falls outside the new limit; we can drop it
+   *
+   *                                          peak
+   *  1.........................................o..........
+   *                                           / \
+   *                                          /   \
+   *                                         /     \
+   *                                        /       \
+   *  0---|-----------|----------|-------- o         o----1
+   *    axisMin     axisDef    axisMax   lower     upper
+   */
+  if (axisMax <= lower && axisMax < peak)
+      return result_t{};  // No overlap
+
+  /* case 2: Only the peak and outermost bound fall outside the new limit;
+   * we keep the deltaset, update peak and outermost bound and scale deltas
+   * by the scalar value for the restricted axis at the new limit, and solve
+   * recursively.
+   *
+   *                                  |peak
+   *  1...............................|.o..........
+   *                                  |/ \
+   *                                  /   \
+   *                                 /|    \
+   *                                / |     \
+   *  0--------------------------- o  |      o----1
+   *                           lower  |      upper
+   *                                  |
+   *                                axisMax
+   *
+   * Convert to:
+   *
+   *  1............................................
+   *                                  |
+   *                                  o peak
+   *                                 /|
+   *                                /x|
+   *  0--------------------------- o  o upper ----1
+   *                           lower  |
+   *                                  |
+   *                                axisMax
+   */
+  if (axisMax < peak)
+  {
+    float mult = supportScalar (axisMax, tent);
+    tent = Triple{lower, axisMax, axisMax};
+
+    result_t vec = _solve (tent, axisLimit);
+
+    for (auto &p : vec)
+      p = hb_pair (p.first * mult, p.second);
+
+    return vec;
+  }
+
+  // lower <= axisDef <= peak <= axisMax
+
+  float gain = supportScalar (axisDef, tent);
+  result_t out {hb_pair (gain, Triple{})};
+
+  // First, the positive side
+
+  // outGain is the scalar of axisMax at the tent.
+  float outGain = supportScalar (axisMax, tent);
+
+  /* Case 3a: Gain is more than outGain. The tent down-slope crosses
+   * the axis into negative. We have to split it into multiples.
+   *
+   *                      | peak  |
+   *  1...................|.o.....|..............
+   *                      |/x\_   |
+   *  gain................+....+_.|..............
+   *                     /|    |y\|
+   *  ................../.|....|..+_......outGain
+   *                   /  |    |  | \
+   *  0---|-----------o   |    |  |  o----------1
+   *    axisMin    lower  |    |  |   upper
+   *                      |    |  |
+   *                axisDef    |  axisMax
+   *                           |
+   *                      crossing
+   */
+  if (gain > outGain)
+  {
+    // Crossing point on the axis.
+    float crossing = peak + (1 - gain) * (upper - peak);
+
+    Triple loc{axisDef, peak, crossing};
+    float scalar = 1.f;
+
+    // The part before the crossing point.
+    out.push (hb_pair (scalar - gain, loc));
+
+    /* The part after the crossing point may use one or two tents,
+     * depending on whether upper is before axisMax or not, in one
+     * case we need to keep it down to eternity.
+     *
+     * Case 3a1, similar to case 1neg; just one tent needed, as in
+     * the drawing above.
+     */
+    if (upper >= axisMax)
+    {
+      Triple loc {crossing, axisMax, axisMax};
+      float scalar = outGain;
+
+      out.push (hb_pair (scalar - gain, loc));
+    }
+
+    /* Case 3a2: Similar to case 2neg; two tents needed, to keep
+     * down to eternity.
+     *
+     *                      | peak             |
+     *  1...................|.o................|...
+     *                      |/ \_              |
+     *  gain................+....+_............|...
+     *                     /|    | \xxxxxxxxxxy|
+     *                    / |    |  \_xxxxxyyyy|
+     *                   /  |    |    \xxyyyyyy|
+     *  0---|-----------o   |    |     o-------|--1
+     *    axisMin    lower  |    |      upper  |
+     *                      |    |             |
+     *                axisDef    |             axisMax
+     *                           |
+     *                      crossing
+     */
+    else
+    {
+      // A tent's peak cannot fall on axis default. Nudge it.
+      if (upper == axisDef)
+        upper += EPSILON;
+
+      // Downslope.
+      Triple loc1 {crossing, upper, axisMax};
+      float scalar1 = 0.f;
+
+      // Eternity justify.
+      Triple loc2 {upper, axisMax, axisMax};
+      float scalar2 = 0.f;
+
+      out.push (hb_pair (scalar1 - gain, loc1));
+      out.push (hb_pair (scalar2 - gain, loc2));
+    }
+  }
+
+  else
+  {
+    // Special-case if peak is at axisMax.
+    if (axisMax == peak)
+        upper = peak;
+
+    /* Case 3:
+     * we keep deltas as is and only scale the axis upper to achieve
+     * the desired new tent if feasible.
+     *
+     *                        peak
+     *  1.....................o....................
+     *                       / \_|
+     *  ..................../....+_.........outGain
+     *                     /     | \
+     *  gain..............+......|..+_.............
+     *                   /|      |  | \
+     *  0---|-----------o |      |  |  o----------1
+     *    axisMin    lower|      |  |   upper
+     *                    |      |  newUpper
+     *              axisDef      axisMax
+     */
+    float newUpper = peak + (1 - gain) * (upper - peak);
+    assert (axisMax <= newUpper);  // Because outGain >= gain
+    if (newUpper <= axisDef + (axisMax - axisDef) * 2)
+    {
+      upper = newUpper;
+      if (!negative && axisDef + (axisMax - axisDef) * MAX_F2DOT14 < upper)
+      {
+        // we clamp +2.0 to the max F2Dot14 (~1.99994) for convenience
+        upper = axisDef + (axisMax - axisDef) * MAX_F2DOT14;
+        assert (peak < upper);
+      }
+
+      Triple loc {hb_max (axisDef, lower), peak, upper};
+      float scalar = 1.f;
+
+      out.push (hb_pair (scalar - gain, loc));
+    }
+
+    /* Case 4: New limit doesn't fit; we need to chop into two tents,
+     * because the shape of a triangle with part of one side cut off
+     * cannot be represented as a triangle itself.
+     *
+     *            |   peak |
+     *  1.........|......o.|....................
+     *  ..........|...../x\|.............outGain
+     *            |    |xxy|\_
+     *            |   /xxxy|  \_
+     *            |  |xxxxy|    \_
+     *            |  /xxxxy|      \_
+     *  0---|-----|-oxxxxxx|        o----------1
+     *    axisMin | lower  |        upper
+     *            |        |
+     *          axisDef  axisMax
+     */
+    else
+    {
+      Triple loc1 {hb_max (axisDef, lower), peak, axisMax};
+      float scalar1 = 1.f;
+
+      Triple loc2 {peak, axisMax, axisMax};
+      float scalar2 = outGain;
+
+      out.push (hb_pair (scalar1 - gain, loc1));
+      // Don't add a dirac delta!
+      if (peak < axisMax)
+        out.push (hb_pair (scalar2 - gain, loc2));
+    }
+  }
+
+  /* Now, the negative side
+   *
+   * Case 1neg: Lower extends beyond axisMin: we chop. Simple.
+   *
+   *                     |   |peak
+   *  1..................|...|.o.................
+   *                     |   |/ \
+   *  gain...............|...+...\...............
+   *                     |x_/|    \
+   *                     |/  |     \
+   *                   _/|   |      \
+   *  0---------------o  |   |       o----------1
+   *              lower  |   |       upper
+   *                     |   |
+   *               axisMin   axisDef
+   */
+  if (lower <= axisMin)
+  {
+    Triple loc {axisMin, axisMin, axisDef};
+    float scalar = supportScalar (axisMin, tent);
+
+    out.push (hb_pair (scalar - gain, loc));
+  }
+
+  /* Case 2neg: Lower is betwen axisMin and axisDef: we add two
+   * tents to keep it down all the way to eternity.
+   *
+   *      |               |peak
+   *  1...|...............|.o.................
+   *      |               |/ \
+   *  gain|...............+...\...............
+   *      |yxxxxxxxxxxxxx/|    \
+   *      |yyyyyyxxxxxxx/ |     \
+   *      |yyyyyyyyyyyx/  |      \
+   *  0---|-----------o   |       o----------1
+   *    axisMin    lower  |       upper
+   *                      |
+   *                    axisDef
+   */
+  else
+  {
+    // A tent's peak cannot fall on axis default. Nudge it.
+    if (lower == axisDef)
+      lower -= EPSILON;
+
+    // Downslope.
+    Triple loc1 {axisMin, lower, axisDef};
+    float scalar1 = 0.f;
+
+    // Eternity justify.
+    Triple loc2 {axisMin, axisMin, lower};
+    float scalar2 = 0.f;
+
+    out.push (hb_pair (scalar1 - gain, loc1));
+    out.push (hb_pair (scalar2 - gain, loc2));
+  }
+
+  return out;
+}
+
+static inline TripleDistances _reverse_triple_distances (const TripleDistances &v)
+{ return TripleDistances (v.positive, v.negative); }
+
+float renormalizeValue (float v, const Triple &triple,
+                        const TripleDistances &triple_distances, bool extrapolate)
+{
+  float lower = triple.minimum, def = triple.middle, upper = triple.maximum;
+  assert (lower <= def && def <= upper);
+
+  if (!extrapolate)
+      v = hb_max (hb_min (v, upper), lower);
+
+  if (v == def)
+    return 0.f;
+
+  if (def < 0.f)
+    return -renormalizeValue (-v, _reverse_negate (triple),
+                              _reverse_triple_distances (triple_distances), extrapolate);
+
+  /* default >= 0 and v != default */
+  if (v > def)
+    return (v - def) / (upper - def);
+
+  /* v < def */
+  if (lower >= 0.f)
+    return (v - def) / (def - lower);
+
+  /* lower < 0 and v < default */
+  float total_distance = triple_distances.negative * (-lower) + triple_distances.positive * def;
+
+  float v_distance;
+  if (v >= 0.f)
+    v_distance = (def - v) * triple_distances.positive;
+  else
+    v_distance = (-v) * triple_distances.negative + triple_distances.positive * def;
+
+  return (-v_distance) /total_distance;
+}
+
+result_t
+rebase_tent (Triple tent, Triple axisLimit, TripleDistances axis_triple_distances)
+{
+  assert (-1.f <= axisLimit.minimum && axisLimit.minimum <= axisLimit.middle && axisLimit.middle <= axisLimit.maximum && axisLimit.maximum <= +1.f);
+  assert (-2.f <= tent.minimum && tent.minimum <= tent.middle && tent.middle <= tent.maximum && tent.maximum <= +2.f);
+  assert (tent.middle != 0.f);
+
+  result_t sols = _solve (tent, axisLimit);
+
+  auto n = [&axisLimit, &axis_triple_distances] (float v) { return renormalizeValue (v, axisLimit, axis_triple_distances); };
+
+  result_t out;
+  for (auto &p : sols)
+  {
+    if (!p.first) continue;
+    if (p.second == Triple{})
+    {
+      out.push (p);
+      continue;
+    }
+    Triple t = p.second;
+    out.push (hb_pair (p.first,
+                       Triple{n (t.minimum), n (t.middle), n (t.maximum)}));
+  }
+
+  return out;
+}
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.hh b/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.hh
new file mode 100644
index 0000000..e8ca1dc
--- /dev/null
+++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-instancer-solver.hh
@@ -0,0 +1,112 @@
+/*
+ * Copyright © 2023  Behdad Esfahbod
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#ifndef HB_SUBSET_INSTANCER_SOLVER_HH
+#define HB_SUBSET_INSTANCER_SOLVER_HH
+
+#include "hb.hh"
+
+/* pre-normalized distances */
+struct TripleDistances
+{
+  TripleDistances (): negative (1.f), positive (1.f) {}
+  TripleDistances (float neg_, float pos_): negative (neg_), positive (pos_) {}
+  TripleDistances (float min, float default_, float max)
+  {
+    negative = default_ - min;
+    positive = max - default_;
+  }
+
+  float negative;
+  float positive;
+};
+
+struct Triple {
+
+  Triple () :
+    minimum (0.f), middle (0.f), maximum (0.f) {}
+
+  Triple (float minimum_, float middle_, float maximum_) :
+    minimum (minimum_), middle (middle_), maximum (maximum_) {}
+
+  bool operator == (const Triple &o) const
+  {
+    return minimum == o.minimum &&
+           middle  == o.middle  &&
+           maximum == o.maximum;
+  }
+
+  bool operator != (const Triple o) const
+  { return !(*this == o); }
+
+  bool is_point () const
+  { return minimum == middle && middle == maximum; }
+
+  bool contains (float point) const
+  { return minimum <= point && point <= maximum; }
+
+  /* from hb_array_t hash ()*/
+  uint32_t hash () const
+  {
+    uint32_t current = /*cbf29ce4*/0x84222325;
+    current = current ^ hb_hash (minimum);
+    current = current * 16777619;
+
+    current = current ^ hb_hash (middle);
+    current = current * 16777619;
+
+    current = current ^ hb_hash (maximum);
+    current = current * 16777619;
+    return current;
+  }
+
+
+  float minimum;
+  float middle;
+  float maximum;
+};
+
+using result_item_t = hb_pair_t<float, Triple>;
+using result_t = hb_vector_t<result_item_t>;
+
+/* renormalize a normalized value v to the range of an axis,
+ * considering the prenormalized distances as well as the new axis limits.
+ * Ported from fonttools */
+HB_INTERNAL float renormalizeValue (float v, const Triple &triple,
+                                    const TripleDistances &triple_distances,
+                                    bool extrapolate = true);
+/* Given a tuple (lower,peak,upper) "tent" and new axis limits
+ * (axisMin,axisDefault,axisMax), solves how to represent the tent
+ * under the new axis configuration.  All values are in normalized
+ * -1,0,+1 coordinate system. Tent values can be outside this range.
+ *
+ * Return value: a list of tuples. Each tuple is of the form
+ * (scalar,tent), where scalar is a multipler to multiply any
+ * delta-sets by, and tent is a new tent for that output delta-set.
+ * If tent value is Triple{}, that is a special deltaset that should
+ * be always-enabled (called "gain").
+ */
+HB_INTERNAL result_t rebase_tent (Triple tent, Triple axisLimit, TripleDistances axis_triple_distances);
+
+#endif /* HB_SUBSET_INSTANCER_SOLVER_HH */
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-plan-member-list.hh b/src/java.desktop/share/native/libharfbuzz/hb-subset-plan-member-list.hh
new file mode 100644
index 0000000..8bc1fcb
--- /dev/null
+++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-plan-member-list.hh
@@ -0,0 +1,137 @@
+/*
+ * Copyright © 2018  Google, Inc.
+ * Copyright © 2023  Behdad Esfahbod
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Garret Rieger, Roderick Sheeter
+ */
+
+#ifndef HB_SUBSET_PLAN_MEMBER_LIST_HH
+#define HB_SUBSET_PLAN_MEMBER_LIST_HH
+#endif /* HB_SUBSET_PLAN_MEMBER_LIST_HH */ /* Dummy header guards */
+
+#define E(x, y) x, y
+
+// For each cp that we'd like to retain maps to the corresponding gid.
+HB_SUBSET_PLAN_MEMBER (hb_set_t, unicodes)
+HB_SUBSET_PLAN_MEMBER (hb_sorted_vector_t<hb_codepoint_pair_t>, unicode_to_new_gid_list)
+
+HB_SUBSET_PLAN_MEMBER (hb_sorted_vector_t<hb_codepoint_pair_t>, new_to_old_gid_list)
+
+// name_ids we would like to retain
+HB_SUBSET_PLAN_MEMBER (hb_set_t, name_ids)
+
+// name_languages we would like to retain
+HB_SUBSET_PLAN_MEMBER (hb_set_t, name_languages)
+
+//layout features which will be preserved
+HB_SUBSET_PLAN_MEMBER (hb_set_t, layout_features)
+
+// layout scripts which will be preserved.
+HB_SUBSET_PLAN_MEMBER (hb_set_t, layout_scripts)
+
+//glyph ids requested to retain
+HB_SUBSET_PLAN_MEMBER (hb_set_t, glyphs_requested)
+
+// Tables which should not be processed, just pass them through.
+HB_SUBSET_PLAN_MEMBER (hb_set_t, no_subset_tables)
+
+// Tables which should be dropped.
+HB_SUBSET_PLAN_MEMBER (hb_set_t, drop_tables)
+
+// Old -> New glyph id mapping
+HB_SUBSET_PLAN_MEMBER (hb_map_t, glyph_map_gsub)
+
+HB_SUBSET_PLAN_MEMBER (hb_set_t, _glyphset)
+HB_SUBSET_PLAN_MEMBER (hb_set_t, _glyphset_gsub)
+HB_SUBSET_PLAN_MEMBER (hb_set_t, _glyphset_mathed)
+HB_SUBSET_PLAN_MEMBER (hb_set_t, _glyphset_colred)
+
+//active lookups we'd like to retain
+HB_SUBSET_PLAN_MEMBER (hb_map_t, gsub_lookups)
+HB_SUBSET_PLAN_MEMBER (hb_map_t, gpos_lookups)
+
+//active langsys we'd like to retain
+HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(<unsigned, hb::unique_ptr<hb_set_t>>), gsub_langsys)
+HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(<unsigned, hb::unique_ptr<hb_set_t>>), gpos_langsys)
+
+//active features after removing redundant langsys and prune_features
+HB_SUBSET_PLAN_MEMBER (hb_map_t, gsub_features)
+HB_SUBSET_PLAN_MEMBER (hb_map_t, gpos_features)
+
+//active feature variation records/condition index with variations
+HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(<unsigned, hb::shared_ptr<hb_set_t>>), gsub_feature_record_cond_idx_map)
+HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(<unsigned, hb::shared_ptr<hb_set_t>>), gpos_feature_record_cond_idx_map)
+
+//feature index-> address of substituation feature table mapping with
+//variations
+HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(<unsigned, const OT::Feature*>), gsub_feature_substitutes_map)
+HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(<unsigned, const OT::Feature*>), gpos_feature_substitutes_map)
+
+//active layers/palettes we'd like to retain
+HB_SUBSET_PLAN_MEMBER (hb_map_t, colrv1_layers)
+HB_SUBSET_PLAN_MEMBER (hb_map_t, colr_palettes)
+
+//Old layout item variation index -> (New varidx, delta) mapping
+HB_SUBSET_PLAN_MEMBER (mutable hb_hashmap_t E(<unsigned, hb_pair_t E(<unsigned, int>)>), layout_variation_idx_delta_map)
+
+//gdef varstore retained varidx mapping
+HB_SUBSET_PLAN_MEMBER (hb_vector_t<hb_inc_bimap_t>, gdef_varstore_inner_maps)
+
+HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(<hb_tag_t, hb::unique_ptr<hb_blob_t>>), sanitized_table_cache)
+
+//normalized axes range map
+HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(<hb_tag_t, Triple>), axes_location)
+HB_SUBSET_PLAN_MEMBER (hb_vector_t<int>, normalized_coords)
+
+//user specified axes range map
+HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(<hb_tag_t, Triple>), user_axes_location)
+//axis->TripleDistances map (distances in the pre-normalized space)
+HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(<hb_tag_t, TripleDistances>), axes_triple_distances)
+
+//retained old axis index -> new axis index mapping in fvar axis array
+HB_SUBSET_PLAN_MEMBER (hb_map_t, axes_index_map)
+
+//axis_index->axis_tag mapping in fvar axis array
+HB_SUBSET_PLAN_MEMBER (hb_map_t, axes_old_index_tag_map)
+//vector of retained axis tags in the order of axes given in the 'fvar' table
+HB_SUBSET_PLAN_MEMBER (hb_vector_t<hb_tag_t>, axis_tags)
+
+//hmtx metrics map: new gid->(advance, lsb)
+HB_SUBSET_PLAN_MEMBER (mutable hb_hashmap_t E(<hb_codepoint_t, hb_pair_t E(<unsigned, int>)>), hmtx_map)
+//vmtx metrics map: new gid->(advance, lsb)
+HB_SUBSET_PLAN_MEMBER (mutable hb_hashmap_t E(<hb_codepoint_t, hb_pair_t E(<unsigned, int>)>), vmtx_map)
+//boundsWidth map: new gid->boundsWidth, boundWidth=xMax - xMin
+HB_SUBSET_PLAN_MEMBER (mutable hb_vector_t<unsigned>, bounds_width_vec)
+//boundsHeight map: new gid->boundsHeight, boundsHeight=yMax - yMin
+HB_SUBSET_PLAN_MEMBER (mutable hb_vector_t<unsigned>, bounds_height_vec)
+
+//map: new_gid -> contour points vector
+HB_SUBSET_PLAN_MEMBER (mutable hb_hashmap_t E(<hb_codepoint_t, contour_point_vector_t>), new_gid_contour_points_map)
+
+#ifdef HB_EXPERIMENTAL_API
+// name table overrides map: hb_ot_name_record_ids_t-> name string new value or
+// None to indicate should remove
+HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(<hb_ot_name_record_ids_t, hb_bytes_t>), name_table_overrides)
+#endif
+
+#undef E
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.cc b/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.cc
index be30601..b9cc4fd 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.cc
+++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.cc
@@ -48,10 +48,24 @@
 using OT::Layout::GSUB;
 using OT::Layout::GPOS;
 
+
+hb_subset_accelerator_t::~hb_subset_accelerator_t ()
+{
+  if (cmap_cache && destroy_cmap_cache)
+    destroy_cmap_cache ((void*) cmap_cache);
+
+#ifndef HB_NO_SUBSET_CFF
+  cff1_accel.fini ();
+  cff2_accel.fini ();
+#endif
+  hb_face_destroy (source);
+}
+
+
 typedef hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> script_langsys_map;
 #ifndef HB_NO_SUBSET_CFF
 static inline bool
-_add_cff_seac_components (const OT::cff1::accelerator_t &cff,
+_add_cff_seac_components (const OT::cff1::accelerator_subset_t &cff,
                           hb_codepoint_t gid,
                           hb_set_t *gids_to_retain)
 {
@@ -135,7 +149,8 @@
                                      hb_set_t             *lookup_indices, /* OUT */
                                      hb_set_t             *feature_indices, /* OUT */
                                      hb_hashmap_t<unsigned, hb::shared_ptr<hb_set_t>> *feature_record_cond_idx_map, /* OUT */
-                                     hb_hashmap_t<unsigned, const OT::Feature*> *feature_substitutes_map /* OUT */)
+                                     hb_hashmap_t<unsigned, const OT::Feature*> *feature_substitutes_map, /* OUT */
+                                     bool& insert_catch_all_feature_variation_record)
 {
   unsigned num_features = table.get_feature_count ();
   hb_vector_t<hb_tag_t> features;
@@ -171,8 +186,11 @@
       &plan->axes_location,
       feature_record_cond_idx_map,
       feature_substitutes_map,
+      insert_catch_all_feature_variation_record,
       feature_indices,
-      true,
+      false,
+      false,
+      false,
       0,
       &conditionset_map
     };
@@ -283,7 +301,8 @@
                                   hb_map_t           *features,
                                   script_langsys_map *langsys_map,
                                   hb_hashmap_t<unsigned, hb::shared_ptr<hb_set_t>> *feature_record_cond_idx_map,
-                                  hb_hashmap_t<unsigned, const OT::Feature*> *feature_substitutes_map)
+                                  hb_hashmap_t<unsigned, const OT::Feature*> *feature_substitutes_map,
+                                  bool& insert_catch_all_feature_variation_record)
 {
   hb_blob_ptr_t<T> table = plan->source_table<T> ();
   hb_tag_t table_tag = table->tableTag;
@@ -293,7 +312,8 @@
                               &lookup_indices,
                               &feature_indices,
                               feature_record_cond_idx_map,
-                              feature_substitutes_map);
+                              feature_substitutes_map,
+                              insert_catch_all_feature_variation_record);
 
   if (table_tag == HB_OT_TAG_GSUB && !(plan->flags & HB_SUBSET_FLAGS_NO_LAYOUT_CLOSURE))
     hb_ot_layout_lookups_substitute_closure (plan->source,
@@ -329,7 +349,7 @@
 {
   if (varidx_set.is_empty () || subtable_count == 0) return;
 
-  inner_maps.resize (subtable_count);
+  if (unlikely (!inner_maps.resize (subtable_count))) return;
   for (unsigned idx : varidx_set)
   {
     uint16_t major = idx >> 16;
@@ -356,7 +376,7 @@
   {
     hb_variation_t var;
     var.tag = _.first;
-    var.value = _.second;
+    var.value = _.second.middle;
     vars.push (var);
   }
 
@@ -379,42 +399,20 @@
     return;
   }
 
-  const OT::VariationStore *var_store = nullptr;
   hb_set_t varidx_set;
-  hb_font_t *font = nullptr;
-  float *store_cache = nullptr;
-  bool collect_delta = plan->pinned_at_default ? false : true;
-  if (collect_delta)
-  {
-    if (unlikely (!plan->check_success (font = _get_hb_font_with_variations (plan)))) {
-      hb_font_destroy (font);
-      gdef.destroy ();
-      gpos.destroy ();
-      return;
-    }
-
-    if (gdef->has_var_store ())
-    {
-      var_store = &(gdef->get_var_store ());
-      store_cache = var_store->create_cache ();
-    }
-  }
-
   OT::hb_collect_variation_indices_context_t c (&varidx_set,
-                                                &plan->layout_variation_idx_delta_map,
-                                                font, var_store,
                                                 &plan->_glyphset_gsub,
-                                                &plan->gpos_lookups,
-                                                store_cache);
+                                                &plan->gpos_lookups);
   gdef->collect_variation_indices (&c);
 
   if (hb_ot_layout_has_positioning (plan->source))
     gpos->collect_variation_indices (&c);
 
-  hb_font_destroy (font);
-  var_store->destroy_cache (store_cache);
-
-  gdef->remap_layout_variation_indices (&varidx_set, &plan->layout_variation_idx_delta_map);
+  gdef->remap_layout_variation_indices (&varidx_set,
+                                        plan->normalized_coords,
+                                        !plan->pinned_at_default,
+                                        plan->all_axes_pinned,
+                                        &plan->layout_variation_idx_delta_map);
 
   unsigned subtable_count = gdef->has_var_store () ? gdef->get_var_store ().get_sub_table_count () : 0;
   _generate_varstore_inner_maps (varidx_set, subtable_count, plan->gdef_varstore_inner_maps);
@@ -549,6 +547,8 @@
         unicodes->get_population () < cmap_unicodes->get_population () &&
         glyphs->get_population () < cmap_unicodes->get_population ())
     {
+      plan->codepoint_to_glyph->alloc (unicodes->get_population () + glyphs->get_population ());
+
       auto &gid_to_unicodes = plan->accelerator->gid_to_unicodes;
       for (hb_codepoint_t gid : *glyphs)
       {
@@ -577,6 +577,7 @@
     }
     else
     {
+      plan->codepoint_to_glyph->alloc (cmap_unicodes->get_population ());
       for (hb_codepoint_t cp : *cmap_unicodes)
       {
         hb_codepoint_t gid = (*unicode_glyphid_map)[cp];
@@ -589,11 +590,15 @@
     }
 
     /* Add gids which where requested, but not mapped in cmap */
-    for (hb_codepoint_t gid : *glyphs)
+    unsigned num_glyphs = plan->source->get_num_glyphs ();
+    hb_codepoint_t first = HB_SET_VALUE_INVALID, last = HB_SET_VALUE_INVALID;
+    for (; glyphs->next_range (&first, &last); )
     {
-      if (gid >= plan->source->get_num_glyphs ())
+      if (first >= num_glyphs)
         break;
-      plan->_glyphset_gsub.add (gid);
+      if (last >= num_glyphs)
+        last = num_glyphs - 1;
+      plan->_glyphset_gsub.add_range (first, last);
     }
   }
 
@@ -616,14 +621,17 @@
                             int operation_count,
                             unsigned depth = 0)
 {
-  if (unlikely (depth++ > HB_MAX_NESTING_LEVEL)) return operation_count;
-  if (unlikely (--operation_count < 0)) return operation_count;
   /* Check if is already visited */
   if (gids_to_retain->has (gid)) return operation_count;
 
   gids_to_retain->add (gid);
 
-  for (auto &item : glyf.glyph_for_gid (gid).get_composite_iterator ())
+  if (unlikely (depth++ > HB_MAX_NESTING_LEVEL)) return operation_count;
+  if (unlikely (--operation_count < 0)) return operation_count;
+
+  auto glyph = glyf.glyph_for_gid (gid);
+
+  for (auto &item : glyph.get_composite_iterator ())
     operation_count =
       _glyf_add_gid_and_children (glyf,
                                   item.get_gid (),
@@ -632,7 +640,7 @@
                                   depth);
 
 #ifndef HB_NO_VAR_COMPOSITES
-  for (auto &item : glyf.glyph_for_gid (gid).get_var_composite_iterator ())
+  for (auto &item : glyph.get_var_composite_iterator ())
    {
     operation_count =
       _glyf_add_gid_and_children (glyf,
@@ -655,7 +663,7 @@
 #endif
 #ifndef HB_NO_VAR
   if (!plan->all_axes_pinned)
-    plan->source->table.fvar->collect_name_ids (&plan->user_axes_location, &plan->name_ids);
+    plan->source->table.fvar->collect_name_ids (&plan->user_axes_location, &plan->axes_old_index_tag_map, &plan->name_ids);
 #endif
 #ifndef HB_NO_COLOR
   if (!drop_tables->has (HB_OT_TAG_CPAL))
@@ -684,7 +692,11 @@
 {
   OT::glyf_accelerator_t glyf (plan->source);
 #ifndef HB_NO_SUBSET_CFF
-  OT::cff1::accelerator_t cff (plan->source);
+  // Note: we cannot use inprogress_accelerator here, since it has not been
+  // created yet. So in case of preprocessed-face (and otherwise), we do an
+  // extra sanitize pass here, which is not ideal.
+  OT::cff1::accelerator_subset_t stack_cff (plan->accelerator ? nullptr : plan->source);
+  const OT::cff1::accelerator_subset_t *cff (plan->accelerator ? plan->accelerator->cff1_accel.get () : &stack_cff);
 #endif
 
   plan->_glyphset_gsub.add (0); // Not-def
@@ -701,7 +713,8 @@
         &plan->gsub_features,
         &plan->gsub_langsys,
         &plan->gsub_feature_record_cond_idx_map,
-        &plan->gsub_feature_substitutes_map);
+        &plan->gsub_feature_substitutes_map,
+        plan->gsub_insert_catch_all_feature_variation_rec);
 
   if (!drop_tables->has (HB_OT_TAG_GPOS))
     _closure_glyphs_lookups_features<GPOS> (
@@ -711,7 +724,8 @@
         &plan->gpos_features,
         &plan->gpos_langsys,
         &plan->gpos_feature_record_cond_idx_map,
-        &plan->gpos_feature_substitutes_map);
+        &plan->gpos_feature_substitutes_map,
+        plan->gpos_insert_catch_all_feature_variation_rec);
 #endif
   _remove_invalid_gids (&plan->_glyphset_gsub, plan->source->get_num_glyphs ());
 
@@ -744,9 +758,9 @@
   if (!plan->accelerator || plan->accelerator->has_seac)
   {
     bool has_seac = false;
-    if (cff.is_valid ())
+    if (cff->is_valid ())
       for (hb_codepoint_t gid : cur_glyphset)
-        if (_add_cff_seac_components (cff, gid, &plan->_glyphset))
+        if (_add_cff_seac_components (*cff, gid, &plan->_glyphset))
           has_seac = true;
     plan->has_seac = has_seac;
   }
@@ -754,7 +768,6 @@
 
   _remove_invalid_gids (&plan->_glyphset, plan->source->get_num_glyphs ());
 
-
 #ifndef HB_NO_VAR
   if (!drop_tables->has (HB_OT_TAG_GDEF))
     _collect_layout_variation_indices (plan);
@@ -766,41 +779,90 @@
                         const hb_map_t* glyph_map,
                         hb_map_t* out)
 {
+  out->alloc (glyph_set_gsub->get_population ());
   + hb_iter (glyph_set_gsub)
   | hb_map ([&] (hb_codepoint_t gid) {
-    return hb_pair_t<hb_codepoint_t, hb_codepoint_t> (gid,
-                                                      glyph_map->get (gid));
+    return hb_codepoint_pair_t (gid, glyph_map->get (gid));
   })
   | hb_sink (out)
   ;
 }
 
-static void
+static bool
 _create_old_gid_to_new_gid_map (const hb_face_t *face,
                                 bool             retain_gids,
                                 const hb_set_t  *all_gids_to_retain,
+                                const hb_map_t  *requested_glyph_map,
                                 hb_map_t        *glyph_map, /* OUT */
                                 hb_map_t        *reverse_glyph_map, /* OUT */
+                                hb_sorted_vector_t<hb_codepoint_pair_t> *new_to_old_gid_list /* OUT */,
                                 unsigned int    *num_glyphs /* OUT */)
 {
   unsigned pop = all_gids_to_retain->get_population ();
-  reverse_glyph_map->resize (pop);
-  glyph_map->resize (pop);
+  reverse_glyph_map->alloc (pop);
+  glyph_map->alloc (pop);
+  new_to_old_gid_list->alloc (pop);
 
-  if (!retain_gids)
+  if (*requested_glyph_map)
+  {
+    hb_set_t new_gids(requested_glyph_map->values());
+    if (new_gids.get_population() != requested_glyph_map->get_population())
+    {
+      DEBUG_MSG (SUBSET, nullptr, "The provided custom glyph mapping is not unique.");
+      return false;
+    }
+
+    if (retain_gids)
+    {
+      DEBUG_MSG (SUBSET, nullptr,
+        "HB_SUBSET_FLAGS_RETAIN_GIDS cannot be set if "
+        "a custom glyph mapping has been provided.");
+      return false;
+    }
+
+    hb_codepoint_t max_glyph = 0;
+    hb_set_t remaining;
+    for (auto old_gid : all_gids_to_retain->iter ())
+    {
+      if (old_gid == 0) {
+        new_to_old_gid_list->push (hb_pair<hb_codepoint_t, hb_codepoint_t> (0u, 0u));
+        continue;
+      }
+
+      hb_codepoint_t* new_gid;
+      if (!requested_glyph_map->has (old_gid, &new_gid))
+      {
+        remaining.add(old_gid);
+        continue;
+      }
+
+      if (*new_gid > max_glyph)
+        max_glyph = *new_gid;
+      new_to_old_gid_list->push (hb_pair (*new_gid, old_gid));
+    }
+    new_to_old_gid_list->qsort ();
+
+    // Anything that wasn't mapped by the requested mapping should
+    // be placed after the requested mapping.
+    for (auto old_gid : remaining)
+      new_to_old_gid_list->push (hb_pair (++max_glyph, old_gid));
+
+    *num_glyphs = max_glyph + 1;
+  }
+  else if (!retain_gids)
   {
     + hb_enumerate (hb_iter (all_gids_to_retain), (hb_codepoint_t) 0)
-    | hb_sink (reverse_glyph_map)
+    | hb_sink (new_to_old_gid_list)
     ;
-    *num_glyphs = reverse_glyph_map->get_population ();
+    *num_glyphs = new_to_old_gid_list->length;
   }
   else
   {
     + hb_iter (all_gids_to_retain)
     | hb_map ([] (hb_codepoint_t _) {
-                return hb_pair_t<hb_codepoint_t, hb_codepoint_t> (_, _);
+                return hb_codepoint_pair_t (_, _);
               })
-    | hb_sink (reverse_glyph_map)
+    | hb_sink (new_to_old_gid_list)
     ;
 
     hb_codepoint_t max_glyph = HB_SET_VALUE_INVALID;
@@ -809,10 +871,15 @@
     *num_glyphs = max_glyph + 1;
   }
 
-  + reverse_glyph_map->iter ()
-  | hb_map (&hb_pair_t<hb_codepoint_t, hb_codepoint_t>::reverse)
+  + hb_iter (new_to_old_gid_list)
+  | hb_sink (reverse_glyph_map)
+  ;
+  + hb_iter (new_to_old_gid_list)
+  | hb_map (&hb_codepoint_pair_t::reverse)
   | hb_sink (glyph_map)
   ;
+
+  return true;
 }
 
 #ifndef HB_NO_VAR
@@ -841,24 +908,38 @@
     hb_tag_t axis_tag = axis.get_axis_tag ();
     plan->axes_old_index_tag_map.set (old_axis_idx, axis_tag);
 
-    if (!plan->user_axes_location.has (axis_tag))
+    if (!plan->user_axes_location.has (axis_tag) ||
+        !plan->user_axes_location.get (axis_tag).is_point ())
     {
       axis_not_pinned = true;
       plan->axes_index_map.set (old_axis_idx, new_axis_idx);
+      plan->axis_tags.push (axis_tag);
       new_axis_idx++;
     }
-    else
+
+    Triple *axis_range;
+    if (plan->user_axes_location.has (axis_tag, &axis_range))
     {
-      int normalized_v = axis.normalize_axis_value (plan->user_axes_location.get (axis_tag));
+      plan->axes_triple_distances.set (axis_tag, axis.get_triple_distances ());
+
+      int normalized_min = axis.normalize_axis_value (axis_range->minimum);
+      int normalized_default = axis.normalize_axis_value (axis_range->middle);
+      int normalized_max = axis.normalize_axis_value (axis_range->maximum);
+
       if (has_avar && old_axis_idx < avar_axis_count)
       {
-        normalized_v = seg_maps->map (normalized_v);
+        normalized_min = seg_maps->map (normalized_min);
+        normalized_default = seg_maps->map (normalized_default);
+        normalized_max = seg_maps->map (normalized_max);
       }
-      plan->axes_location.set (axis_tag, normalized_v);
-      if (normalized_v != 0)
+      plan->axes_location.set (axis_tag, Triple (static_cast<float> (normalized_min / 16384.f),
+                                                 static_cast<float> (normalized_default / 16384.f),
+                                                 static_cast<float> (normalized_max / 16384.f)));
+
+      if (normalized_default != 0)
         plan->pinned_at_default = false;
 
-      plan->normalized_coords[old_axis_idx] = normalized_v;
+      plan->normalized_coords[old_axis_idx] = normalized_default;
     }
 
     old_axis_idx++;
@@ -925,7 +1006,7 @@
           continue;
       }
       plan->hmtx_map.set (new_gid, hb_pair ((unsigned) hori_aw, lsb));
-      plan->bounds_width_map.set (new_gid, extents.width);
+      plan->bounds_width_vec[new_gid] = extents.width;
     }
 
     if (_vmtx.has_data ())
@@ -942,7 +1023,7 @@
           continue;
       }
       plan->vmtx_map.set (new_gid, hb_pair ((unsigned) vert_aw, tsb));
-      plan->bounds_height_map.set (new_gid, extents.height);
+      plan->bounds_height_vec[new_gid] = extents.height;
     }
   }
   hb_font_destroy (font);
@@ -951,6 +1032,36 @@
   if (vvar_store_cache)
     _vmtx.var_table->get_var_store ().destroy_cache (vvar_store_cache);
 }
+
+static bool
+_get_instance_glyphs_contour_points (hb_subset_plan_t *plan)
+{
+  /* contour_points vector only needed for updating gvar table (infer delta)
+   * during partial instancing */
+  if (plan->user_axes_location.is_empty () || plan->all_axes_pinned)
+    return true;
+
+  OT::glyf_accelerator_t glyf (plan->source);
+
+  for (auto &_ : plan->new_to_old_gid_list)
+  {
+    hb_codepoint_t new_gid = _.first;
+    contour_point_vector_t all_points;
+    if (new_gid == 0 && !(plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE))
+    {
+      if (unlikely (!plan->new_gid_contour_points_map.set (new_gid, all_points)))
+        return false;
+      continue;
+    }
+
+    hb_codepoint_t old_gid = _.second;
+    if (unlikely (!glyf.glyph_for_gid (old_gid).get_all_points_without_var (plan->source, all_points)))
+      return false;
+    if (unlikely (!plan->new_gid_contour_points_map.set (new_gid, all_points)))
+      return false;
+  }
+  return true;
+}
 #endif
 
 hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face,
@@ -975,6 +1086,8 @@
   glyph_map = hb_map_create ();
   reverse_glyph_map = hb_map_create ();
 
+  gsub_insert_catch_all_feature_variation_rec = false;
+  gpos_insert_catch_all_feature_variation_rec = false;
   gdef_varstore_inner_maps.init ();
 
   user_axes_location = input->axes_location;
@@ -1002,7 +1115,6 @@
   if (accel)
     accelerator = (hb_subset_accelerator_t*) accel;
 
-
   if (unlikely (in_error ()))
     return;
 
@@ -1016,12 +1128,17 @@
   if (unlikely (in_error ()))
     return;
 
-  _create_old_gid_to_new_gid_map (face,
-                                  input->flags & HB_SUBSET_FLAGS_RETAIN_GIDS,
-                                  &_glyphset,
-                                  glyph_map,
-                                  reverse_glyph_map,
-                                  &_num_output_glyphs);
+  if (!check_success(_create_old_gid_to_new_gid_map(
+          face,
+          input->flags & HB_SUBSET_FLAGS_RETAIN_GIDS,
+          &_glyphset,
+          &input->glyph_map,
+          glyph_map,
+          reverse_glyph_map,
+          &new_to_old_gid_list,
+          &_num_output_glyphs))) {
+    return;
+  }
 
   _create_glyph_map_gsub (
       &_glyphset_gsub,
@@ -1036,33 +1153,61 @@
         glyph_map->get(unicode_to_new_gid_list.arrayZ[i].second);
   }
 
+  bounds_width_vec.resize (_num_output_glyphs, false);
+  for (auto &v : bounds_width_vec)
+    v = 0xFFFFFFFF;
+  bounds_height_vec.resize (_num_output_glyphs, false);
+  for (auto &v : bounds_height_vec)
+    v = 0xFFFFFFFF;
+
   if (unlikely (in_error ()))
     return;
 
 #ifndef HB_NO_VAR
   _update_instance_metrics_map_from_cff2 (this);
+  if (!check_success (_get_instance_glyphs_contour_points (this)))
+      return;
 #endif
 
   if (attach_accelerator_data)
   {
-    hb_multimap_t gid_to_unicodes;
-
-    hb_map_t &unicode_to_gid = *codepoint_to_glyph;
-
-    for (auto unicode : unicodes)
-    {
-      auto gid = unicode_to_gid[unicode];
-      gid_to_unicodes.add (gid, unicode);
-    }
-
     inprogress_accelerator =
-      hb_subset_accelerator_t::create (*codepoint_to_glyph,
-                                       gid_to_unicodes,
+      hb_subset_accelerator_t::create (source,
+                                       *codepoint_to_glyph,
                                        unicodes,
                                        has_seac);
+
+    check_success (inprogress_accelerator);
   }
+
+#define HB_SUBSET_PLAN_MEMBER(Type, Name) check_success (!Name.in_error ());
+#include "hb-subset-plan-member-list.hh"
+#undef HB_SUBSET_PLAN_MEMBER
 }
 
+hb_subset_plan_t::~hb_subset_plan_t()
+{
+  hb_face_destroy (dest);
+
+  hb_map_destroy (codepoint_to_glyph);
+  hb_map_destroy (glyph_map);
+  hb_map_destroy (reverse_glyph_map);
+#ifndef HB_NO_SUBSET_CFF
+  cff1_accel.fini ();
+  cff2_accel.fini ();
+#endif
+  hb_face_destroy (source);
+
+#ifdef HB_EXPERIMENTAL_API
+  for (auto _ : name_table_overrides.iter_ref ())
+    _.second.fini ();
+#endif
+
+  if (inprogress_accelerator)
+    hb_subset_accelerator_t::destroy ((void*) inprogress_accelerator);
+}
+
+
 /**
  * hb_subset_plan_create_or_fail:
  * @face: font face to create the plan for.
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.hh b/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.hh
index 8f2ac23..40a6ff1 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-subset-plan.hh
@@ -67,28 +67,51 @@
 
 typedef struct head_maxp_info_t head_maxp_info_t;
 
+struct contour_point_t
+{
+  void init (float x_ = 0.f, float y_ = 0.f, bool is_end_point_ = false)
+  { flag = 0; x = x_; y = y_; is_end_point = is_end_point_; }
+
+  void transform (const float (&matrix)[4])
+  {
+    float x_ = x * matrix[0] + y * matrix[2];
+          y  = x * matrix[1] + y * matrix[3];
+    x  = x_;
+  }
+  HB_ALWAYS_INLINE
+  void translate (const contour_point_t &p) { x += p.x; y += p.y; }
+
+
+  float x;
+  float y;
+  uint8_t flag;
+  bool is_end_point;
+};
+
+struct contour_point_vector_t : hb_vector_t<contour_point_t>
+{
+  void extend (const hb_array_t<contour_point_t> &a)
+  {
+    unsigned int old_len = length;
+    if (unlikely (!resize (old_len + a.length, false)))
+      return;
+    auto arrayZ = this->arrayZ + old_len;
+    unsigned count = a.length;
+    hb_memcpy (arrayZ, a.arrayZ, count * sizeof (arrayZ[0]));
+  }
+};
+
+namespace OT {
+  struct cff1_subset_accelerator_t;
+  struct cff2_subset_accelerator_t;
+}
+
 struct hb_subset_plan_t
 {
   HB_INTERNAL hb_subset_plan_t (hb_face_t *,
                                 const hb_subset_input_t *input);
 
-  ~hb_subset_plan_t()
-  {
-    hb_face_destroy (source);
-    hb_face_destroy (dest);
-
-    hb_map_destroy (codepoint_to_glyph);
-    hb_map_destroy (glyph_map);
-    hb_map_destroy (reverse_glyph_map);
-
-#ifdef HB_EXPERIMENTAL_API
-    for (auto _ : name_table_overrides)
-      _.second.fini ();
-#endif
-
-    if (inprogress_accelerator)
-      hb_subset_accelerator_t::destroy ((void*) inprogress_accelerator);
-  }
+  HB_INTERNAL ~hb_subset_plan_t();
 
   hb_object_header_t header;
 
@@ -97,137 +120,71 @@
   bool attach_accelerator_data = false;
   bool force_long_loca = false;
 
-  // For each cp that we'd like to retain maps to the corresponding gid.
-  hb_set_t unicodes;
-  hb_sorted_vector_t<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> unicode_to_new_gid_list;
-
-  // name_ids we would like to retain
-  hb_set_t name_ids;
-
-  // name_languages we would like to retain
-  hb_set_t name_languages;
-
-  //layout features which will be preserved
-  hb_set_t layout_features;
-
-  // layout scripts which will be preserved.
-  hb_set_t layout_scripts;
-
-  //glyph ids requested to retain
-  hb_set_t glyphs_requested;
-
-  // Tables which should not be processed, just pass them through.
-  hb_set_t no_subset_tables;
-
-  // Tables which should be dropped.
-  hb_set_t drop_tables;
-
   // The glyph subset
   hb_map_t *codepoint_to_glyph; // Needs to be heap-allocated
 
   // Old -> New glyph id mapping
   hb_map_t *glyph_map; // Needs to be heap-allocated
   hb_map_t *reverse_glyph_map; // Needs to be heap-allocated
-  hb_map_t glyph_map_gsub;
 
   // Plan is only good for a specific source/dest so keep them with it
   hb_face_t *source;
+#ifndef HB_NO_SUBSET_CFF
+  // These have to be immediately after source:
+  hb_face_lazy_loader_t<OT::cff1_subset_accelerator_t, 1> cff1_accel;
+  hb_face_lazy_loader_t<OT::cff2_subset_accelerator_t, 2> cff2_accel;
+#endif
+
   hb_face_t *dest;
 
   unsigned int _num_output_glyphs;
-  hb_set_t _glyphset;
-  hb_set_t _glyphset_gsub;
-  hb_set_t _glyphset_mathed;
-  hb_set_t _glyphset_colred;
 
-  //active lookups we'd like to retain
-  hb_map_t gsub_lookups;
-  hb_map_t gpos_lookups;
-
-  //active langsys we'd like to retain
-  hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> gsub_langsys;
-  hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> gpos_langsys;
-
-  //active features after removing redundant langsys and prune_features
-  hb_map_t gsub_features;
-  hb_map_t gpos_features;
-
-  //active feature variation records/condition index with variations
-  hb_hashmap_t<unsigned, hb::shared_ptr<hb_set_t>> gsub_feature_record_cond_idx_map;
-  hb_hashmap_t<unsigned, hb::shared_ptr<hb_set_t>> gpos_feature_record_cond_idx_map;
-
-  //feature index-> address of substituation feature table mapping with
-  //variations
-  hb_hashmap_t<unsigned, const OT::Feature*> gsub_feature_substitutes_map;
-  hb_hashmap_t<unsigned, const OT::Feature*> gpos_feature_substitutes_map;
-
-  //active layers/palettes we'd like to retain
-  hb_map_t colrv1_layers;
-  hb_map_t colr_palettes;
-
-  //Old layout item variation index -> (New varidx, delta) mapping
-  hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> layout_variation_idx_delta_map;
-
-  //gdef varstore retained varidx mapping
-  hb_vector_t<hb_inc_bimap_t> gdef_varstore_inner_maps;
-
-  hb_hashmap_t<hb_tag_t, hb::unique_ptr<hb_blob_t>> sanitized_table_cache;
-  //normalized axes location map
-  hb_hashmap_t<hb_tag_t, int> axes_location;
-  hb_vector_t<int> normalized_coords;
-  //user specified axes location map
-  hb_hashmap_t<hb_tag_t, float> user_axes_location;
-  //retained old axis index -> new axis index mapping in fvar axis array
-  hb_map_t axes_index_map;
-  //axis_index->axis_tag mapping in fvar axis array
-  hb_map_t axes_old_index_tag_map;
   bool all_axes_pinned;
   bool pinned_at_default;
   bool has_seac;
 
-  //hmtx metrics map: new gid->(advance, lsb)
-  mutable hb_hashmap_t<hb_codepoint_t, hb_pair_t<unsigned, int>> hmtx_map;
-  //vmtx metrics map: new gid->(advance, lsb)
-  mutable hb_hashmap_t<hb_codepoint_t, hb_pair_t<unsigned, int>> vmtx_map;
-  //boundsWidth map: new gid->boundsWidth, boundWidth=xMax - xMin
-  mutable hb_map_t bounds_width_map;
-  //boundsHeight map: new gid->boundsHeight, boundsHeight=yMax - yMin
-  mutable hb_map_t bounds_height_map;
+  // whether to insert a catch-all FeatureVariationRecord
+  bool gsub_insert_catch_all_feature_variation_rec;
+  bool gpos_insert_catch_all_feature_variation_rec;
+
+#define HB_SUBSET_PLAN_MEMBER(Type, Name) Type Name;
+#include "hb-subset-plan-member-list.hh"
+#undef HB_SUBSET_PLAN_MEMBER
 
   //recalculated head/maxp table info after instancing
   mutable head_maxp_info_t head_maxp_info;
 
-#ifdef HB_EXPERIMENTAL_API
-  // name table overrides map: hb_ot_name_record_ids_t-> name string new value or
-  // None to indicate should remove
-  hb_hashmap_t<hb_ot_name_record_ids_t, hb_bytes_t> name_table_overrides;
-#endif
-
   const hb_subset_accelerator_t* accelerator;
   hb_subset_accelerator_t* inprogress_accelerator;
 
  public:
 
   template<typename T>
-  hb_blob_ptr_t<T> source_table()
+  struct source_table_loader
   {
-    hb_lock_t lock (accelerator ? &accelerator->sanitized_table_cache_lock : nullptr);
+    hb_blob_ptr_t<T> operator () (hb_subset_plan_t *plan)
+    {
+      hb_lock_t lock (plan->accelerator ? &plan->accelerator->sanitized_table_cache_lock : nullptr);
 
-    auto *cache = accelerator ? &accelerator->sanitized_table_cache : &sanitized_table_cache;
-    if (cache
-        && !cache->in_error ()
-        && cache->has (+T::tableTag)) {
-      return hb_blob_reference (cache->get (+T::tableTag).get ());
+      auto *cache = plan->accelerator ? &plan->accelerator->sanitized_table_cache : &plan->sanitized_table_cache;
+      if (cache
+          && !cache->in_error ()
+          && cache->has (+T::tableTag)) {
+        return hb_blob_reference (cache->get (+T::tableTag).get ());
+      }
+
+      hb::unique_ptr<hb_blob_t> table_blob {hb_sanitize_context_t ().reference_table<T> (plan->source)};
+      hb_blob_t* ret = hb_blob_reference (table_blob.get ());
+
+      if (likely (cache))
+        cache->set (+T::tableTag, std::move (table_blob));
+
+      return ret;
     }
+  };
 
-    hb::unique_ptr<hb_blob_t> table_blob {hb_sanitize_context_t ().reference_table<T> (source)};
-    hb_blob_t* ret = hb_blob_reference (table_blob.get ());
-
-    if (likely (cache))
-      cache->set (+T::tableTag, std::move (table_blob));
-
-    return ret;
-  }
+  template<typename T>
+  auto source_table() HB_AUTO_RETURN (source_table_loader<T> {} (this))
 
   bool in_error () const { return !successful; }
 
@@ -266,15 +223,6 @@
     return _num_output_glyphs;
   }
 
-  /*
-   * Given an output gid , returns true if that glyph id is an empty
-   * glyph (ie. it's a gid that we are dropping all data for).
-   */
-  inline bool is_empty_glyph (hb_codepoint_t gid) const
-  {
-    return !_glyphset.has (gid);
-  }
-
   inline bool new_gid_for_codepoint (hb_codepoint_t codepoint,
                                      hb_codepoint_t *new_gid) const
   {
@@ -324,4 +272,5 @@
   }
 };
 
+
 #endif /* HB_SUBSET_PLAN_HH */
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset.cc b/src/java.desktop/share/native/libharfbuzz/hb-subset.cc
index 538f4ec..c125a43 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-subset.cc
+++ b/src/java.desktop/share/native/libharfbuzz/hb-subset.cc
@@ -43,21 +43,19 @@
 #include "OT/Color/sbix/sbix.hh"
 #include "hb-ot-os2-table.hh"
 #include "hb-ot-post-table.hh"
-
-#if !defined(AIX)
 #include "hb-ot-post-table-v2subset.hh"
-#endif
-
 #include "hb-ot-cff1-table.hh"
 #include "hb-ot-cff2-table.hh"
 #include "hb-ot-vorg-table.hh"
 #include "hb-ot-name-table.hh"
 #include "hb-ot-layout-gsub-table.hh"
 #include "hb-ot-layout-gpos-table.hh"
+#include "hb-ot-var-avar-table.hh"
 #include "hb-ot-var-cvar-table.hh"
 #include "hb-ot-var-fvar-table.hh"
 #include "hb-ot-var-gvar-table.hh"
 #include "hb-ot-var-hvar-table.hh"
+#include "hb-ot-var-mvar-table.hh"
 #include "hb-ot-math-table.hh"
 #include "hb-ot-stat-table.hh"
 #include "hb-repacker.hh"
@@ -66,6 +64,27 @@
 using OT::Layout::GSUB;
 using OT::Layout::GPOS;
 
+
+#ifndef HB_NO_SUBSET_CFF
+template<>
+struct hb_subset_plan_t::source_table_loader<const OT::cff1>
+{
+  auto operator () (hb_subset_plan_t *plan)
+  HB_AUTO_RETURN (plan->accelerator ? plan->accelerator->cff1_accel :
+                  plan->inprogress_accelerator ? plan->inprogress_accelerator->cff1_accel :
+                  plan->cff1_accel)
+};
+template<>
+struct hb_subset_plan_t::source_table_loader<const OT::cff2>
+{
+  auto operator () (hb_subset_plan_t *plan)
+  HB_AUTO_RETURN (plan->accelerator ? plan->accelerator->cff2_accel :
+                  plan->inprogress_accelerator ? plan->inprogress_accelerator->cff2_accel :
+                  plan->cff2_accel)
+};
+#endif
+
+
 /**
  * SECTION:hb-subset
  * @title: hb-subset
@@ -100,8 +119,8 @@
   HB_OT_TAG_BASE,
   HB_OT_TAG_CBDT,
   HB_OT_TAG_CBLC,
-  HB_OT_TAG_cff1,
-  HB_OT_TAG_cff2,
+  HB_OT_TAG_CFF1,
+  HB_OT_TAG_CFF2,
   HB_OT_TAG_cmap,
   HB_OT_TAG_COLR,
   HB_OT_TAG_CPAL,
@@ -196,15 +215,36 @@
 static unsigned
 _plan_estimate_subset_table_size (hb_subset_plan_t *plan,
                                   unsigned table_len,
-                                  bool same_size)
+                                  hb_tag_t table_tag)
 {
   unsigned src_glyphs = plan->source->get_num_glyphs ();
   unsigned dst_glyphs = plan->glyphset ()->get_population ();
 
-  if (unlikely (!src_glyphs) || same_size)
-    return 512 + table_len;
+  unsigned bulk = 8192;
+  /* Tables that we want to allocate same space as the source table. For GSUB/GPOS it's
+   * because those are expensive to subset, so giving them more room is fine. */
+  bool same_size = table_tag == HB_OT_TAG_GSUB ||
+                   table_tag == HB_OT_TAG_GPOS ||
+                   table_tag == HB_OT_TAG_name;
 
-  return 512 + (unsigned) (table_len * sqrt ((double) dst_glyphs / src_glyphs));
+  if (plan->flags & HB_SUBSET_FLAGS_RETAIN_GIDS)
+  {
+    if (table_tag == HB_OT_TAG_CFF1)
+    {
+      /* Add some extra room for the CFF charset. */
+      bulk += src_glyphs * 16;
+    }
+    else if (table_tag == HB_OT_TAG_CFF2)
+    {
+      /* Just extra CharString offsets. */
+      bulk += src_glyphs * 4;
+    }
+  }
+
+  if (unlikely (!src_glyphs) || same_size)
+    return bulk + table_len;
+
+  return bulk + (unsigned) (table_len * sqrt ((double) dst_glyphs / src_glyphs));
 }
 
 /*
@@ -235,7 +275,7 @@
              hb_vector_t<char>* buf,
              hb_subset_context_t* c /* OUT */)
 {
-  c->serializer->start_serialize<TableType> ();
+  c->serializer->start_serialize ();
   if (c->serializer->in_error ()) return false;
 
   bool needed = table->subset (c);
@@ -266,45 +306,46 @@
   return _try_subset (table, buf, c);
 }
 
+template <typename T>
+static auto _do_destroy (T &t, hb_priority<1>) HB_RETURN (void, t.destroy ())
+
+template <typename T>
+static void _do_destroy (T &t, hb_priority<0>) {}
+
 template<typename TableType>
 static bool
 _subset (hb_subset_plan_t *plan, hb_vector_t<char> &buf)
 {
-  hb_blob_ptr_t<TableType> source_blob = plan->source_table<TableType> ();
-  const TableType *table = source_blob.get ();
+  auto &&source_blob = plan->source_table<TableType> ();
+  auto *table = source_blob.get ();
 
   hb_tag_t tag = TableType::tableTag;
-  if (!source_blob.get_blob()->data)
+  hb_blob_t *blob = source_blob.get_blob();
+  if (unlikely (!blob || !blob->data))
   {
     DEBUG_MSG (SUBSET, nullptr,
                "OT::%c%c%c%c::subset sanitize failed on source table.", HB_UNTAG (tag));
-    source_blob.destroy ();
+    _do_destroy (source_blob, hb_prioritize);
     return false;
   }
 
-  /* Tables that we want to allocate same space as the source table. For GSUB/GPOS it's
-   * because those are expensive to subset, so giving them more room is fine. */
-  bool same_size_table = TableType::tableTag == HB_OT_TAG_GSUB ||
-                         TableType::tableTag == HB_OT_TAG_GPOS ||
-                         TableType::tableTag == HB_OT_TAG_name;
-
-  unsigned buf_size = _plan_estimate_subset_table_size (plan, source_blob.get_length (), same_size_table);
+  unsigned buf_size = _plan_estimate_subset_table_size (plan, blob->length, TableType::tableTag);
   DEBUG_MSG (SUBSET, nullptr,
              "OT::%c%c%c%c initial estimated table size: %u bytes.", HB_UNTAG (tag), buf_size);
   if (unlikely (!buf.alloc (buf_size)))
   {
     DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c failed to allocate %u bytes.", HB_UNTAG (tag), buf_size);
-    source_blob.destroy ();
+    _do_destroy (source_blob, hb_prioritize);
     return false;
   }
 
   bool needed = false;
   hb_serialize_context_t serializer (buf.arrayZ, buf.allocated);
   {
-    hb_subset_context_t c (source_blob.get_blob (), plan, &serializer, tag);
+    hb_subset_context_t c (blob, plan, &serializer, tag);
     needed = _try_subset (table, &buf, &c);
   }
-  source_blob.destroy ();
+  _do_destroy (source_blob, hb_prioritize);
 
   if (serializer.in_error () && !serializer.only_offset_overflow ())
   {
@@ -420,6 +461,8 @@
   case HB_OT_TAG_vmtx:
   case HB_OT_TAG_maxp:
     return !plan->normalized_coords || !pending_subset_tags.has (HB_OT_TAG_glyf);
+  case HB_OT_TAG_GPOS:
+    return !plan->normalized_coords || plan->all_axes_pinned || !pending_subset_tags.has (HB_OT_TAG_GDEF);
   default:
     return true;
   }
@@ -461,8 +504,8 @@
   case HB_OT_TAG_MATH: return _subset<const OT::MATH> (plan, buf);
 
 #ifndef HB_NO_SUBSET_CFF
-  case HB_OT_TAG_cff1: return _subset<const OT::cff1> (plan, buf);
-  case HB_OT_TAG_cff2: return _subset<const OT::cff2> (plan, buf);
+  case HB_OT_TAG_CFF1: return _subset<const OT::cff1> (plan, buf);
+  case HB_OT_TAG_CFF2: return _subset<const OT::cff2> (plan, buf);
   case HB_OT_TAG_VORG: return _subset<const OT::VORG> (plan, buf);
 #endif
 
@@ -474,13 +517,24 @@
   case HB_OT_TAG_HVAR: return _subset<const OT::HVAR> (plan, buf);
   case HB_OT_TAG_VVAR: return _subset<const OT::VVAR> (plan, buf);
 #endif
+
+#ifndef HB_NO_VAR
   case HB_OT_TAG_fvar:
     if (plan->user_axes_location.is_empty ()) return _passthrough (plan, tag);
     return _subset<const OT::fvar> (plan, buf);
+  case HB_OT_TAG_avar:
+    if (plan->user_axes_location.is_empty ()) return _passthrough (plan, tag);
+    return _subset<const OT::avar> (plan, buf);
+  case HB_OT_TAG_cvar:
+    if (plan->user_axes_location.is_empty ()) return _passthrough (plan, tag);
+    return _subset<const OT::cvar> (plan, buf);
+  case HB_OT_TAG_MVAR:
+    if (plan->user_axes_location.is_empty ()) return _passthrough (plan, tag);
+    return _subset<const OT::MVAR> (plan, buf);
+#endif
+
   case HB_OT_TAG_STAT:
-    /*TODO(qxliu): change the condition as we support more complex
-     * instancing operation*/
-    if (plan->all_axes_pinned) return _subset<const OT::STAT> (plan, buf);
+    if (!plan->user_axes_location.is_empty ()) return _subset<const OT::STAT> (plan, buf);
     else return _passthrough (plan, tag);
 
   case HB_TAG ('c', 'v', 't', ' '):
@@ -591,46 +645,49 @@
     offset += num_tables;
   }
 
-  hb_vector_t<char> buf;
-  buf.alloc (4096 - 16);
-
-
   bool success = true;
 
-  while (!pending_subset_tags.is_empty ())
   {
-    if (subsetted_tags.in_error ()
-        || pending_subset_tags.in_error ()) {
-      success = false;
-      goto end;
-    }
+    // Grouping to deallocate buf before calling hb_face_reference (plan->dest).
 
-    bool made_changes = false;
-    for (hb_tag_t tag : pending_subset_tags)
+    hb_vector_t<char> buf;
+    buf.alloc (8192 - 16);
+
+    while (!pending_subset_tags.is_empty ())
     {
-      if (!_dependencies_satisfied (plan, tag,
-                                    subsetted_tags,
-                                    pending_subset_tags))
-      {
-        // delayed subsetting for some tables since they might have dependency on other tables
-        // in some cases: e.g: during instantiating glyf tables, hmetrics/vmetrics are updated
-        // and saved in subset plan, hmtx/vmtx subsetting need to use these updated metrics values
-        continue;
+      if (subsetted_tags.in_error ()
+          || pending_subset_tags.in_error ()) {
+        success = false;
+        goto end;
       }
 
-      pending_subset_tags.del (tag);
-      subsetted_tags.add (tag);
-      made_changes = true;
+      bool made_changes = false;
+      for (hb_tag_t tag : pending_subset_tags)
+      {
+        if (!_dependencies_satisfied (plan, tag,
+                                      subsetted_tags,
+                                      pending_subset_tags))
+        {
+          // delayed subsetting for some tables since they might have dependency on other tables
+          // in some cases: e.g: during instantiating glyf tables, hmetrics/vmetrics are updated
+          // and saved in subset plan, hmtx/vmtx subsetting need to use these updated metrics values
+          continue;
+        }
 
-      success = _subset_table (plan, buf, tag);
-      if (unlikely (!success)) goto end;
-    }
+        pending_subset_tags.del (tag);
+        subsetted_tags.add (tag);
+        made_changes = true;
 
-    if (!made_changes)
-    {
-      DEBUG_MSG (SUBSET, nullptr, "Table dependencies unable to be satisfied. Subset failed.");
-      success = false;
-      goto end;
+        success = _subset_table (plan, buf, tag);
+        if (unlikely (!success)) goto end;
+      }
+
+      if (!made_changes)
+      {
+        DEBUG_MSG (SUBSET, nullptr, "Table dependencies unable to be satisfied. Subset failed.");
+        success = false;
+        goto end;
+      }
     }
   }
 
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-subset.h b/src/java.desktop/share/native/libharfbuzz/hb-subset.h
index 410fd90..8ea24da 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-subset.h
+++ b/src/java.desktop/share/native/libharfbuzz/hb-subset.h
@@ -154,6 +154,9 @@
 HB_EXTERN hb_set_t *
 hb_subset_input_set (hb_subset_input_t *input, hb_subset_sets_t set_type);
 
+HB_EXTERN hb_map_t*
+hb_subset_input_old_to_new_glyph_mapping (hb_subset_input_t *input);
+
 HB_EXTERN hb_subset_flags_t
 hb_subset_input_get_flags (hb_subset_input_t *input);
 
@@ -174,6 +177,14 @@
 
 #ifdef HB_EXPERIMENTAL_API
 HB_EXTERN hb_bool_t
+hb_subset_input_set_axis_range (hb_subset_input_t  *input,
+                                hb_face_t          *face,
+                                hb_tag_t            axis_tag,
+                                float               axis_min_value,
+                                float               axis_max_value,
+                                float              *axis_def_value);
+
+HB_EXTERN hb_bool_t
 hb_subset_input_override_name_table (hb_subset_input_t  *input,
                                      hb_ot_name_id_t     name_id,
                                      unsigned            platform_id,
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-ucd-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-ucd-table.hh
index f7d76ee..8d3807a 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-ucd-table.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-ucd-table.hh
@@ -4,7 +4,7 @@
  *
  *   ./gen-ucd-table.py ucd.nounihan.grouped.xml
  *
- * on file with this description: Unicode 15.0.0
+ * on file with this description: Unicode 15.1.0
  */
 
 #ifndef HB_UCD_TABLE_HH
@@ -1069,7 +1069,7 @@
 #ifndef HB_OPTIMIZE_SIZE
 
 static const uint8_t
-_hb_ucd_u8[17868] =
+_hb_ucd_u8[17884] =
 {
     0,  1,  2,  3,  4,  5,  6,  7,  7,  8,  7,  7,  7,  7,  7,  7,
     7,  7,  7,  7,  9, 10,  7,  7,  7,  7, 11, 12, 13, 13, 13, 14,
@@ -1146,13 +1146,13 @@
    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,243, 34,
   244, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,245, 34, 34,
-   34, 34, 34, 34, 34, 34, 34,246,122,122,122,122,122,122,122,122,
-   34, 34, 34, 34,247,122,122,122,122,122,122,122,122,122,122,122,
-   34, 34, 34, 34, 34, 34,248, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-   34, 34, 34, 34, 34, 34, 34,249,122,122,122,122,122,122,122,122,
-  250,122,251,252,122,122,122,122,122,122,122,122,122,122,122,122,
-  107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,253,
+   34, 34, 34, 34, 34, 34, 34,246, 34, 34, 34, 34,247,122,122,122,
+   34, 34, 34, 34,248,122,122,122,122,122,122,122,122,122,122,122,
+   34, 34, 34, 34, 34, 34,249, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+   34, 34, 34, 34, 34, 34, 34,250,122,122,122,122,122,122,122,122,
+  251,122,252,253,122,122,122,122,122,122,122,122,122,122,122,122,
   107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,254,
+  107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,255,
     0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  3,  2,  4,  5,  6,  2,
     7,  7,  7,  7,  7,  2,  8,  9, 10, 11, 11, 11, 11, 11, 11, 11,
    11, 11, 11, 11, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16,
@@ -1315,11 +1315,11 @@
   121,  4,  4,  4,  4,  2,  2, 88,  2,  2,  2,  2,  2,120,  2,  2,
   108,151,  2,  2,  2,  2,  2,  2, 67,  2,152,148,148,148,153, 44,
    67, 67, 67, 67, 67, 55, 67, 67, 67, 67, 44, 44, 44, 44, 44, 44,
-   67, 67, 67, 44, 44, 44, 44, 44, 67, 67, 67, 67, 67, 67, 44, 44,
-    1,  2,154,155,  4,  4,  4,  4,  4, 67,  4,  4,  4,  4,156,157,
-  158,105,105,105,105, 43, 43, 86,159, 40, 40, 67,105,160, 63, 67,
-   36, 36, 36, 61, 57,161,162, 69, 36, 36, 36, 36, 36, 63, 40, 69,
-   44, 44, 62, 36, 36, 36, 36, 36, 67, 27, 27, 67, 67, 67, 67, 67,
+   67, 67, 67, 44, 44, 44, 44, 44,  1,  2,154,155,  4,  4,  4,  4,
+    4, 67,  4,  4,  4,  4,156,157,158,105,105,105,105, 43, 43, 86,
+  159, 40, 40, 67,105,160, 63, 67, 36, 36, 36, 61, 57,161,162, 69,
+   36, 36, 36, 36, 36, 63, 40, 69, 44, 44, 62, 36, 36, 36, 36, 36,
+   67, 27, 27, 67, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44, 44, 55,
    67, 67, 67, 67, 67, 67, 67, 92, 27, 27, 27, 27, 27, 67, 67, 67,
    67, 67, 67, 67, 27, 27, 27, 27,163, 27, 27, 27, 27, 27, 27, 27,
    36, 36, 83, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,164,  2,
@@ -1487,214 +1487,215 @@
    44, 61, 44, 62, 62, 62, 62, 36, 62, 61, 61, 62, 62, 62, 62, 62,
    62, 61, 61, 62, 36, 61, 36, 36, 36, 61, 36, 36, 62, 36, 61, 61,
    36, 36, 36, 36, 36, 62, 36, 36, 62, 36, 62, 36, 36, 62, 36, 36,
-    8, 44, 44, 44, 44, 44, 44, 44, 55, 67, 67, 67, 67, 67, 67, 67,
-   27, 27, 27, 27, 27, 27, 91, 67, 67, 67, 67, 67, 67, 67, 67, 44,
-   44, 44, 44, 67, 67, 67, 67, 67, 67, 92, 44, 44, 44, 44, 44, 44,
-   67, 67, 67, 67, 92, 44, 44, 44, 67, 44, 44, 44, 44, 44, 44, 44,
-   67, 67, 67, 67, 67, 25, 41, 41, 67, 67, 67, 67, 44, 44, 67, 67,
-   67, 67, 67, 92, 44, 55, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44,
-   67, 67, 67, 67, 67, 67, 67, 55, 67, 67, 67, 44, 44, 44, 44, 67,
-   67, 92, 67, 67, 67, 67, 67, 67, 79, 44, 44, 44, 44, 44, 44, 44,
-  171,171,171,171,171,171,171, 44,171,171,171,171,171,171,171,  0,
-    0,  0, 29, 21, 21, 21, 23, 21, 22, 18, 21, 25, 21, 17, 13, 13,
-   25, 25, 25, 21, 21,  9,  9,  9,  9, 22, 21, 18, 24, 16, 24,  5,
-    5,  5,  5, 22, 25, 18, 25,  0, 23, 23, 26, 21, 24, 26,  7, 20,
-   25,  1, 26, 24, 26, 25, 15, 15, 24, 15,  7, 19, 15, 21,  9, 25,
-    9,  5,  5, 25,  5,  9,  5,  7,  7,  7,  9,  8,  8,  5,  7,  5,
-    6,  6, 24, 24,  6, 24, 12, 12,  2,  2,  6,  5,  9, 21,  9,  2,
-    2,  9, 25,  9, 26, 12, 11, 11,  2,  6,  5, 21, 17,  2,  2, 26,
-   26, 23,  2, 12, 17, 12, 21, 12, 12, 21,  7,  2,  2,  7,  7, 21,
-   21,  2,  1,  1, 21, 23, 26, 26,  1, 21,  6,  7,  7, 12, 12,  7,
-   21,  7, 12,  1, 12,  6,  6, 12, 12, 26,  7, 26, 26,  7,  2,  1,
-   12,  2,  6,  2, 24,  7,  7,  6,  1, 12, 12, 10, 10, 10, 10, 12,
-   21,  6,  2, 10, 10,  2, 15, 26, 26,  2,  2, 21,  7, 10, 15,  7,
-    2, 23, 21, 26, 10,  7, 21, 15, 15,  2, 17,  7, 29,  7,  7, 22,
-   18,  2, 14, 14, 14,  7, 10, 21, 17, 21, 11, 12,  5,  2,  5,  6,
-    8,  8,  8, 24,  5, 24,  2, 24,  9, 24, 24,  2, 29, 29, 29,  1,
-   17, 17, 20, 19, 22, 20, 27, 28,  1, 29, 21, 20, 19, 21, 21, 16,
-   16, 21, 25, 22, 18, 21, 21, 29,  1,  2, 15,  6, 18,  6, 23,  2,
-   12, 11,  9, 26, 26,  9, 26,  5,  5, 26, 14,  9,  5, 14, 14, 15,
-   25, 26, 26, 22, 18, 26, 18, 25, 18, 22,  5, 12,  2,  5, 22, 21,
-   21, 22, 18, 17, 26,  6,  7, 14, 17, 22, 18, 18, 26, 14, 17,  6,
-   14,  6, 12, 24, 24,  6, 26, 15,  6, 21, 11, 21, 24,  9,  6,  9,
-   23, 26,  6, 10,  4,  4,  3,  3,  7, 25, 17, 16, 16, 22, 16, 16,
-   25, 17, 25,  2, 25, 24,  2, 15, 12, 15, 14,  2, 21, 14,  7, 15,
-   12, 17, 21,  1, 26, 10, 10,  1, 23, 15,  0,  1,  2,  3,  4,  5,
-    6,  7,  8,  9,  0, 10, 11, 12, 13,  0, 14,  0,  0,  0,  0,  0,
-   15,  0, 16,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    8, 44, 44, 44, 44, 44, 44, 44, 67, 67, 67, 67, 67, 67, 44, 44,
+   55, 67, 67, 67, 67, 67, 67, 67, 27, 27, 27, 27, 27, 27, 91, 67,
+   67, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44, 67, 67, 67, 67, 67,
+   67, 92, 44, 44, 44, 44, 44, 44, 67, 67, 67, 67, 92, 44, 44, 44,
+   67, 44, 44, 44, 44, 44, 44, 44, 67, 67, 67, 67, 67, 25, 41, 41,
+   67, 67, 67, 67, 44, 44, 67, 67, 67, 67, 67, 92, 44, 55, 67, 67,
+   67, 67, 67, 67, 44, 44, 44, 44, 67, 67, 67, 67, 67, 67, 67, 55,
+   67, 67, 67, 44, 44, 44, 44, 67, 67, 92, 67, 67, 67, 67, 67, 67,
+   79, 44, 44, 44, 44, 44, 44, 44,171,171,171,171,171,171,171, 44,
+  171,171,171,171,171,171,171,  0,  0,  0, 29, 21, 21, 21, 23, 21,
+   22, 18, 21, 25, 21, 17, 13, 13, 25, 25, 25, 21, 21,  9,  9,  9,
+    9, 22, 21, 18, 24, 16, 24,  5,  5,  5,  5, 22, 25, 18, 25,  0,
+   23, 23, 26, 21, 24, 26,  7, 20, 25,  1, 26, 24, 26, 25, 15, 15,
+   24, 15,  7, 19, 15, 21,  9, 25,  9,  5,  5, 25,  5,  9,  5,  7,
+    7,  7,  9,  8,  8,  5,  7,  5,  6,  6, 24, 24,  6, 24, 12, 12,
+    2,  2,  6,  5,  9, 21,  9,  2,  2,  9, 25,  9, 26, 12, 11, 11,
+    2,  6,  5, 21, 17,  2,  2, 26, 26, 23,  2, 12, 17, 12, 21, 12,
+   12, 21,  7,  2,  2,  7,  7, 21, 21,  2,  1,  1, 21, 23, 26, 26,
+    1, 21,  6,  7,  7, 12, 12,  7, 21,  7, 12,  1, 12,  6,  6, 12,
+   12, 26,  7, 26, 26,  7,  2,  1, 12,  2,  6,  2, 24,  7,  7,  6,
+    1, 12, 12, 10, 10, 10, 10, 12, 21,  6,  2, 10, 10,  2, 15, 26,
+   26,  2,  2, 21,  7, 10, 15,  7,  2, 23, 21, 26, 10,  7, 21, 15,
+   15,  2, 17,  7, 29,  7,  7, 22, 18,  2, 14, 14, 14,  7, 10, 21,
+   17, 21, 11, 12,  5,  2,  5,  6,  8,  8,  8, 24,  5, 24,  2, 24,
+    9, 24, 24,  2, 29, 29, 29,  1, 17, 17, 20, 19, 22, 20, 27, 28,
+    1, 29, 21, 20, 19, 21, 21, 16, 16, 21, 25, 22, 18, 21, 21, 29,
+    1,  2, 15,  6, 18,  6, 23,  2, 12, 11,  9, 26, 26,  9, 26,  5,
+    5, 26, 14,  9,  5, 14, 14, 15, 25, 26, 26, 22, 18, 26, 18, 25,
+   18, 22,  5, 12,  2,  5, 22, 21, 21, 22, 18, 17, 26,  6,  7, 14,
+   17, 22, 18, 18, 26, 14, 17,  6, 14,  6, 12, 24, 24,  6, 26, 15,
+    6, 21, 11, 21, 24,  9,  6,  9, 23, 26,  6, 10,  4,  4,  3,  3,
+    7, 25, 17, 16, 16, 22, 16, 16, 25, 17, 25,  2, 25, 24,  2, 15,
+   12, 15, 14,  2, 21, 14,  7, 15, 12, 17, 21,  1, 26, 10, 10,  1,
+   23, 15,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  0, 10, 11, 12,
+   13,  0, 14,  0,  0,  0,  0,  0, 15,  0, 16,  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, 17, 18, 19,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0, 17, 18, 19,  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, 20,
+    0, 21, 22, 23,  0,  0,  0, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+   33, 34,  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, 35,  0, 36,  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, 20,  0, 21, 22, 23,  0,  0,  0, 24,
-   25, 26, 27, 28, 29, 30, 31, 32, 33, 34,  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, 35,
-    0, 36,  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, 37,  0,  0,  0,  0,  0,  0,  0,
-    0,  0, 38, 39,  0,  0,  0,  0,  0,  0, 40, 41, 42,  0, 43,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  0,  0,
-    0,  0,  3,  0,  0,  0,  4,  5,  6,  7,  0,  8,  9, 10,  0, 11,
-   12, 13, 14, 15, 16, 17, 16, 18, 16, 19, 16, 19, 16, 19,  0, 19,
-   16, 20, 16, 19, 21, 19,  0, 22, 23, 24, 25, 26, 27, 28, 29, 30,
-   31,  0, 32,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 33,  0,  0,
-    0,  0,  0,  0, 34,  0,  0, 35,  0,  0, 36,  0, 37,  0,  0,  0,
-   38, 39, 40, 41, 42, 43, 44, 45, 46,  0,  0, 47,  0,  0,  0, 48,
-    0,  0,  0, 49,  0,  0,  0,  0,  0,  0,  0, 50,  0, 51,  0, 52,
-   53,  0, 54,  0,  0,  0,  0,  0,  0, 55, 56, 57,  0,  0,  0,  0,
-   58,  0,  0, 59, 60, 61, 62, 63,  0,  0, 64, 65,  0,  0,  0, 66,
-    0,  0,  0,  0, 67,  0,  0,  0, 68,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0, 69,  0,  0,  0, 70,  0, 71,  0,  0,
-   72,  0,  0, 73,  0,  0,  0,  0,  0,  0,  0,  0, 74,  0,  0,  0,
-    0,  0, 75, 76,  0, 77, 78,  0,  0, 79, 80,  0, 81, 62,  0, 82,
-   83,  0,  0, 84, 85, 86,  0,  0,  0, 87,  0, 88,  0,  0, 51, 89,
-   51,  0, 90,  0, 91,  0,  0,  0, 80,  0,  0,  0, 92, 93,  0, 94,
-   95, 96, 97,  0,  0,  0,  0,  0, 51,  0,  0,  0,  0, 98, 99,  0,
-    0,  0,  0,  0,  0,100,  0,  0,  0,  0,  0,101,102,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,103,  0,  0,104,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,105,106,  0,  0,107,  0,  0,  0,  0,  0,  0,
-  108,  0,109,  0,102,  0,  0,  0,  0,  0,110,111,  0,  0,  0,  0,
-    0,  0,  0,112,  0,  0,  0,  0,  0,  0,  0,113,  0,114,  0,  0,
-    0,  0,  0,  0,  1,  2,  3,  4,  5,  6,  7,  0,  8,  0,  0,  0,
-    0,  9, 10, 11, 12,  0,  0,  0,  0, 13,  0,  0, 14, 15,  0, 16,
-    0, 17, 18,  0,  0, 19,  0, 20, 21,  0,  0,  0,  0,  0, 22, 23,
-    0, 24, 25,  0,  0, 26,  0,  0,  0, 27,  0,  0, 28, 29, 30, 31,
-    0,  0,  0, 32, 33, 34,  0,  0, 33,  0,  0, 35, 33,  0,  0,  0,
-   33, 36,  0,  0,  0,  0,  0, 37, 38,  0,  0,  0,  0,  0,  0, 39,
-   40,  0,  0,  0,  0,  0,  0, 41, 42,  0,  0,  0,  0, 43,  0, 44,
-    0,  0,  0, 45, 46,  0,  0,  0, 47,  0,  0,  0,  0,  0,  0, 48,
-   49,  0,  0,  0,  0, 50,  0,  0,  0, 51,  0, 52,  0, 53,  0,  0,
-    0,  0, 54,  0,  0,  0,  0, 55,  0, 56,  0,  0,  0,  0, 57, 58,
-    0,  0,  0, 59, 60,  0,  0,  0,  0,  0,  0, 61, 52,  0, 62, 63,
-    0,  0, 64,  0,  0,  0, 65, 66,  0,  0,  0, 67,  0, 68, 69, 70,
-   71, 72,  1, 73,  0, 74, 75, 76,  0,  0, 77, 78,  0,  0,  0, 79,
-    0,  0,  1,  1,  0,  0, 80,  0,  0, 81,  0,  0,  0,  0, 77, 82,
-    0, 83,  0,  0,  0,  0,  0, 78, 84,  0, 85,  0, 52,  0,  1, 78,
-    0,  0, 86,  0,  0, 87,  0,  0,  0,  0,  0, 88, 57,  0,  0,  0,
-    0,  0,  0, 89, 90,  0,  0, 84,  0,  0, 33,  0,  0, 91,  0,  0,
-    0,  0, 92,  0,  0,  0,  0, 49,  0,  0, 93,  0,  0,  0,  0, 94,
-   95,  0,  0, 96,  0,  0, 97,  0,  0,  0, 98,  0,  0,  0, 99,  0,
-    0,  0,  0,100,101, 93,  0,  0,102,  0,  0,  0, 84,  0,  0,103,
-    0,  0,  0,104,105,  0,  0,106,107,  0,  0,  0,  0,  0,  0,108,
-    0,  0,109,  0,  0,  0,  0,110, 33,  0,111,112,113, 35,  0,  0,
-  114,  0,  0,  0,115,  0,  0,  0,  0,  0,  0,116,  0,  0,117,  0,
-    0,  0,  0,118, 88,  0,  0,  0,  0,  0, 57,  0,  0,  0,  0, 52,
-  119,  0,  0,  0,  0,120,  0,  0,121,  0,  0,  0,  0,119,  0,  0,
-  122,  0,  0,  0,  0,  0,  0,123,  0,  0,  0,124,  0,  0,  0,125,
-    0,126,  0,  0,  0,  0,127,128,129,  0,130,  0,131,  0,  0,  0,
-  132,133,134,  0, 77,  0,  0,  0,  0,  0, 35,  0,  0,  0,135,  0,
-    0,  0,136,  0,  0,137,  0,  0,138,  0,  0,  0,  0,  0,  0,  0,
-    1,  1,  1,  1,  1,  2,  3,  4,  5,  6,  7,  4,  4,  8,  9, 10,
-    1, 11, 12, 13, 14, 15, 16, 17, 18,  1,  1,  1, 19,  1,  0,  0,
-   20, 21, 22,  1, 23,  4, 21, 24, 25, 26, 27, 28, 29, 30,  0,  0,
-    1,  1, 31,  0,  0,  0, 32, 33, 34, 35,  1, 36, 37,  0,  0,  0,
-    0, 38,  1, 39, 14, 39, 40, 41, 42,  0,  0,  0, 43, 36, 44, 45,
-   21, 45, 46,  0,  0,  0, 19,  1, 21,  0,  0, 47,  0, 38, 48,  1,
-    1, 49, 49, 50,  0,  0, 51,  0,  0,  0, 52,  1,  0,  0, 38, 14,
-    4,  1,  1,  1, 53, 21, 43, 52, 54, 21, 35,  1,  0,  0,  0, 55,
-    0,  0,  0, 56, 57, 58,  0,  0,  0,  0,  0, 59,  0, 60,  0,  0,
-    0,  0, 61, 62,  0,  0, 63,  0,  0,  0, 64,  0,  0,  0, 65,  0,
-    0,  0, 66,  0,  0,  0, 67,  0,  0,  0, 68,  0,  0, 69, 70,  0,
-   71, 72, 73, 74, 75, 76,  0,  0,  0, 77,  0,  0,  0, 78, 79,  0,
-    0,  0,  0, 47,  0,  0,  0, 49,  0, 80,  0,  0,  0, 62,  0,  0,
-   63,  0,  0, 81,  0,  0, 82,  0,  0,  0, 83,  0,  0, 19, 84,  0,
-   62,  0,  0,  0,  0, 49,  1, 85,  1, 52, 15, 86, 36, 10, 21, 87,
-    0, 55,  0,  0,  0,  0, 19, 10,  1,  0,  0,  0,  0,  0, 88,  0,
-    0, 89,  0,  0, 88,  0,  0,  0,  0, 78,  0,  0, 87,  9, 12,  4,
-   90,  8, 91, 47,  0, 58, 50,  0, 21,  1, 21, 92, 93,  1,  1,  1,
-    1, 94, 95, 96, 97,  1, 98, 58, 81, 99,100,  4, 58,  0,  0,  0,
-    0,  0,  0, 19, 50,  0,  0,  0,  0,  0,  0, 61,  0,  0,101,102,
-    0,  0,103,  0,  0,  1,  1, 50,  0,  0,  0, 38,  0, 63,  0,  0,
-    0,  0,  0, 62,  0,  0,104, 68, 61,  0,  0,  0, 78,  0,  0,  0,
-  105,106, 58, 38, 81,  0,  0,  0,  0,  0,  0,107,  1, 14,  4, 12,
-   84,  0,  0,  0,  0, 38, 87,  0,  0,  0,  0,108,  0,  0,109, 61,
-    0,110,  0,  0,  0,  1,  0,  0,  0,  0, 19, 58,  0,  0,  0, 51,
-    0,111, 14, 52,112, 41,  0,  0, 62,  0,  0, 61,  0,  0,113,  0,
-   87,  0,  0,  0, 61, 62,  0,  0, 62,  0, 89,  0,  0,113,  0,  0,
-    0,  0,114,  0,  0,  0, 78, 55,  0, 38,  1, 58,  1, 58,  0,  0,
-   63, 89,  0,  0,115,  0,  0,  0, 55,  0,  0,  0,  0,115,  0,  0,
-    0,  0, 61,  0,  0,  0,  0, 79,  0, 61,  0,  0,  0,  0, 56,  0,
-   89, 80,  0,  0, 79,  0,  0,  0,  8, 91,  0,  0,  1, 87,  0,  0,
-  116,  0,  0,  0,  0,  0,  0,117,  0,118,119,120,121,  0,104,  4,
-  122, 49, 23,  0,  0,  0, 38, 50, 38, 58,  0,  0,  1, 87,  1,  1,
-    1,  1, 39,  1, 48,105, 87,  0,  0,  0,  0,  1,  0,  0,  0,123,
-    4,122,  0,  0,  0,  1,124,  0,  0,  0,  0,  0,230,230,230,230,
-  230,232,220,220,220,220,232,216,220,220,220,220,220,202,202,220,
-  220,220,220,202,202,220,220,220,  1,  1,  1,  1,  1,220,220,220,
-  220,230,230,230,230,240,230,220,220,220,230,230,230,220,220,  0,
-  230,230,230,220,220,220,220,230,232,220,220,230,233,234,234,233,
-  234,234,233,230,  0,  0,  0,230,  0,220,230,230,230,230,220,230,
-  230,230,222,220,230,230,220,220,230,222,228,230, 10, 11, 12, 13,
-   14, 15, 16, 17, 18, 19, 19, 20, 21, 22,  0, 23,  0, 24, 25,  0,
-  230,220,  0, 18, 30, 31, 32,  0,  0,  0,  0, 27, 28, 29, 30, 31,
-   32, 33, 34,230,230,220,220,230,220,230,230,220, 35,  0,  0,  0,
-    0,  0,230,230,230,  0,  0,230,230,  0,220,230,230,220,  0,  0,
-    0, 36,  0,  0,230,220,230,230,220,220,230,220,220,230,220,230,
-  220,230,230,  0,  0,220,  0,  0,230,230,  0,230,  0,230,230,230,
-  230,230,  0,  0,  0,220,220,220,230,220,220,220,230,230,  0,220,
-   27, 28, 29,230,  7,  0,  0,  0,  0,  9,  0,  0,  0,230,220,230,
-  230,  0,  0,  0,  0,  0,230,  0,  0, 84, 91,  0,  0,  0,  0,  9,
-    9,  0,  0,  0,  0,  0,  9,  0,103,103,  9,  0,107,107,107,107,
-  118,118,  9,  0,122,122,122,122,220,220,  0,  0,  0,220,  0,220,
-    0,216,  0,  0,  0,129,130,  0,132,  0,  0,  0,  0,  0,130,130,
-  130,130,  0,  0,130,  0,230,230,  9,  0,230,230,  0,  0,220,  0,
-    0,  0,  0,  7,  0,  9,  9,  0,  9,  9,  0,  0,  0,230,  0,  0,
-    0,228,  0,  0,  0,222,230,220,220,  0,  0,  0,230,  0,  0,220,
-  230,220,  0,220,230,230,230,  0,  0,  0,  9,  9,  0,  0,  7,  0,
-  230,  0,  1,  1,  1,  0,  0,  0,230,234,214,220,202,230,230,230,
-  230,230,232,228,228,220,218,230,233,220,230,220,230,230,  1,  1,
-    1,  1,  1,230,  0,  1,  1,230,220,230,  1,  1,  0,  0,218,228,
-  232,222,224,224,  0,  8,  8,  0,  0,  0,  0,220,230,  0,230,230,
-  220,  0,  0,230,  0,  0, 26,  0,  0,220,  0,230,230,  1,220,  0,
-    0,230,220,  0,  0,  0,220,220,  0,  0,230,220,  0,  9,  7,  0,
-    0,  7,  9,  0,  0,  0,  9,  7,  6,  6,  0,  0,  0,  0,  1,  0,
-    0,216,216,  1,  1,  1,  0,  0,  0,226,216,216,216,216,216,  0,
-  220,220,220,  0,232,232,220,230,230,230,  7,  0, 16, 17, 17, 17,
-   17, 17, 17, 33, 17, 17, 17, 19, 17, 17, 17, 17, 20,101, 17,113,
-  129,169, 17, 27, 28, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+   37,  0,  0,  0,  0,  0,  0,  0,  0,  0, 38, 39,  0,  0,  0,  0,
+    0,  0, 40, 41, 42,  0, 43,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  1,  2,  0,  0,  0,  0,  3,  0,  0,  0,  4,  5,
+    6,  7,  0,  8,  9, 10,  0, 11, 12, 13, 14, 15, 16, 17, 16, 18,
+   16, 19, 16, 19, 16, 19,  0, 19, 16, 20, 16, 19, 21, 19,  0, 22,
+   23, 24, 25, 26, 27, 28, 29, 30, 31,  0, 32,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0, 33,  0,  0,  0,  0,  0,  0, 34,  0,  0, 35,
+    0,  0, 36,  0, 37,  0,  0,  0, 38, 39, 40, 41, 42, 43, 44, 45,
+   46,  0,  0, 47,  0,  0,  0, 48,  0,  0,  0, 49,  0,  0,  0,  0,
+    0,  0,  0, 50,  0, 51,  0, 52, 53,  0, 54,  0,  0,  0,  0,  0,
+    0, 55, 56, 57,  0,  0,  0,  0, 58,  0,  0, 59, 60, 61, 62, 63,
+    0,  0, 64, 65,  0,  0,  0, 66,  0,  0,  0,  0, 67,  0,  0,  0,
+   68,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 69,
+    0,  0,  0, 70,  0, 71,  0,  0, 72,  0,  0, 73,  0,  0,  0,  0,
+    0,  0,  0,  0, 74,  0,  0,  0,  0,  0, 75, 76,  0, 77, 78,  0,
+    0, 79, 80,  0, 81, 62,  0, 82, 83,  0,  0, 84, 85, 86,  0,  0,
+    0, 87,  0, 88,  0,  0, 51, 89, 51,  0, 90,  0, 91,  0,  0,  0,
+   80,  0,  0,  0, 92, 93,  0, 94, 95, 96, 97,  0,  0,  0,  0,  0,
+   51,  0,  0,  0,  0, 98, 99,  0,  0,  0,  0,  0,  0,100,  0,  0,
+    0,  0,  0,101,102,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,103,
+    0,  0,104,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,105,106,  0,
+    0,107,  0,  0,  0,  0,  0,  0,108,  0,109,  0,102,  0,  0,  0,
+    0,  0,110,111,  0,  0,  0,  0,  0,  0,  0,112,  0,  0,  0,  0,
+    0,  0,  0,113,  0,114,  0,  0,  0,  0,  0,  0,  1,  2,  3,  4,
+    5,  6,  7,  0,  8,  0,  0,  0,  0,  9, 10, 11, 12,  0,  0,  0,
+    0, 13,  0,  0, 14, 15,  0, 16,  0, 17, 18,  0,  0, 19,  0, 20,
+   21,  0,  0,  0,  0,  0, 22, 23,  0, 24, 25,  0,  0, 26,  0,  0,
+    0, 27,  0,  0, 28, 29, 30, 31,  0,  0,  0, 32, 33, 34,  0,  0,
+   33,  0,  0, 35, 33,  0,  0,  0, 33, 36,  0,  0,  0,  0,  0, 37,
+   38,  0,  0,  0,  0,  0,  0, 39, 40,  0,  0,  0,  0,  0,  0, 41,
+   42,  0,  0,  0,  0, 43,  0, 44,  0,  0,  0, 45, 46,  0,  0,  0,
+   47,  0,  0,  0,  0,  0,  0, 48, 49,  0,  0,  0,  0, 50,  0,  0,
+    0, 51,  0, 52,  0, 53,  0,  0,  0,  0, 54,  0,  0,  0,  0, 55,
+    0, 56,  0,  0,  0,  0, 57, 58,  0,  0,  0, 59, 60,  0,  0,  0,
+    0,  0,  0, 61, 52,  0, 62, 63,  0,  0, 64,  0,  0,  0, 65, 66,
+    0,  0,  0, 67,  0, 68, 69, 70, 71, 72,  1, 73,  0, 74, 75, 76,
+    0,  0, 77, 78,  0,  0,  0, 79,  0,  0,  1,  1,  0,  0, 80,  0,
+    0, 81,  0,  0,  0,  0, 77, 82,  0, 83,  0,  0,  0,  0,  0, 78,
+   84,  0, 85,  0, 52,  0,  1, 78,  0,  0, 86,  0,  0, 87,  0,  0,
+    0,  0,  0, 88, 57,  0,  0,  0,  0,  0,  0, 89, 90,  0,  0, 84,
+    0,  0, 33,  0,  0, 91,  0,  0,  0,  0, 92,  0,  0,  0,  0, 49,
+    0,  0, 93,  0,  0,  0,  0, 94, 95,  0,  0, 96,  0,  0, 97,  0,
+    0,  0, 98,  0,  0,  0, 99,  0,  0,  0,  0,100,101, 93,  0,  0,
+  102,  0,  0,  0, 84,  0,  0,103,  0,  0,  0,104,105,  0,  0,106,
+  107,  0,  0,  0,  0,  0,  0,108,  0,  0,109,  0,  0,  0,  0,110,
+   33,  0,111,112,113, 35,  0,  0,114,  0,  0,  0,115,  0,  0,  0,
+    0,  0,  0,116,  0,  0,117,  0,  0,  0,  0,118, 88,  0,  0,  0,
+    0,  0, 57,  0,  0,  0,  0, 52,119,  0,  0,  0,  0,120,  0,  0,
+  121,  0,  0,  0,  0,119,  0,  0,122,  0,  0,  0,  0,  0,  0,123,
+    0,  0,  0,124,  0,  0,  0,125,  0,126,  0,  0,  0,  0,127,128,
+  129,  0,130,  0,131,  0,  0,  0,132,133,134,  0, 77,  0,  0,  0,
+    0,  0, 35,  0,  0,  0,135,  0,  0,  0,136,  0,  0,137,  0,  0,
+  138,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1,  2,  3,  4,
+    5,  6,  7,  4,  4,  8,  9, 10,  1, 11, 12, 13, 14, 15, 16, 17,
+   18,  1,  1,  1, 19,  1,  0,  0, 20, 21, 22,  1, 23,  4, 21, 24,
+   25, 26, 27, 28, 29, 30,  0,  0,  1,  1, 31,  0,  0,  0, 32, 33,
+   34, 35,  1, 36, 37,  0,  0,  0,  0, 38,  1, 39, 14, 39, 40, 41,
+   42,  0,  0,  0, 43, 36, 44, 45, 21, 45, 46,  0,  0,  0, 19,  1,
+   21,  0,  0, 47,  0, 38, 48,  1,  1, 49, 49, 50,  0,  0, 51,  0,
+    0,  0, 52,  1,  0,  0, 38, 14,  4,  1,  1,  1, 53, 21, 43, 52,
+   54, 21, 35,  1,  0,  0,  0, 55,  0,  0,  0, 56, 57, 58,  0,  0,
+    0,  0,  0, 59,  0, 60,  0,  0,  0,  0, 61, 62,  0,  0, 63,  0,
+    0,  0, 64,  0,  0,  0, 65,  0,  0,  0, 66,  0,  0,  0, 67,  0,
+    0,  0, 68,  0,  0, 69, 70,  0, 71, 72, 73, 74, 75, 76,  0,  0,
+    0, 77,  0,  0,  0, 78, 79,  0,  0,  0,  0, 47,  0,  0,  0, 49,
+    0, 80,  0,  0,  0, 62,  0,  0, 63,  0,  0, 81,  0,  0, 82,  0,
+    0,  0, 83,  0,  0, 19, 84,  0, 62,  0,  0,  0,  0, 49,  1, 85,
+    1, 52, 15, 86, 36, 10, 21, 87,  0, 55,  0,  0,  0,  0, 19, 10,
+    1,  0,  0,  0,  0,  0, 88,  0,  0, 89,  0,  0, 88,  0,  0,  0,
+    0, 78,  0,  0, 87,  9, 12,  4, 90,  8, 91, 47,  0, 58, 50,  0,
+   21,  1, 21, 92, 93,  1,  1,  1,  1, 94, 95, 96, 97,  1, 98, 58,
+   81, 99,100,  4, 58,  0,  0,  0,  0,  0,  0, 19, 50,  0,  0,  0,
+    0,  0,  0, 61,  0,  0,101,102,  0,  0,103,  0,  0,  1,  1, 50,
+    0,  0,  0, 38,  0, 63,  0,  0,  0,  0,  0, 62,  0,  0,104, 68,
+   61,  0,  0,  0, 78,  0,  0,  0,105,106, 58, 38, 81,  0,  0,  0,
+    0,  0,  0,107,  1, 14,  4, 12, 84,  0,  0,  0,  0, 38, 87,  0,
+    0,  0,  0,108,  0,  0,109, 61,  0,110,  0,  0,  0,  1,  0,  0,
+    0,  0, 19, 58,  0,  0,  0, 51,  0,111, 14, 52,112, 41,  0,  0,
+   62,  0,  0, 61,  0,  0,113,  0, 87,  0,  0,  0, 61, 62,  0,  0,
+   62,  0, 89,  0,  0,113,  0,  0,  0,  0,114,  0,  0,  0, 78, 55,
+    0, 38,  1, 58,  1, 58,  0,  0, 63, 89,  0,  0,115,  0,  0,  0,
+   55,  0,  0,  0,  0,115,  0,  0,  0,  0, 61,  0,  0,  0,  0, 79,
+    0, 61,  0,  0,  0,  0, 56,  0, 89, 80,  0,  0, 79,  0,  0,  0,
+    8, 91,  0,  0,  1, 87,  0,  0,116,  0,  0,  0,  0,  0,  0,117,
+    0,118,119,120,121,  0,104,  4,122, 49, 23,  0,  0,  0, 38, 50,
+   38, 58,  0,  0,  1, 87,  1,  1,  1,  1, 39,  1, 48,105, 87,  0,
+    0,  0,  0,  1,  0,  0,  0,123,  4,122,  0,  0,  0,  1,124,  0,
+    0,  0,  0,  0,230,230,230,230,230,232,220,220,220,220,232,216,
+  220,220,220,220,220,202,202,220,220,220,220,202,202,220,220,220,
+    1,  1,  1,  1,  1,220,220,220,220,230,230,230,230,240,230,220,
+  220,220,230,230,230,220,220,  0,230,230,230,220,220,220,220,230,
+  232,220,220,230,233,234,234,233,234,234,233,230,  0,  0,  0,230,
+    0,220,230,230,230,230,220,230,230,230,222,220,230,230,220,220,
+  230,222,228,230, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20,
+   21, 22,  0, 23,  0, 24, 25,  0,230,220,  0, 18, 30, 31, 32,  0,
+    0,  0,  0, 27, 28, 29, 30, 31, 32, 33, 34,230,230,220,220,230,
+  220,230,230,220, 35,  0,  0,  0,  0,  0,230,230,230,  0,  0,230,
+  230,  0,220,230,230,220,  0,  0,  0, 36,  0,  0,230,220,230,230,
+  220,220,230,220,220,230,220,230,220,230,230,  0,  0,220,  0,  0,
+  230,230,  0,230,  0,230,230,230,230,230,  0,  0,  0,220,220,220,
+  230,220,220,220,230,230,  0,220, 27, 28, 29,230,  7,  0,  0,  0,
+    0,  9,  0,  0,  0,230,220,230,230,  0,  0,  0,  0,  0,230,  0,
+    0, 84, 91,  0,  0,  0,  0,  9,  9,  0,  0,  0,  0,  0,  9,  0,
+  103,103,  9,  0,107,107,107,107,118,118,  9,  0,122,122,122,122,
+  220,220,  0,  0,  0,220,  0,220,  0,216,  0,  0,  0,129,130,  0,
+  132,  0,  0,  0,  0,  0,130,130,130,130,  0,  0,130,  0,230,230,
+    9,  0,230,230,  0,  0,220,  0,  0,  0,  0,  7,  0,  9,  9,  0,
+    9,  9,  0,  0,  0,230,  0,  0,  0,228,  0,  0,  0,222,230,220,
+  220,  0,  0,  0,230,  0,  0,220,230,220,  0,220,230,230,230,  0,
+    0,  0,  9,  9,  0,  0,  7,  0,230,  0,  1,  1,  1,  0,  0,  0,
+  230,234,214,220,202,230,230,230,230,230,232,228,228,220,218,230,
+  233,220,230,220,230,230,  1,  1,  1,  1,  1,230,  0,  1,  1,230,
+  220,230,  1,  1,  0,  0,218,228,232,222,224,224,  0,  8,  8,  0,
+    0,  0,  0,220,230,  0,230,230,220,  0,  0,230,  0,  0, 26,  0,
+    0,220,  0,230,230,  1,220,  0,  0,230,220,  0,  0,  0,220,220,
+    0,  0,230,220,  0,  9,  7,  0,  0,  7,  9,  0,  0,  0,  9,  7,
+    6,  6,  0,  0,  0,  0,  1,  0,  0,216,216,  1,  1,  1,  0,  0,
+    0,226,216,216,216,216,216,  0,220,220,220,  0,232,232,220,230,
+  230,230,  7,  0, 16, 17, 17, 17, 17, 17, 17, 33, 17, 17, 17, 19,
+   17, 17, 17, 17, 20,101, 17,113,129,169, 17, 27, 28, 17, 17, 17,
    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
-   17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,237,  0,  1,  2,  2,
-    0,  3,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  4,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  5,  0,  0,  0,  0,  6,  7,  8,
-    9,  0,  0,  0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,  0,  0,
-    0,  0,  0,  0,  0,  0,  0, 20,  0,  0, 21, 22,  0,  0,  0,  0,
-   23, 24, 25, 26,  0, 27,  0, 28, 29, 30, 31, 32,  0,  0,  0,  0,
-    0,  0,  0, 33, 34, 35, 36,  0,  0,  0,  0,  0, 37,  0,  0,  0,
-    0,  0,  0,  0,  0,  0, 38, 39,  0,  0,  0,  0,  1,  2, 40, 41,
-    0,  1,  2,  2,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,
-    0,  0,  0,  2,  0,  0,  0,  0,  0,  0,  3,  4,  0,  0,  5,  0,
-    0,  0,  6,  0,  0,  0,  0,  0,  0,  0,  7,  1,  0,  0,  0,  0,
-    0,  0,  8,  9,  0,  0,  0,  0,  0,  0, 10,  0,  0, 10,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 10,  0,  0,  0, 10,
-    0,  0,  0,  0,  0,  0, 11, 12,  0, 13,  0, 14, 15, 16,  0,  0,
-    0,  0,  0,  1, 17, 18,  0, 19,  7,  1,  0,  0,  0, 20, 20,  7,
-   20, 20, 20, 20, 20, 20, 20,  8, 21,  0, 22,  0,  7, 23, 24,  0,
-   20, 20, 25,  0,  0,  0, 26, 27,  1,  7, 20, 20, 20, 20, 20,  1,
-   28, 29, 30, 31,  0,  0, 20,  0,  0,  0,  0,  0,  0,  0, 10,  0,
-    0,  0,  0,  0,  0,  0, 20, 20, 20,  1,  0,  0,  8, 21, 32,  4,
-    0, 10,  0, 33,  7, 20, 20, 20,  0,  0,  0,  0,  8, 34, 34, 35,
-   36, 34, 37,  0, 38,  1, 20, 20,  0,  0, 39,  0,  1,  1,  0,  8,
-   21,  1, 20,  0,  0,  0,  1,  0,  0, 40,  1,  1,  0,  0,  8, 21,
-    0,  1,  0,  1,  0,  1,  0,  0,  0,  0, 26, 34, 34, 34, 34, 34,
-   34, 34, 34, 34, 21,  7, 20, 41, 34, 34, 34, 34, 34, 34, 34, 34,
-   34, 21,  0, 42, 43, 44,  0, 45,  0,  8, 21,  0,  0,  0,  0,  0,
-    0,  0,  0, 46,  7,  1, 10,  1,  0,  0,  0,  1, 20, 20,  1,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0, 26, 34,  9,  0,  0, 20, 20,
-    1, 20, 20,  0,  0,  0,  0,  0,  0,  0, 26, 21,  0,  1,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  3, 47, 48,  0,  0,  0,
-    0,  0,  0,  0,  0,  1,  2,  3,  4,  5,  6,  7,  7,  8,  7,  7,
-    7,  7,  7,  7,  7,  7,  7,  7,  9, 10, 11, 11, 11, 11, 12, 13,
-   13, 13, 13, 14, 15, 16, 17, 18, 19, 20, 21, 13, 22, 13, 13, 13,
-   13, 23, 24, 24, 25, 26, 13, 13, 13, 27, 28, 29, 13, 30, 31, 32,
-   33, 34, 35, 36,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
-    7,  7,  7,  7,  7,  7,  7,  7, 37,  7, 38, 39,  7, 40,  7,  7,
-    7, 41, 13, 42,  7,  7, 43,  7, 44, 13, 13, 13, 13, 13, 13, 13,
+   17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+   17, 17, 17,237,  0,  1,  2,  2,  0,  3,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  4,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    5,  0,  0,  0,  0,  6,  7,  8,  9,  0,  0,  0, 10, 11, 12, 13,
+   14, 15, 16, 17, 18, 19,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20,
+    0,  0, 21, 22,  0,  0,  0,  0, 23, 24, 25, 26,  0, 27,  0, 28,
+   29, 30, 31, 32,  0,  0,  0,  0,  0,  0,  0, 33, 34, 35, 36,  0,
+    0,  0,  0,  0, 37,  0,  0,  0,  0,  0,  0,  0,  0,  0, 38, 39,
+    0,  0,  0,  0,  1,  2, 40, 41,  0,  1,  2,  2,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  2,  0,  0,  0,  0,
+    0,  0,  3,  4,  0,  0,  5,  0,  0,  0,  6,  0,  0,  0,  0,  0,
+    0,  0,  7,  1,  0,  0,  0,  0,  0,  0,  8,  9,  0,  0,  0,  0,
+    0,  0, 10,  0,  0, 10,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0, 10,  0,  0,  0, 10,  0,  0,  0,  0,  0,  0, 11, 12,
+    0, 13,  0, 14, 15, 16,  0,  0,  0,  0,  0,  1, 17, 18,  0, 19,
+    7,  1,  0,  0,  0, 20, 20,  7, 20, 20, 20, 20, 20, 20, 20,  8,
+   21,  0, 22,  0,  7, 23, 24,  0, 20, 20, 25,  0,  0,  0, 26, 27,
+    1,  7, 20, 20, 20, 20, 20,  1, 28, 29, 30, 31,  0,  0, 20,  0,
+    0,  0,  0,  0,  0,  0, 10,  0,  0,  0,  0,  0,  0,  0, 20, 20,
+   20,  1,  0,  0,  8, 21, 32,  4,  0, 10,  0, 33,  7, 20, 20, 20,
+    0,  0,  0,  0,  8, 34, 34, 35, 36, 34, 37,  0, 38,  1, 20, 20,
+    0,  0, 39,  0,  1,  1,  0,  8, 21,  1, 20,  0,  0,  0,  1,  0,
+    0, 40,  1,  1,  0,  0,  8, 21,  0,  1,  0,  1,  0,  1,  0,  0,
+    0,  0, 26, 34, 34, 34, 34, 34, 34, 34, 34, 34, 21,  7, 20, 41,
+   34, 34, 34, 34, 34, 34, 34, 34, 34, 21,  0, 42, 43, 44,  0, 45,
+    0,  8, 21,  0,  0,  0,  0,  0,  0,  0,  0, 46,  7,  1, 10,  1,
+    0,  0,  0,  1, 20, 20,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0, 26, 34,  9,  0,  0, 20, 20,  1, 20, 20,  0,  0,  0,  0,  0,
+    0,  0, 26, 21,  0,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  3, 47, 48,  0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  3,
+    4,  5,  6,  7,  7,  8,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+    9, 10, 11, 11, 11, 11, 12, 13, 13, 13, 13, 14, 15, 16, 17, 18,
+   19, 20, 21, 13, 22, 13, 13, 13, 13, 23, 24, 24, 25, 26, 13, 13,
+   13, 27, 28, 29, 13, 30, 31, 32, 33, 34, 35, 36,  7,  7,  7,  7,
+    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+   37,  7, 38, 39,  7, 40,  7,  7,  7, 41, 13, 42,  7,  7, 43,  7,
+   44, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
@@ -1715,202 +1716,202 @@
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-   13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-   13, 13, 13, 13, 45,  0,  0,  1,  2,  2,  2,  3,  4,  5,  6,  7,
-    8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
-   24, 25, 26, 27, 28, 29, 30, 31, 32, 32, 33, 34, 35, 36, 37, 37,
-   37, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
-   51, 52,  2,  2, 53, 54, 55, 56, 57, 58, 59, 59, 59, 59, 60, 59,
-   59, 59, 59, 59, 59, 59, 61, 61, 59, 59, 59, 59, 62, 63, 64, 65,
-   66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 59, 70, 70,
+   13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 45,  0,  0,  1,
+    2,  2,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
+   16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+   32, 32, 33, 34, 35, 36, 37, 37, 37, 37, 37, 38, 39, 40, 41, 42,
+   43, 44, 45, 46, 47, 48, 49, 50, 51, 52,  2,  2, 53, 54, 55, 56,
+   57, 58, 59, 59, 59, 59, 60, 59, 59, 59, 59, 59, 59, 59, 61, 61,
+   59, 59, 59, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
+   74, 75, 76, 77, 78, 59, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
    70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
-   70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
-   70, 79, 70, 70, 70, 70, 80, 80, 80, 80, 80, 80, 80, 80, 80, 81,
-   82, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 32, 32,
+   70, 70, 70, 70, 70, 70, 70, 70, 70, 79, 70, 70, 70, 70, 80, 80,
+   80, 80, 80, 80, 80, 80, 80, 81, 82, 82, 83, 84, 85, 86, 87, 88,
+   89, 90, 91, 92, 93, 94, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-   32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-   32, 32, 32, 32, 32, 95, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-   96, 96, 96, 96, 96, 96, 96, 96, 70, 70, 97, 98, 99,100,101,101,
-  102,103,104,105,106,107,108,109,110,111, 96,112,113,114,115,116,
-  117,118,119,119,120,121,122,123,124,125,126,127,128,129,130,131,
-  132, 96,133,134,135,136,137,138,139,140,141,142,143, 96,144,145,
-   96,146,147,148,149, 96,150,151,152,153,154,155,156, 96,157,158,
-  159,160, 96,161,162,163,164,164,164,164,164,164,164,165,166,164,
-  167, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-   96, 96, 96, 96, 96,168,169,169,169,169,169,169,169,169,170, 96,
-   96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,171,171,
-  171,171,172, 96, 96, 96,173,173,173,173,174,175,176,177, 96, 96,
-   96, 96,178,179,180,181,182,182,182,182,182,182,182,182,182,182,
-  182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
-  182,182,182,182,182,183,182,182,182,182,182,182,184,184,184,185,
-  186, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-   96, 96, 96, 96, 96,187,188,189,190,191,191,192, 96, 96, 96, 96,
-   96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,193,194,
+   32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 95, 96, 96,
    96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-   96, 96, 96, 96,195,196, 59,197,198,199,200,201,202, 96,203,204,
-  205, 59, 59,206, 59,207,208,208,208,208,208,209, 96, 96, 96, 96,
-   96, 96, 96, 96,210, 96,211,212,213, 96, 96,214, 96, 96, 96,215,
-   96, 96, 96, 96, 96,216,217,218,219, 96, 96, 96, 96, 96,220,221,
-  222, 96,223,224, 96, 96,225,226, 59,227,228, 96, 59, 59, 59, 59,
-   59, 59, 59,229,230,231,232,233, 59, 59,234,235, 59,236, 96, 96,
-   96, 96, 96, 96, 96, 96, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
-   70, 70, 70,237, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
-   70, 70, 70, 70,238, 70,239, 70, 70, 70, 70, 70, 70, 70, 70, 70,
+   70, 70, 97, 98, 99,100,101,101,102,103,104,105,106,107,108,109,
+  110,111, 96,112,113,114,115,116,117,118,119,119,120,121,122,123,
+  124,125,126,127,128,129,130,131,132, 96,133,134,135,136,137,138,
+  139,140,141,142,143, 96,144,145, 96,146,147,148,149, 96,150,151,
+  152,153,154,155,156, 96,157,158,159,160, 96,161,162,163,164,164,
+  164,164,164,164,164,165,166,164,167, 96, 96, 96, 96, 96, 96, 96,
+   96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,168,169,169,
+  169,169,169,169,169,169,170, 96, 96, 96, 96, 96, 96, 96, 96, 96,
+   96, 96, 96, 96, 96, 96,171,171,171,171,172, 96, 96, 96,173,173,
+  173,173,174,175,176,177, 96, 96, 96, 96,178,179,180,181,182,182,
+  182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
+  182,182,182,182,182,182,182,182,182,182,182,182,182,183,182,182,
+  182,182,182,182,184,184,184,185,186, 96, 96, 96, 96, 96, 96, 96,
+   96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,187,188,189,
+  190,191,191,192, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
+   96, 96, 96, 96, 96, 96,193,194, 96, 96, 96, 96, 96, 96, 96, 96,
+   96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,195,196, 59,197,
+  198,199,200,201,202, 96,203,204,205, 59, 59,206, 59,207,208,208,
+  208,208,208,209, 96, 96, 96, 96, 96, 96, 96, 96,210, 96,211,212,
+  213, 96, 96,214, 96, 96, 96,215, 96, 96, 96, 96, 96,216,217,218,
+  219, 96, 96, 96, 96, 96,220,221,222, 96,223,224, 96, 96,225,226,
+   59,227,228, 96, 59, 59, 59, 59, 59, 59, 59,229,230,231,232,233,
+   59, 59,234,235, 59,236, 96, 96, 96, 96, 96, 96, 96, 96, 70, 70,
+   70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,237, 70, 70, 70, 70,
+   70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,238, 70,239, 70,
    70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
-   70, 70, 70,240, 70, 70, 70, 70, 70, 70, 70, 70, 70,241, 96, 96,
-   96, 96, 96, 96, 96, 96, 70, 70, 70, 70,242, 96, 96, 96, 96, 96,
-   96, 96, 96, 96, 96, 96, 70, 70, 70, 70, 70, 70,243, 70, 70, 70,
-   70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,244, 96, 96,
-   96, 96, 96, 96, 96, 96,245, 96,246,247,  0,  1,  2,  2,  0,  1,
-    2,  2,  2,  3,  4,  5,  0,  0,  0,  0,  0,  0,  0,  0,  0, 19,
-   19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
-   19,  0,  0,  0,  0,  0,  0,  0, 19,  0,  0,  0,  0,  0, 19, 19,
-   19, 19, 19, 19, 19,  0, 19,  0,  0,  0,  0,  0,  0,  0, 19, 19,
-   19, 19, 19,  0,  0,  0,  0,  0, 26, 26,  0,  0,  0,  0,  1,  1,
-    1,  1,  1,  1,  1,  1,  9,  9,  9,  9,  0,  9,  9,  9,  2,  2,
-    9,  9,  9,  9,  0,  9,  2,  2,  2,  2,  9,  0,  9,  0,  9,  9,
-    9,  2,  9,  2,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
-    2,  9,  9,  9,  9,  9,  9,  9, 55, 55, 55, 55, 55, 55, 55, 55,
-   55, 55, 55, 55, 55, 55,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,
-    6,  6,  6,  1,  1,  6,  2,  4,  4,  4,  4,  4,  4,  4,  4,  4,
-    4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  2,  4,  4,
-    4,  2,  2,  4,  4,  4,  2, 14, 14, 14, 14, 14, 14, 14, 14, 14,
-   14, 14, 14, 14, 14, 14,  2,  2,  2,  2,  2,  2,  2,  2, 14, 14,
-   14,  2,  2,  2,  2, 14, 14, 14, 14, 14, 14,  2,  2,  2,  3,  3,
-    3,  3,  3,  0,  3,  3,  3,  3,  3,  3,  0,  3,  3,  3,  3,  3,
-    3,  3,  3,  3,  3,  3,  3,  3,  3,  0,  3,  3,  3,  0,  0,  3,
-    3,  3,  3,  3,  3,  3,  3,  3,  3,  1,  1,  1,  1,  1,  1,  1,
-    1,  1,  1,  1,  3,  3,  1,  3,  3,  3,  3,  3,  3,  3, 37, 37,
-   37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,  2, 37, 37, 37,
-   37,  2,  2, 37, 37, 37, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
-    2,  2,  2,  2,  2,  2, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
-   64,  2,  2, 64, 64, 64, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90,
-   90, 90, 90, 90,  2,  2, 90, 90, 90, 90, 90, 90, 90,  2, 95, 95,
-   95, 95, 95, 95, 95, 95, 95, 95, 95, 95,  2,  2, 95,  2, 37, 37,
-   37,  2,  2,  2,  2,  2,  3,  3,  3,  3,  3,  3,  3,  2,  3,  3,
-    2,  2,  2,  2,  2,  2,  3,  3,  0,  3,  3,  3,  3,  3,  7,  7,
-    7,  7,  7,  7,  7,  7,  7,  1,  1,  1,  1,  7,  7,  7,  7,  7,
-    7,  7,  0,  0,  7,  7,  5,  5,  5,  5,  2,  5,  5,  5,  5,  5,
-    5,  5,  5,  2,  2,  5,  5,  2,  2,  5,  5,  5,  5,  5,  5,  5,
-    5,  5,  5,  5,  5,  5,  5,  2,  5,  5,  5,  5,  5,  5,  5,  2,
-    5,  2,  2,  2,  5,  5,  5,  5,  2,  2,  5,  5,  5,  5,  5,  2,
-    2,  5,  5,  5,  5,  2,  2,  2,  2,  2,  2,  2,  2,  5,  2,  2,
-    2,  2,  5,  5,  2,  5,  5,  5,  5,  5,  2,  2,  5,  5,  5,  5,
-    5,  5,  5,  5,  5,  2,  2, 11, 11, 11,  2, 11, 11, 11, 11, 11,
-   11,  2,  2,  2,  2, 11, 11,  2,  2, 11, 11, 11, 11, 11, 11, 11,
-   11, 11, 11, 11, 11, 11, 11,  2, 11, 11, 11, 11, 11, 11, 11,  2,
-   11, 11,  2, 11, 11,  2, 11, 11,  2,  2, 11,  2, 11, 11, 11,  2,
-    2, 11, 11, 11,  2,  2,  2, 11,  2,  2,  2,  2,  2,  2,  2, 11,
-   11, 11, 11,  2, 11,  2,  2,  2,  2,  2,  2,  2, 11, 11, 11, 11,
-   11, 11, 11, 11, 11,  2,  2, 10, 10, 10,  2, 10, 10, 10, 10, 10,
-   10, 10, 10, 10,  2, 10, 10, 10,  2, 10, 10, 10, 10, 10, 10, 10,
-   10, 10, 10, 10, 10, 10, 10,  2, 10, 10, 10, 10, 10, 10, 10,  2,
-   10, 10,  2, 10, 10, 10, 10, 10,  2,  2, 10, 10, 10, 10, 10, 10,
-    2, 10, 10, 10,  2,  2, 10,  2,  2,  2,  2,  2,  2,  2, 10, 10,
-   10, 10,  2,  2, 10, 10, 10, 10,  2,  2,  2,  2,  2,  2,  2, 10,
-   10, 10, 10, 10, 10, 10,  2, 21, 21, 21,  2, 21, 21, 21, 21, 21,
-   21, 21, 21,  2,  2, 21, 21,  2,  2, 21, 21, 21, 21, 21, 21, 21,
-   21, 21, 21, 21, 21, 21, 21,  2, 21, 21, 21, 21, 21, 21, 21,  2,
-   21, 21,  2, 21, 21, 21, 21, 21,  2,  2, 21, 21, 21, 21, 21,  2,
-    2, 21, 21, 21,  2,  2,  2,  2,  2,  2,  2, 21, 21, 21,  2,  2,
-    2,  2, 21, 21,  2, 21, 21, 21, 21, 21,  2,  2, 21, 21,  2,  2,
-   22, 22,  2, 22, 22, 22, 22, 22, 22,  2,  2,  2, 22, 22, 22,  2,
-   22, 22, 22, 22,  2,  2,  2, 22, 22,  2, 22,  2, 22, 22,  2,  2,
-    2, 22, 22,  2,  2,  2, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
-    2,  2,  2,  2, 22, 22, 22,  2,  2,  2,  2,  2,  2, 22,  2,  2,
-    2,  2,  2,  2, 22, 22, 22, 22, 22,  2,  2,  2,  2,  2, 23, 23,
-   23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,  2, 23, 23, 23,  2,
-   23, 23, 23, 23, 23, 23, 23, 23,  2,  2, 23, 23, 23, 23, 23,  2,
-   23, 23, 23, 23,  2,  2,  2,  2,  2,  2,  2, 23, 23,  2, 23, 23,
-   23,  2,  2, 23,  2,  2, 23, 23, 23, 23,  2,  2, 23, 23,  2,  2,
-    2,  2,  2,  2,  2, 23, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
-   16, 16, 16,  2, 16, 16, 16,  2, 16, 16, 16, 16, 16, 16, 16, 16,
-   16, 16,  2, 16, 16, 16, 16, 16,  2,  2, 16, 16, 16, 16, 16,  2,
-   16, 16, 16, 16,  2,  2,  2,  2,  2,  2,  2, 16, 16,  2, 16, 16,
-   16, 16,  2,  2, 16, 16,  2, 16, 16, 16,  2,  2,  2,  2, 20, 20,
-   20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,  2, 20, 20, 20,  2,
-   20, 20, 20, 20, 20, 20,  2,  2,  2,  2, 20, 20, 20, 20, 20, 20,
-   20, 20,  2,  2, 20, 20,  2, 36, 36, 36,  2, 36, 36, 36, 36, 36,
-   36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,  2,  2,  2,
-   36, 36, 36, 36, 36, 36, 36, 36,  2, 36, 36, 36, 36, 36, 36, 36,
-   36, 36,  2, 36,  2,  2,  2,  2, 36,  2,  2,  2,  2, 36, 36, 36,
-   36, 36, 36,  2, 36,  2,  2,  2,  2,  2,  2,  2, 36, 36,  2,  2,
-   36, 36, 36,  2,  2,  2,  2, 24, 24, 24, 24, 24, 24, 24, 24, 24,
-   24, 24, 24, 24, 24, 24, 24, 24, 24,  2,  2,  2,  2,  0, 24, 24,
-   24, 24,  2,  2,  2,  2,  2, 18, 18,  2, 18,  2, 18, 18, 18, 18,
-   18,  2, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
-   18, 18,  2, 18,  2, 18, 18, 18, 18, 18, 18, 18,  2,  2, 18, 18,
-   18, 18, 18,  2, 18,  2, 18, 18, 18, 18, 18, 18, 18,  2, 18, 18,
-    2,  2, 18, 18, 18, 18, 25, 25, 25, 25, 25, 25, 25, 25,  2, 25,
-   25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,  2,  2,  2, 25, 25,
-   25, 25, 25,  2, 25, 25, 25, 25, 25, 25, 25,  0,  0,  0,  0, 25,
-   25,  2,  2,  2,  2,  2, 33, 33, 33, 33, 33, 33, 33, 33,  8,  8,
-    8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,  2,  8,  2,  2,
-    2,  2,  2,  8,  2,  2,  8,  8,  8,  0,  8,  8,  8,  8, 12, 12,
-   12, 12, 12, 12, 12, 12, 30, 30, 30, 30, 30, 30, 30, 30, 30,  2,
-   30, 30, 30, 30,  2,  2, 30, 30, 30, 30, 30, 30, 30,  2, 30, 30,
-   30,  2,  2, 30, 30, 30, 30, 30, 30, 30, 30,  2,  2,  2, 30, 30,
-    2,  2,  2,  2,  2,  2, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
-   29, 29, 29, 29,  2,  2, 28, 28, 28, 28, 28, 28, 28, 28, 34, 34,
-   34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,  2,  2,  2, 35, 35,
-   35, 35, 35, 35, 35, 35, 35, 35, 35,  0,  0,  0, 35, 35, 35,  2,
-    2,  2,  2,  2,  2,  2, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
-   45, 45, 45, 45,  2,  2,  2,  2,  2,  2,  2,  2,  2, 45, 44, 44,
-   44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,  0,  0,  2, 43, 43,
-   43, 43, 43, 43, 43, 43, 43, 43, 43, 43,  2,  2,  2,  2, 46, 46,
-   46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,  2, 46, 46, 46,  2,
-   46, 46,  2,  2,  2,  2, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
-   31, 31, 31, 31,  2,  2, 31, 31,  2,  2,  2,  2,  2,  2, 32, 32,
-    0,  0, 32,  0, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-    2,  2,  2,  2,  2,  2, 32,  2,  2,  2,  2,  2,  2,  2, 32, 32,
-   32,  2,  2,  2,  2,  2, 28, 28, 28, 28, 28, 28,  2,  2, 48, 48,
-   48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,  2, 48, 48,
-   48, 48,  2,  2,  2,  2, 48,  2,  2,  2, 48, 48, 48, 48, 52, 52,
-   52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,  2,  2, 52, 52,
-   52, 52, 52,  2,  2,  2, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58,
-   58, 58,  2,  2,  2,  2, 58, 58,  2,  2,  2,  2,  2,  2, 58, 58,
-   58,  2,  2,  2, 58, 58, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54,
-   54, 54,  2,  2, 54, 54, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
-   91, 91, 91, 91, 91,  2, 91, 91, 91, 91, 91,  2,  2, 91, 91, 91,
-    2,  2,  2,  2,  2,  2, 91, 91, 91, 91, 91, 91,  2,  2,  1,  1,
-    1,  1,  1,  1,  1,  2, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,
-   62, 62, 62,  2,  2,  2, 62, 62, 62, 62, 62, 62, 62,  2, 76, 76,
-   76, 76, 76, 76, 76, 76, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
-   93, 93,  2,  2,  2,  2,  2,  2,  2,  2, 93, 93, 93, 93, 70, 70,
-   70, 70, 70, 70, 70, 70,  2,  2,  2, 70, 70, 70, 70, 70, 70, 70,
-    2,  2,  2, 70, 70, 70, 73, 73, 73, 73, 73, 73, 73, 73,  6,  2,
-    2,  2,  2,  2,  2,  2,  8,  8,  8,  2,  2,  8,  8,  8,  1,  1,
-    1,  0,  1,  1,  1,  1,  1,  0,  1,  1,  1,  1,  1,  1,  1,  0,
-    0,  0,  0,  1,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  1,  1,
-    0,  2,  2,  2,  2,  2, 19, 19, 19, 19, 19, 19,  9,  9,  9,  9,
-    9,  6, 19, 19, 19, 19, 19, 19, 19, 19, 19,  9,  9,  9,  9,  9,
-   19, 19, 19, 19,  9,  9,  9,  9,  9, 19, 19, 19, 19, 19,  6, 19,
-   19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,  9,  9,  9,
-    9,  9,  9,  9,  2,  2,  2,  9,  2,  9,  2,  9,  2,  9,  9,  9,
-    9,  9,  9,  2,  9,  9,  9,  9,  9,  9,  2,  2,  9,  9,  9,  9,
-    9,  9,  2,  9,  9,  9,  2,  2,  9,  9,  9,  2,  9,  9,  9,  9,
-    9,  9,  9,  9,  9,  2,  0,  0,  0,  0,  1,  1,  0,  0,  0,  0,
-    0,  0,  0,  2,  0,  0,  0, 19,  2,  2,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0, 19,  0,  0,  0,  0,  0,  0,  0,  2, 19, 19,
-   19, 19, 19,  2,  2,  2,  0,  2,  2,  2,  2,  2,  2,  2,  1,  2,
-    2,  2,  2,  2,  2,  2,  0,  0,  0,  0,  0,  0,  9,  0,  0,  0,
-   19, 19,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 19,  0, 19,  0,
-    0,  0,  2,  2,  2,  2,  0,  0,  0,  2,  2,  2,  2,  2, 27, 27,
-   27, 27, 27, 27, 27, 27,  0,  0,  0,  0,  2,  2,  0,  0,  0,  0,
-    0,  0,  0,  0,  2,  0, 56, 56, 56, 56, 56, 56, 56, 56, 55, 55,
-   55, 55,  2,  2,  2,  2,  2, 55, 55, 55, 55, 55, 55, 55, 61, 61,
-   61, 61, 61, 61, 61, 61,  2,  2,  2,  2,  2,  2,  2, 61, 61,  2,
-    2,  2,  2,  2,  2,  2,  0,  0,  0,  0,  0,  0,  2,  2, 13, 13,
-   13, 13, 13, 13, 13, 13, 13, 13,  2, 13, 13, 13, 13, 13, 13, 13,
-   13, 13,  2,  2,  2,  2, 13, 13, 13, 13, 13, 13,  2,  2,  0,  0,
-    0,  0,  2,  2,  2,  2,  0,  0,  0,  0,  0, 13,  0, 13,  0, 13,
+   70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,240, 70, 70, 70, 70,
+   70, 70, 70, 70, 70,241, 70, 70, 70, 70,242, 96, 96, 96, 70, 70,
+   70, 70,243, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 70, 70,
+   70, 70, 70, 70,244, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
+   70, 70, 70, 70, 70,245, 96, 96, 96, 96, 96, 96, 96, 96,246, 96,
+  247,248,  0,  1,  2,  2,  0,  1,  2,  2,  2,  3,  4,  5,  0,  0,
+    0,  0,  0,  0,  0,  0,  0, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+   19, 19, 19, 19, 19, 19, 19, 19, 19,  0,  0,  0,  0,  0,  0,  0,
+   19,  0,  0,  0,  0,  0, 19, 19, 19, 19, 19, 19, 19,  0, 19,  0,
+    0,  0,  0,  0,  0,  0, 19, 19, 19, 19, 19,  0,  0,  0,  0,  0,
+   26, 26,  0,  0,  0,  0,  1,  1,  1,  1,  1,  1,  1,  1,  9,  9,
+    9,  9,  0,  9,  9,  9,  2,  2,  9,  9,  9,  9,  0,  9,  2,  2,
+    2,  2,  9,  0,  9,  0,  9,  9,  9,  2,  9,  2,  9,  9,  9,  9,
+    9,  9,  9,  9,  9,  9,  9,  9,  2,  9,  9,  9,  9,  9,  9,  9,
+   55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55,  6,  6,
+    6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  6,  1,  1,  6,  2,  4,
+    4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,
+    4,  4,  4,  4,  4,  2,  4,  4,  4,  2,  2,  4,  4,  4,  2, 14,
+   14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,  2,  2,
+    2,  2,  2,  2,  2,  2, 14, 14, 14,  2,  2,  2,  2, 14, 14, 14,
+   14, 14, 14,  2,  2,  2,  3,  3,  3,  3,  3,  0,  3,  3,  3,  3,
+    3,  3,  0,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,
+    3,  0,  3,  3,  3,  0,  0,  3,  3,  3,  3,  3,  3,  3,  3,  3,
+    3,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  1,  3,  3,  1,  3,
+    3,  3,  3,  3,  3,  3, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37,
+   37, 37, 37, 37,  2, 37, 37, 37, 37,  2,  2, 37, 37, 37, 38, 38,
+   38, 38, 38, 38, 38, 38, 38, 38,  2,  2,  2,  2,  2,  2, 64, 64,
+   64, 64, 64, 64, 64, 64, 64, 64, 64,  2,  2, 64, 64, 64, 90, 90,
+   90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90,  2,  2, 90, 90,
+   90, 90, 90, 90, 90,  2, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
+   95, 95,  2,  2, 95,  2, 37, 37, 37,  2,  2,  2,  2,  2,  3,  3,
+    3,  3,  3,  3,  3,  2,  3,  3,  2,  2,  2,  2,  2,  2,  3,  3,
+    0,  3,  3,  3,  3,  3,  7,  7,  7,  7,  7,  7,  7,  7,  7,  1,
+    1,  1,  1,  7,  7,  7,  7,  7,  7,  7,  0,  0,  7,  7,  5,  5,
+    5,  5,  2,  5,  5,  5,  5,  5,  5,  5,  5,  2,  2,  5,  5,  2,
+    2,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  2,
+    5,  5,  5,  5,  5,  5,  5,  2,  5,  2,  2,  2,  5,  5,  5,  5,
+    2,  2,  5,  5,  5,  5,  5,  2,  2,  5,  5,  5,  5,  2,  2,  2,
+    2,  2,  2,  2,  2,  5,  2,  2,  2,  2,  5,  5,  2,  5,  5,  5,
+    5,  5,  2,  2,  5,  5,  5,  5,  5,  5,  5,  5,  5,  2,  2, 11,
+   11, 11,  2, 11, 11, 11, 11, 11, 11,  2,  2,  2,  2, 11, 11,  2,
+    2, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,  2,
+   11, 11, 11, 11, 11, 11, 11,  2, 11, 11,  2, 11, 11,  2, 11, 11,
+    2,  2, 11,  2, 11, 11, 11,  2,  2, 11, 11, 11,  2,  2,  2, 11,
+    2,  2,  2,  2,  2,  2,  2, 11, 11, 11, 11,  2, 11,  2,  2,  2,
+    2,  2,  2,  2, 11, 11, 11, 11, 11, 11, 11, 11, 11,  2,  2, 10,
+   10, 10,  2, 10, 10, 10, 10, 10, 10, 10, 10, 10,  2, 10, 10, 10,
+    2, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,  2,
+   10, 10, 10, 10, 10, 10, 10,  2, 10, 10,  2, 10, 10, 10, 10, 10,
+    2,  2, 10, 10, 10, 10, 10, 10,  2, 10, 10, 10,  2,  2, 10,  2,
+    2,  2,  2,  2,  2,  2, 10, 10, 10, 10,  2,  2, 10, 10, 10, 10,
+    2,  2,  2,  2,  2,  2,  2, 10, 10, 10, 10, 10, 10, 10,  2, 21,
+   21, 21,  2, 21, 21, 21, 21, 21, 21, 21, 21,  2,  2, 21, 21,  2,
+    2, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,  2,
+   21, 21, 21, 21, 21, 21, 21,  2, 21, 21,  2, 21, 21, 21, 21, 21,
+    2,  2, 21, 21, 21, 21, 21,  2,  2, 21, 21, 21,  2,  2,  2,  2,
+    2,  2,  2, 21, 21, 21,  2,  2,  2,  2, 21, 21,  2, 21, 21, 21,
+   21, 21,  2,  2, 21, 21,  2,  2, 22, 22,  2, 22, 22, 22, 22, 22,
+   22,  2,  2,  2, 22, 22, 22,  2, 22, 22, 22, 22,  2,  2,  2, 22,
+   22,  2, 22,  2, 22, 22,  2,  2,  2, 22, 22,  2,  2,  2, 22, 22,
+   22, 22, 22, 22, 22, 22, 22, 22,  2,  2,  2,  2, 22, 22, 22,  2,
+    2,  2,  2,  2,  2, 22,  2,  2,  2,  2,  2,  2, 22, 22, 22, 22,
+   22,  2,  2,  2,  2,  2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+   23, 23, 23,  2, 23, 23, 23,  2, 23, 23, 23, 23, 23, 23, 23, 23,
+    2,  2, 23, 23, 23, 23, 23,  2, 23, 23, 23, 23,  2,  2,  2,  2,
+    2,  2,  2, 23, 23,  2, 23, 23, 23,  2,  2, 23,  2,  2, 23, 23,
+   23, 23,  2,  2, 23, 23,  2,  2,  2,  2,  2,  2,  2, 23, 16, 16,
+   16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,  2, 16, 16, 16,  2,
+   16, 16, 16, 16, 16, 16, 16, 16, 16, 16,  2, 16, 16, 16, 16, 16,
+    2,  2, 16, 16, 16, 16, 16,  2, 16, 16, 16, 16,  2,  2,  2,  2,
+    2,  2,  2, 16, 16,  2, 16, 16, 16, 16,  2,  2, 16, 16,  2, 16,
+   16, 16,  2,  2,  2,  2, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+   20, 20, 20,  2, 20, 20, 20,  2, 20, 20, 20, 20, 20, 20,  2,  2,
+    2,  2, 20, 20, 20, 20, 20, 20, 20, 20,  2,  2, 20, 20,  2, 36,
+   36, 36,  2, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,
+   36, 36, 36, 36, 36,  2,  2,  2, 36, 36, 36, 36, 36, 36, 36, 36,
+    2, 36, 36, 36, 36, 36, 36, 36, 36, 36,  2, 36,  2,  2,  2,  2,
+   36,  2,  2,  2,  2, 36, 36, 36, 36, 36, 36,  2, 36,  2,  2,  2,
+    2,  2,  2,  2, 36, 36,  2,  2, 36, 36, 36,  2,  2,  2,  2, 24,
+   24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+   24,  2,  2,  2,  2,  0, 24, 24, 24, 24,  2,  2,  2,  2,  2, 18,
+   18,  2, 18,  2, 18, 18, 18, 18, 18,  2, 18, 18, 18, 18, 18, 18,
+   18, 18, 18, 18, 18, 18, 18, 18, 18, 18,  2, 18,  2, 18, 18, 18,
+   18, 18, 18, 18,  2,  2, 18, 18, 18, 18, 18,  2, 18,  2, 18, 18,
+   18, 18, 18, 18, 18,  2, 18, 18,  2,  2, 18, 18, 18, 18, 25, 25,
+   25, 25, 25, 25, 25, 25,  2, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+   25, 25, 25,  2,  2,  2, 25, 25, 25, 25, 25,  2, 25, 25, 25, 25,
+   25, 25, 25,  0,  0,  0,  0, 25, 25,  2,  2,  2,  2,  2, 33, 33,
+   33, 33, 33, 33, 33, 33,  8,  8,  8,  8,  8,  8,  8,  8,  8,  8,
+    8,  8,  8,  8,  2,  8,  2,  2,  2,  2,  2,  8,  2,  2,  8,  8,
+    8,  0,  8,  8,  8,  8, 12, 12, 12, 12, 12, 12, 12, 12, 30, 30,
+   30, 30, 30, 30, 30, 30, 30,  2, 30, 30, 30, 30,  2,  2, 30, 30,
+   30, 30, 30, 30, 30,  2, 30, 30, 30,  2,  2, 30, 30, 30, 30, 30,
+   30, 30, 30,  2,  2,  2, 30, 30,  2,  2,  2,  2,  2,  2, 29, 29,
+   29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,  2,  2, 28, 28,
+   28, 28, 28, 28, 28, 28, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+   34, 34, 34,  2,  2,  2, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35,
+   35,  0,  0,  0, 35, 35, 35,  2,  2,  2,  2,  2,  2,  2, 45, 45,
+   45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,  2,  2,  2,  2,
+    2,  2,  2,  2,  2, 45, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44,
+   44, 44, 44,  0,  0,  2, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
+   43, 43,  2,  2,  2,  2, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
+   46, 46, 46,  2, 46, 46, 46,  2, 46, 46,  2,  2,  2,  2, 31, 31,
+   31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,  2,  2, 31, 31,
+    2,  2,  2,  2,  2,  2, 32, 32,  0,  0, 32,  0, 32, 32, 32, 32,
+   32, 32, 32, 32, 32, 32, 32, 32,  2,  2,  2,  2,  2,  2, 32,  2,
+    2,  2,  2,  2,  2,  2, 32, 32, 32,  2,  2,  2,  2,  2, 28, 28,
+   28, 28, 28, 28,  2,  2, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
+   48, 48, 48, 48, 48,  2, 48, 48, 48, 48,  2,  2,  2,  2, 48,  2,
+    2,  2, 48, 48, 48, 48, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52,
+   52, 52, 52, 52,  2,  2, 52, 52, 52, 52, 52,  2,  2,  2, 58, 58,
+   58, 58, 58, 58, 58, 58, 58, 58, 58, 58,  2,  2,  2,  2, 58, 58,
+    2,  2,  2,  2,  2,  2, 58, 58, 58,  2,  2,  2, 58, 58, 54, 54,
+   54, 54, 54, 54, 54, 54, 54, 54, 54, 54,  2,  2, 54, 54, 91, 91,
+   91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,  2, 91, 91,
+   91, 91, 91,  2,  2, 91, 91, 91,  2,  2,  2,  2,  2,  2, 91, 91,
+   91, 91, 91, 91,  2,  2,  1,  1,  1,  1,  1,  1,  1,  2, 62, 62,
+   62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62,  2,  2,  2, 62, 62,
+   62, 62, 62, 62, 62,  2, 76, 76, 76, 76, 76, 76, 76, 76, 93, 93,
+   93, 93, 93, 93, 93, 93, 93, 93, 93, 93,  2,  2,  2,  2,  2,  2,
+    2,  2, 93, 93, 93, 93, 70, 70, 70, 70, 70, 70, 70, 70,  2,  2,
+    2, 70, 70, 70, 70, 70, 70, 70,  2,  2,  2, 70, 70, 70, 73, 73,
+   73, 73, 73, 73, 73, 73,  6,  2,  2,  2,  2,  2,  2,  2,  8,  8,
+    8,  2,  2,  8,  8,  8,  1,  1,  1,  0,  1,  1,  1,  1,  1,  0,
+    1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  1,  0,  0,  0,  0,
+    0,  0,  1,  0,  0,  0,  1,  1,  0,  2,  2,  2,  2,  2, 19, 19,
+   19, 19, 19, 19,  9,  9,  9,  9,  9,  6, 19, 19, 19, 19, 19, 19,
+   19, 19, 19,  9,  9,  9,  9,  9, 19, 19, 19, 19,  9,  9,  9,  9,
+    9, 19, 19, 19, 19, 19,  6, 19, 19, 19, 19, 19, 19, 19, 19, 19,
+   19, 19, 19, 19, 19,  9,  9,  9,  9,  9,  9,  9,  2,  2,  2,  9,
+    2,  9,  2,  9,  2,  9,  9,  9,  9,  9,  9,  2,  9,  9,  9,  9,
+    9,  9,  2,  2,  9,  9,  9,  9,  9,  9,  2,  9,  9,  9,  2,  2,
+    9,  9,  9,  2,  9,  9,  9,  9,  9,  9,  9,  9,  9,  2,  0,  0,
+    0,  0,  1,  1,  0,  0,  0,  0,  0,  0,  0,  2,  0,  0,  0, 19,
+    2,  2,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 19,  0,  0,
+    0,  0,  0,  0,  0,  2, 19, 19, 19, 19, 19,  2,  2,  2,  0,  2,
+    2,  2,  2,  2,  2,  2,  1,  2,  2,  2,  2,  2,  2,  2,  0,  0,
+    0,  0,  0,  0,  9,  0,  0,  0, 19, 19,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0, 19,  0, 19,  0,  0,  0,  2,  2,  2,  2,  0,  0,
+    0,  2,  2,  2,  2,  2, 27, 27, 27, 27, 27, 27, 27, 27,  0,  0,
+    0,  0,  2,  2,  0,  0,  0,  0,  0,  0,  0,  0,  2,  0, 56, 56,
+   56, 56, 56, 56, 56, 56, 55, 55, 55, 55,  2,  2,  2,  2,  2, 55,
+   55, 55, 55, 55, 55, 55, 61, 61, 61, 61, 61, 61, 61, 61,  2,  2,
+    2,  2,  2,  2,  2, 61, 61,  2,  2,  2,  2,  2,  2,  2,  0,  0,
+    0,  0,  0,  0,  2,  2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+    2, 13, 13, 13, 13, 13, 13, 13, 13, 13,  2,  2,  2,  2, 13, 13,
+   13, 13, 13, 13,  2,  2,  0,  0,  0,  0,  0, 13,  0, 13,  0, 13,
    13, 13, 13, 13, 13, 13, 13, 13,  1,  1,  1,  1, 12, 12, 13, 13,
    13, 13,  0,  0,  0,  0,  2, 15, 15, 15, 15, 15, 15, 15, 15, 15,
    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,  2,  2,  1,
     1,  0,  0, 15, 15, 15,  0, 17, 17, 17, 17, 17, 17, 17, 17, 17,
    17, 17, 17, 17, 17, 17, 17, 17, 17,  0,  0, 17, 17, 17,  2,  2,
     2,  2,  2, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,  2, 12,
-   12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  2, 12, 12,
+   12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  2,  0,  0,
+    0,  0,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  2,  0, 12, 12,
    12, 12, 12, 12, 12,  0, 17, 17, 17, 17, 17, 17, 17,  0, 39, 39,
    39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,  2,  2,  2, 39, 39,
    39, 39, 39, 39, 39,  2, 86, 86, 86, 86, 86, 86, 86, 86, 77, 77,
@@ -2190,7 +2191,7 @@
     0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  3,  4,
 };
 static const uint16_t
-_hb_ucd_u16[9320] =
+_hb_ucd_u16[9344] =
 {
      0,   0,   1,   2,   3,   4,   5,   6,   0,   0,   7,   8,   9,  10,  11,  12,
     13,  13,  13,  14,  15,  13,  13,  16,  17,  18,  19,  20,  21,  22,  13,  23,
@@ -2233,9 +2234,9 @@
    209, 306, 209, 209, 209, 209, 209, 209,   9,   9,   9,  11,  11,  11, 307, 308,
     13,  13,  13,  13,  13,  13, 309, 310,  11,  11, 311,  48,  48,  48, 312, 313,
     48, 314, 315, 315, 315, 315,  32,  32, 316, 317, 318, 319, 320, 321, 140, 140,
-   209, 322, 209, 209, 209, 209, 209, 323, 209, 209, 209, 209, 209, 324, 140, 325,
-   326, 327, 328, 329, 136,  48,  48,  48,  48, 330, 178,  48,  48,  48,  48, 331,
-   332,  48,  48, 136,  48,  48,  48,  48, 200, 333,  48,  48, 209, 209, 323,  48,
+   209, 322, 209, 209, 209, 209, 209, 323, 209, 209, 209, 209, 209, 324, 140, 209,
+   325, 326, 327, 328, 136,  48,  48,  48,  48, 329, 178,  48,  48,  48,  48, 330,
+   331,  48,  48, 136,  48,  48,  48,  48, 200, 332,  48,  48, 209, 209, 333,  48,
    209, 334, 335, 209, 336, 337, 209, 209, 335, 209, 209, 337, 209, 209, 209, 209,
     48,  48,  48,  48, 209, 209, 209, 209,  48, 338,  48,  48,  48,  48,  48,  48,
    151, 209, 209, 209, 287,  48,  48, 229, 339,  48, 340, 140,  13,  13, 341, 342,
@@ -2306,475 +2307,476 @@
      9,   9, 607,  11, 654, 370, 140, 140, 140, 140, 140, 140, 140, 140, 140, 499,
    271, 271, 655, 656, 140, 140, 140, 140, 499, 271, 657, 658, 140, 140, 140, 140,
    659,  48, 660, 661, 662, 663, 664, 665, 666, 206, 667, 206, 140, 140, 140, 668,
-   209, 209, 325, 209, 209, 209, 209, 209, 209, 323, 334, 669, 669, 669, 209, 324,
-   670, 209, 209, 209, 209, 209, 209, 209, 209, 209, 671, 140, 140, 140, 672, 209,
-   673, 209, 209, 325, 674, 675, 324, 140, 209, 209, 209, 209, 209, 209, 209, 676,
-   209, 209, 209, 209, 209, 677, 426, 426, 209, 209, 209, 209, 209, 209, 209, 678,
-   209, 209, 209, 209, 209, 176, 325, 427, 325, 209, 209, 209, 679, 176, 209, 209,
-   679, 209, 671, 675, 140, 140, 140, 140, 209, 209, 209, 209, 209, 323, 671, 426,
-   674, 209, 209, 680, 681, 325, 674, 674, 209, 682, 209, 209, 288, 140, 140, 192,
+   209, 209, 669, 209, 209, 209, 209, 209, 209, 323, 334, 670, 670, 670, 209, 324,
+   671, 209, 209, 209, 209, 209, 209, 209, 209, 209, 672, 140, 140, 140, 673, 209,
+   674, 209, 209, 669, 675, 676, 324, 140, 209, 209, 209, 209, 209, 209, 209, 677,
+   209, 209, 209, 209, 209, 678, 426, 426, 209, 209, 209, 209, 209, 209, 209, 679,
+   209, 209, 209, 209, 209, 176, 669, 427, 669, 209, 209, 209, 680, 176, 209, 209,
+   680, 209, 672, 676, 140, 140, 140, 140, 209, 209, 209, 209, 209, 323, 672, 426,
+   675, 209, 209, 681, 682, 669, 675, 675, 209, 683, 209, 209, 288, 140, 140, 192,
     48,  48,  48,  48,  48,  48, 140, 140,  48,  48,  48, 207,  48,  48,  48,  48,
     48, 204,  48,  48,  48,  48,  48,  48,  48,  48, 478,  48,  48,  48,  48,  48,
-    48,  48,  48,  48,  48,  48, 100, 140,  48, 204, 140, 140, 140, 140, 140, 140,
-    48,  48,  48,  48,  71,  48,  48,  48,  48,  48,  48, 140, 140, 140, 140, 140,
-   683, 140, 570, 570, 570, 570, 570, 570,  32,  32,  32,  32,  32,  32,  32,  32,
-    32,  32,  32,  32,  32,  32,  32, 140, 391, 391, 391, 391, 391, 391, 391, 684,
-   391, 391, 391, 391, 391, 391, 391, 685,   0,   0,   0,   0,   0,   0,   0,   0,
-     1,   2,   2,   3,   1,   2,   2,   3,   0,   0,   0,   0,   0,   4,   0,   4,
-     2,   2,   5,   2,   2,   2,   5,   2,   2,   2,   2,   2,   2,   2,   2,   2,
-     2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   6,
-     0,   0,   0,   0,   7,   8,   0,   0,   9,   9,   9,   9,   9,   9,   9,   9,
-     9,   9,   9,   9,   9,   9,  10,  11,  12,  13,  14,  14,  15,  14,  14,  14,
-    14,  14,  14,  14,  16,  17,  14,  14,  18,  18,  18,  18,  18,  18,  18,  18,
-    18,  18,  18,  18,  18,  18,  18,  18,  19,  18,  18,  18,  18,  18,  18,  18,
-    18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  20,  21,
-    21,  21,  22,  20,  21,  21,  21,  21,  21,  23,  24,  25,  25,  25,  25,  25,
-    25,  26,  25,  25,  25,  27,  28,  26,  29,  30,  31,  32,  31,  31,  31,  31,
-    33,  34,  35,  31,  31,  31,  36,  31,  31,  31,  31,  31,  31,  31,  31,  31,
-    31,  31,  31,  29,  31,  31,  31,  31,  37,  38,  37,  37,  37,  37,  37,  37,
-    37,  39,  31,  31,  31,  31,  31,  31,  40,  40,  40,  40,  40,  40,  41,  26,
-    42,  42,  42,  42,  42,  42,  42,  43,  44,  44,  44,  44,  44,  45,  44,  46,
-    47,  47,  47,  48,  37,  49,  31,  31,  31,  50,  51,  31,  31,  31,  31,  31,
-    31,  31,  31,  31,  52,  31,  31,  31,  53,  53,  53,  53,  53,  53,  53,  53,
-    53,  53,  54,  53,  55,  53,  53,  53,  56,  57,  58,  59,  59,  60,  61,  62,
-    57,  63,  64,  65,  66,  59,  59,  67,  68,  69,  70,  71,  71,  72,  73,  74,
-    69,  75,  76,  77,  78,  71,  79,  26,  80,  81,  82,  83,  83,  84,  85,  86,
-    81,  87,  88,  26,  89,  83,  90,  91,  92,  93,  94,  95,  95,  96,  97,  98,
-    93,  99, 100, 101, 102,  95,  95,  26, 103, 104, 105, 106, 107, 104, 108, 109,
-   104, 105, 110,  26, 111, 108, 108, 112, 113, 114, 115, 113, 113, 115, 113, 116,
-   114, 117, 118, 119, 120, 113, 121, 113, 122, 123, 124, 122, 122, 124, 125, 126,
-   123, 127, 128, 128, 129, 122, 130,  26, 131, 132, 133, 131, 131, 131, 131, 131,
-   132, 133, 134, 131, 135, 131, 131, 131, 136, 137, 138, 139, 137, 137, 140, 141,
-   138, 142, 143, 137, 144, 137, 145,  26, 146, 147, 147, 147, 147, 147, 147, 148,
-   147, 147, 147, 149,  26,  26,  26,  26, 150, 151, 152, 152, 153, 152, 152, 154,
-   155, 156, 152, 157,  26,  26,  26,  26, 158, 158, 158, 158, 158, 158, 158, 158,
-   158, 159, 158, 158, 158, 160, 159, 158, 158, 158, 158, 159, 158, 158, 158, 161,
-   158, 161, 162, 163,  26,  26,  26,  26, 164, 164, 164, 164, 164, 164, 164, 164,
-   164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 165, 165, 165, 165,
-   166, 167, 165, 165, 165, 165, 165, 168, 169, 169, 169, 169, 169, 169, 169, 169,
-   169, 169, 169, 169, 169, 169, 169, 169, 170, 170, 170, 170, 170, 170, 170, 170,
-   170, 171, 172, 171, 170, 170, 170, 170, 170, 171, 170, 170, 170, 170, 171, 172,
-   171, 170, 172, 170, 170, 170, 170, 170, 170, 170, 171, 170, 170, 170, 170, 170,
-   170, 170, 170, 173, 170, 170, 170, 174, 170, 170, 170, 175, 176, 176, 176, 176,
-   176, 176, 176, 176, 176, 176, 177, 177, 178, 178, 178, 178, 178, 178, 178, 178,
-   178, 178, 178, 178, 178, 178, 178, 178, 179, 179, 179, 180, 181, 181, 181, 181,
-   181, 181, 181, 181, 181, 182, 181, 183, 184, 184, 185, 186, 187, 187, 188,  26,
-   189, 189, 190,  26, 191, 192, 193,  26, 194, 194, 194, 194, 194, 194, 194, 194,
-   194, 194, 194, 195, 194, 196, 194, 196, 197, 198, 198, 199, 198, 198, 198, 198,
-   198, 198, 198, 198, 198, 198, 198, 200, 198, 198, 198, 198, 198, 201, 178, 178,
-   178, 178, 178, 178, 178, 178, 202,  26, 203, 203, 203, 204, 203, 205, 203, 205,
-   206, 203, 207, 207, 207, 208, 209,  26, 210, 210, 210, 210, 210, 211, 210, 210,
-   210, 212, 210, 213, 194, 194, 194, 194, 214, 214, 214, 215, 216, 216, 216, 216,
-   216, 216, 216, 217, 216, 216, 216, 218, 216, 219, 216, 219, 216, 220,   9,   9,
-     9, 221,  26,  26,  26,  26,  26,  26, 222, 222, 222, 222, 222, 222, 222, 222,
-   222, 223, 222, 222, 222, 222, 222, 224, 225, 225, 225, 225, 225, 225, 225, 225,
-   226, 226, 226, 226, 226, 226, 227, 228, 229, 229, 229, 229, 229, 229, 229, 230,
-   229, 231, 232, 232, 232, 232, 232, 232,  18, 233, 165, 165, 165, 165, 165, 234,
-   225,  26, 235,   9, 236, 237, 238, 239,   2,   2,   2,   2, 240, 241,   2,   2,
-     2,   2,   2, 242, 243, 244,   2, 245,   2,   2,   2,   2,   2,   2,   2, 246,
-     9,   9,   9,   9,   9,   9,   9,   9,  14,  14, 247, 247,  14,  14,  14,  14,
-   247, 247,  14, 248,  14,  14,  14, 247,  14,  14,  14,  14,  14,  14, 249,  14,
-   249,  14, 250, 251,  14,  14, 252, 253,   0, 254,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0, 255,   0, 256, 257,   0, 258,   2, 259,   0,   0,   0,   0,
-   260,  26,   9,   9,   9,   9, 261,  26,   0,   0,   0,   0, 262, 263,   4,   0,
-     0, 264,   0,   0,   2,   2,   2,   2,   2, 265,   0,   0,   0,   0,   0,   0,
+    48,  48,  48,  48,  48,  48, 100,  48,  48,  48,  48,  48,  48, 204, 140, 140,
+    48, 204, 140, 140, 140, 140, 140, 140,  48,  48,  48,  48,  71,  48,  48,  48,
+    48,  48,  48, 140, 140, 140, 140, 140, 684, 140, 570, 570, 570, 570, 570, 570,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32, 140,
+   391, 391, 391, 391, 391, 391, 391, 685, 391, 391, 391, 391, 391, 391, 391, 686,
+     0,   0,   0,   0,   0,   0,   0,   0,   1,   2,   2,   3,   1,   2,   2,   3,
+     0,   0,   0,   0,   0,   4,   0,   4,   2,   2,   5,   2,   2,   2,   5,   2,
+     2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,
+     2,   2,   2,   2,   2,   2,   2,   6,   0,   0,   0,   0,   7,   8,   0,   0,
+     9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,  10,  11,
+    12,  13,  14,  14,  15,  14,  14,  14,  14,  14,  14,  14,  16,  17,  14,  14,
+    18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,
+    19,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,
+    18,  18,  18,  18,  18,  18,  20,  21,  21,  21,  22,  20,  21,  21,  21,  21,
+    21,  23,  24,  25,  25,  25,  25,  25,  25,  26,  25,  25,  25,  27,  28,  26,
+    29,  30,  31,  32,  31,  31,  31,  31,  33,  34,  35,  31,  31,  31,  36,  31,
+    31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  29,  31,  31,  31,  31,
+    37,  38,  37,  37,  37,  37,  37,  37,  37,  39,  31,  31,  31,  31,  31,  31,
+    40,  40,  40,  40,  40,  40,  41,  26,  42,  42,  42,  42,  42,  42,  42,  43,
+    44,  44,  44,  44,  44,  45,  44,  46,  47,  47,  47,  48,  37,  49,  31,  31,
+    31,  50,  51,  31,  31,  31,  31,  31,  31,  31,  31,  31,  52,  31,  31,  31,
+    53,  53,  53,  53,  53,  53,  53,  53,  53,  53,  54,  53,  55,  53,  53,  53,
+    56,  57,  58,  59,  59,  60,  61,  62,  57,  63,  64,  65,  66,  59,  59,  67,
+    68,  69,  70,  71,  71,  72,  73,  74,  69,  75,  76,  77,  78,  71,  79,  26,
+    80,  81,  82,  83,  83,  84,  85,  86,  81,  87,  88,  26,  89,  83,  90,  91,
+    92,  93,  94,  95,  95,  96,  97,  98,  93,  99, 100, 101, 102,  95,  95,  26,
+   103, 104, 105, 106, 107, 104, 108, 109, 104, 105, 110,  26, 111, 108, 108, 112,
+   113, 114, 115, 113, 113, 115, 113, 116, 114, 117, 118, 119, 120, 113, 121, 113,
+   122, 123, 124, 122, 122, 124, 125, 126, 123, 127, 128, 128, 129, 122, 130,  26,
+   131, 132, 133, 131, 131, 131, 131, 131, 132, 133, 134, 131, 135, 131, 131, 131,
+   136, 137, 138, 139, 137, 137, 140, 141, 138, 142, 143, 137, 144, 137, 145,  26,
+   146, 147, 147, 147, 147, 147, 147, 148, 147, 147, 147, 149,  26,  26,  26,  26,
+   150, 151, 152, 152, 153, 152, 152, 154, 155, 156, 152, 157,  26,  26,  26,  26,
+   158, 158, 158, 158, 158, 158, 158, 158, 158, 159, 158, 158, 158, 160, 159, 158,
+   158, 158, 158, 159, 158, 158, 158, 161, 158, 161, 162, 163,  26,  26,  26,  26,
+   164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164,
+   164, 164, 164, 164, 165, 165, 165, 165, 166, 167, 165, 165, 165, 165, 165, 168,
+   169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169,
+   170, 170, 170, 170, 170, 170, 170, 170, 170, 171, 172, 171, 170, 170, 170, 170,
+   170, 171, 170, 170, 170, 170, 171, 172, 171, 170, 172, 170, 170, 170, 170, 170,
+   170, 170, 171, 170, 170, 170, 170, 170, 170, 170, 170, 173, 170, 170, 170, 174,
+   170, 170, 170, 175, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 177, 177,
+   178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178,
+   179, 179, 179, 180, 181, 181, 181, 181, 181, 181, 181, 181, 181, 182, 181, 183,
+   184, 184, 185, 186, 187, 187, 188,  26, 189, 189, 190,  26, 191, 192, 193,  26,
+   194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 195, 194, 196, 194, 196,
+   197, 198, 198, 199, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 200,
+   198, 198, 198, 198, 198, 201, 178, 178, 178, 178, 178, 178, 178, 178, 202,  26,
+   203, 203, 203, 204, 203, 205, 203, 205, 206, 203, 207, 207, 207, 208, 209,  26,
+   210, 210, 210, 210, 210, 211, 210, 210, 210, 212, 210, 213, 194, 194, 194, 194,
+   214, 214, 214, 215, 216, 216, 216, 216, 216, 216, 216, 217, 216, 216, 216, 218,
+   216, 219, 216, 219, 216, 220,   9,   9,   9, 221,  26,  26,  26,  26,  26,  26,
+   222, 222, 222, 222, 222, 222, 222, 222, 222, 223, 222, 222, 222, 222, 222, 224,
+   225, 225, 225, 225, 225, 225, 225, 225, 226, 226, 226, 226, 226, 226, 227, 228,
+   229, 229, 229, 229, 229, 229, 229, 230, 229, 231, 232, 232, 232, 232, 232, 232,
+    18, 233, 165, 165, 165, 165, 165, 234, 225,  26, 235,   9, 236, 237, 238, 239,
+     2,   2,   2,   2, 240, 241,   2,   2,   2,   2,   2, 242, 243, 244,   2, 245,
+     2,   2,   2,   2,   2,   2,   2, 246,   9,   9,   9,   9,   9,   9,   9,   9,
+    14,  14, 247, 247,  14,  14,  14,  14, 247, 247,  14, 248,  14,  14,  14, 247,
+    14,  14,  14,  14,  14,  14, 249,  14, 249,  14, 250, 251,  14,  14, 252, 253,
+     0, 254,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 255,   0, 256, 257,
+     0, 258,   2, 259,   0,   0,   0,   0, 260,  26,   9,   9,   9,   9, 261,  26,
+     0,   0,   0,   0, 262, 263,   4,   0,   0, 264,   0,   0,   2,   2,   2,   2,
+     2, 265,   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, 258,  26,  26,  26,
-     0, 266,  26,  26,   0,   0,   0,   0, 267, 267, 267, 267, 267, 267, 267, 267,
-   267, 267, 267, 267, 267, 267, 267, 267,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0, 268,   0,   0,   0, 269,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0, 270, 270, 270, 270, 270, 270, 270, 270,
-   270, 270, 270, 270,   2,   2,   2,   2,  17,  17,  17,  17,  17,  17,  17,  17,
-    17,  17,  17,  17,  17,  17, 271, 272, 165, 165, 165, 165, 166, 167, 273, 273,
-   273, 273, 273, 273, 273, 274, 275, 274, 170, 170, 172,  26, 172, 172, 172, 172,
-   172, 172, 172, 172,  18,  18,  18,  18,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0, 276,  26,  26,  26,  26, 277, 277, 277, 278, 277, 277, 277, 277,
-   277, 277, 277, 277, 277, 277, 279,  26, 277, 277, 277, 277, 277, 277, 277, 277,
+     0,   0,   0,   0, 258,  26,  26,  26,   0, 266,  26,  26,   0,   0,   0,   0,
+   267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 268,   0,
+     0,   0, 269,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+   270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270,   2,   2,   2,   2,
+    17,  17,  17,  17,  17,  17,  17,  17,  17,  17,  17,  17,  17,  17, 271, 272,
+   165, 165, 165, 165, 166, 167, 273, 273, 273, 273, 273, 273, 273, 274, 275, 274,
+   170, 170, 172,  26, 172, 172, 172, 172, 172, 172, 172, 172,  18,  18,  18,  18,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 276,  26,  26,  26,  26,
+   277, 277, 277, 278, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 279,  26,
    277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
-   277, 277, 280,  26,  26,  26,   0, 281, 282,   0,   0,   0, 283, 284,   0, 285,
-   286, 287, 287, 287, 287, 287, 287, 287, 287, 287, 288, 289, 290, 291, 291, 291,
-   291, 291, 291, 291, 291, 291, 291, 292, 293, 294, 294, 294, 294, 294, 295, 169,
-   169, 169, 169, 169, 169, 169, 169, 169, 169, 296,   0,   0, 294, 294, 294, 294,
-     0,   0,   0,   0, 281,  26, 291, 291, 169, 169, 169, 296,   0,   0,   0,   0,
-     0,   0,   0,   0, 169, 169, 169, 297,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0, 291, 291, 291, 291, 291, 298, 291, 291, 291, 291, 291, 291, 291, 291,
-   291, 291, 291,   0,   0,   0,   0,   0, 277, 277, 277, 277, 277, 277, 277, 277,
-     0,   0,   0,   0,   0,   0,   0,   0, 299, 299, 299, 299, 299, 299, 299, 299,
-   299, 299, 299, 299, 299, 299, 299, 299, 299, 300, 299, 299, 299, 299, 299, 299,
-   301,  26, 302, 302, 302, 302, 302, 302, 303, 303, 303, 303, 303, 303, 303, 303,
-   303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 304,  26,  26,
-    18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18,  18, 305, 305, 305, 305,
-   305, 305, 305, 305, 305, 305, 305,  26,   0,   0,   0,   0, 306,   2,   2,   2,
-     2,   2,   2,   2,   2,   2,   2,   2,   2, 307,   2,   2,   2,   2,   2,   2,
-     2, 308, 309, 310,  26,  26, 311,   2, 312, 312, 312, 312, 312, 313,   0, 314,
-   315, 315, 315, 315, 315, 315, 315,  26, 316, 316, 316, 316, 316, 316, 316, 316,
-   317, 318, 316, 319,  53,  53,  53,  53, 320, 320, 320, 320, 320, 321, 322, 322,
-   322, 322, 323, 324, 169, 169, 169, 325, 326, 326, 326, 326, 326, 326, 326, 326,
-   326, 327, 326, 328, 164, 164, 164, 329, 330, 330, 330, 330, 330, 330, 331,  26,
-   330, 332, 330, 333, 164, 164, 164, 164, 334, 334, 334, 334, 334, 334, 334, 334,
-   335,  26,  26, 336, 337, 337, 338,  26, 339, 339, 339,  26, 172, 172,   2,   2,
-     2,   2,   2, 340, 341, 342, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176,
-   337, 337, 337, 337, 337, 343, 337, 344, 169, 169, 169, 169, 345,  26, 169, 169,
-   296, 346, 169, 169, 169, 169, 169, 345,  26,  26,  26,  26,  26,  26,  26,  26,
-    26,  26,  26,  26,  26,  26,  26,  26, 277, 277, 277, 277, 277, 277, 277, 277,
-   277, 277, 277, 277, 277, 280, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
-   277, 277, 277, 347,  26,  26,  26,  26, 348,  26, 349, 350,  25,  25, 351, 352,
-   353,  25,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,
-   354,  26, 355,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,
-    31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31, 356,
-    31,  31,  31,  31,  31,  31,  31,  31,  31,  31, 357,  31,  31,  31,  31,  31,
-    31, 358,  26,  26,  26,  26,  31,  31,   9,   9,   0, 314,   9, 359,   0,   0,
-     0,   0, 360,   0, 258, 281, 361,  31,  31,  31,  31,  31,  31,  31,  31,  31,
-    31,  31,  31,  31,  31,  31,  31, 362, 363,   0,   0,   0,   1,   2,   2,   3,
-     1,   2,   2,   3, 364, 291, 290, 291, 291, 291, 291, 365, 169, 169, 169, 296,
-   366, 366, 366, 367, 258, 258,  26, 368, 369, 370, 369, 369, 371, 369, 369, 372,
-   369, 373, 369, 373,  26,  26,  26,  26, 369, 369, 369, 369, 369, 369, 369, 369,
-   369, 369, 369, 369, 369, 369, 369, 374, 375,   0,   0,   0,   0,   0, 376,   0,
-    14,  14,  14,  14,  14,  14,  14,  14,  14, 253,   0, 377, 378,  26,  26,  26,
-    26,  26,   0,   0,   0,   0,   0, 379, 380, 380, 380, 381, 382, 382, 382, 382,
-   382, 382, 383,  26, 384,   0,   0, 281, 385, 385, 385, 385, 386, 387, 388, 388,
-   388, 389, 390, 390, 390, 390, 390, 391, 392, 392, 392, 393, 394, 394, 394, 394,
-   395, 394, 396,  26,  26,  26,  26,  26, 397, 397, 397, 397, 397, 397, 397, 397,
-   397, 397, 398, 398, 398, 398, 398, 398, 399, 399, 399, 400, 399, 401, 402, 402,
-   402, 402, 403, 402, 402, 402, 402, 403, 404, 404, 404, 404, 404,  26, 405, 405,
-   405, 405, 405, 405, 406, 407, 408, 409, 408, 409, 410, 408, 411, 408, 411, 412,
-    26,  26,  26,  26,  26,  26,  26,  26, 413, 413, 413, 413, 413, 413, 413, 413,
-   413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 414,  26,
-   413, 413, 415,  26, 413,  26,  26,  26, 416,   2,   2,   2,   2,   2, 417, 308,
-    26,  26,  26,  26,  26,  26,  26,  26, 418, 419, 420, 420, 420, 420, 421, 422,
-   423, 423, 424, 423, 425, 425, 425, 425, 426, 426, 426, 427, 428, 426,  26,  26,
-    26,  26,  26,  26, 429, 429, 430, 431, 432, 432, 432, 433, 434, 434, 434, 435,
-    26,  26,  26,  26,  26,  26,  26,  26, 436, 436, 436, 436, 437, 437, 437, 438,
-   437, 437, 439, 437, 437, 437, 437, 437, 440, 441, 442, 443, 444, 444, 445, 446,
-   444, 447, 444, 447, 448, 448, 448, 448, 449, 449, 449, 449,  26,  26,  26,  26,
-   450, 450, 450, 450, 451, 452, 451,  26, 453, 453, 453, 453, 453, 453, 454, 455,
-   456, 456, 457, 456, 458, 458, 459, 458, 460, 460, 461, 462,  26, 463,  26,  26,
-    26,  26,  26,  26,  26,  26,  26,  26, 464, 464, 464, 464, 464, 464, 464, 464,
-   464, 465,  26,  26,  26,  26,  26,  26, 466, 466, 466, 466, 466, 466, 467,  26,
-   466, 466, 466, 466, 466, 466, 467, 468, 469, 469, 469, 469, 469,  26, 469, 470,
+   277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 280,  26,  26,  26,   0,   0,
+   281,   0,   0,   0, 282, 283,   0, 284, 285, 286, 286, 286, 286, 286, 286, 286,
+   286, 286, 287, 288, 289, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 291,
+   292, 293, 293, 293, 293, 293, 294, 169, 169, 169, 169, 169, 169, 169, 169, 169,
+   169, 295,   0,   0, 293, 293, 293, 293,   0,   0,   0,   0, 296, 297, 290, 290,
+   169, 169, 169, 295,   0,   0,   0,   0,   0,   0,   0,   0, 169, 169, 169, 298,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 290, 290, 290, 290, 290, 299,
+   290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290,   0,   0,   0,   0,   0,
+   277, 277, 277, 277, 277, 277, 277, 277,   0,   0,   0,   0,   0,   0,   0,   0,
+   300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300,
+   300, 301, 300, 300, 300, 300, 300, 300, 302,  26, 303, 303, 303, 303, 303, 303,
+   304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304,
+   304, 304, 304, 304, 304, 305,  26,  26,  18,  18,  18,  18,  18,  18,  18,  18,
+    18,  18,  18,  18, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306,  26,
+     0,   0,   0,   0, 307,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,   2,
+     2, 308,   2,   2,   2,   2,   2,   2,   2, 309, 310, 311,  26,  26, 312,   2,
+   313, 313, 313, 313, 313, 314,   0, 315, 316, 316, 316, 316, 316, 316, 316,  26,
+   317, 317, 317, 317, 317, 317, 317, 317, 318, 319, 317, 320,  53,  53,  53,  53,
+   321, 321, 321, 321, 321, 322, 323, 323, 323, 323, 324, 325, 169, 169, 169, 326,
+   327, 327, 327, 327, 327, 327, 327, 327, 327, 328, 327, 329, 164, 164, 164, 330,
+   331, 331, 331, 331, 331, 331, 332,  26, 331, 333, 331, 334, 164, 164, 164, 164,
+   335, 335, 335, 335, 335, 335, 335, 335, 336,  26,  26, 337, 338, 338, 339,  26,
+   340, 340, 340,  26, 172, 172,   2,   2,   2,   2,   2, 341, 342, 343, 176, 176,
+   176, 176, 176, 176, 176, 176, 176, 176, 338, 338, 338, 338, 338, 344, 338, 345,
+   169, 169, 169, 169, 346,  26, 169, 169, 295, 347, 169, 169, 169, 169, 169, 346,
     26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
-    26,  26,  26,  26,  31,  31,  31,  50, 471, 471, 471, 471, 471, 472, 473,  26,
-    26,  26,  26,  26,  26,  26,  26, 474, 475, 475, 475, 475, 475,  26, 476, 476,
-   476, 476, 476, 477,  26,  26, 478, 478, 478, 479,  26,  26,  26,  26, 480, 480,
-   480, 481,  26,  26, 482, 482, 483,  26, 484, 484, 484, 484, 484, 484, 484, 484,
-   484, 485, 486, 484, 484, 484, 485, 487, 488, 488, 488, 488, 488, 488, 488, 488,
-   489, 490, 491, 491, 491, 492, 491, 493, 494, 494, 494, 494, 494, 494, 495, 494,
-   494,  26, 496, 496, 496, 496, 497,  26, 498, 498, 498, 498, 498, 498, 498, 498,
-   498, 498, 498, 498, 499, 137, 500,  26, 501, 501, 502, 501, 501, 501, 501, 501,
-   503,  26,  26,  26,  26,  26,  26,  26, 504, 505, 506, 507, 506, 508, 509, 509,
-   509, 509, 509, 509, 509, 510, 509, 511, 512, 513, 514, 515, 515, 516, 517, 518,
-   513, 519, 520, 521, 522, 523, 523,  26, 524, 524, 524, 524, 524, 524, 524, 524,
-   524, 524, 524, 525, 526,  26,  26,  26, 527, 527, 527, 527, 527, 527, 527, 527,
-   527,  26, 527, 528,  26,  26,  26,  26, 529, 529, 529, 529, 529, 529, 530, 529,
-   529, 529, 529, 530,  26,  26,  26,  26, 531, 531, 531, 531, 531, 531, 531, 531,
-   532,  26, 531, 533, 198, 534,  26,  26, 535, 535, 535, 535, 535, 535, 535, 536,
-   535, 536,  26,  26,  26,  26,  26,  26, 537, 537, 537, 538, 537, 539, 537, 537,
-   540,  26,  26,  26,  26,  26,  26,  26, 541, 541, 541, 541, 541, 541, 541, 542,
-    26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26, 543, 543, 543, 543,
-   543, 543, 543, 543, 543, 543, 544, 545, 546, 547, 548, 549, 549, 549, 550, 551,
-   546,  26, 549, 552,  26,  26,  26,  26,  26,  26,  26,  26, 553, 554, 553, 553,
-   553, 553, 553, 554, 555,  26,  26,  26, 556, 556, 556, 556, 556, 556, 556, 556,
-   556,  26, 557, 557, 557, 557, 557, 557, 557, 557, 557, 557, 558,  26, 178, 178,
-   559, 559, 559, 559, 559, 559, 559, 560,  53, 561,  26,  26,  26,  26,  26,  26,
-    26,  26,  26,  26,  26,  26,  26,  26, 562, 563, 562, 562, 562, 562, 564, 562,
-   565,  26, 562, 562, 562, 566, 567, 567, 567, 567, 568, 567, 567, 569, 570,  26,
-    26,  26,  26,  26,  26,  26,  26,  26, 571, 572, 573, 573, 573, 573, 571, 574,
-   573,  26, 573, 575, 576, 577, 578, 578, 578, 579, 580, 581, 578, 582,  26,  26,
-    26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
-    26,  26,  26,  26, 583, 583, 583, 584, 585, 585, 586, 585, 585, 585, 585, 587,
-   585, 585, 585, 588,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26, 589,  26,
-   108, 108, 108, 108, 108, 108, 590, 591, 592, 592, 592, 592, 592, 592, 592, 592,
-   592, 592, 592, 592, 592, 592, 592, 592, 592, 592, 592, 593,  26,  26,  26,  26,
-    26,  26,  26,  26,  26,  26,  26,  26, 592, 592, 592, 592, 592, 592, 592, 592,
-   592, 592, 592, 592, 592, 594, 595,  26, 592, 592, 592, 592, 592, 592, 592, 592,
-   596,  26,  26,  26,  26,  26,  26,  26,  26,  26, 597, 597, 597, 597, 597, 597,
-   597, 597, 597, 597, 597, 597, 598,  26, 599, 599, 599, 599, 599, 599, 599, 599,
-   599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599,
-   599, 599, 600,  26,  26,  26,  26,  26, 601, 601, 601, 601, 601, 601, 601, 601,
-   601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601,
-   602,  26,  26,  26,  26,  26,  26,  26, 305, 305, 305, 305, 305, 305, 305, 305,
-   305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 603,
-   604, 604, 604, 605, 604, 606, 607, 607, 607, 607, 607, 607, 607, 607, 607, 608,
-   607, 609, 610, 610, 610, 611, 611,  26, 612, 612, 612, 612, 612, 612, 612, 612,
-   613,  26, 612, 614, 614, 612, 612, 615, 612, 612,  26,  26,  26,  26,  26,  26,
-    26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
-   616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 617,  26,  26,  26,  26,
-    26,  26,  26,  26,  26,  26,  26,  26, 618, 618, 618, 618, 618, 618, 618, 618,
-   618, 619, 618, 618, 618, 618, 618, 618, 618, 620, 618, 618,  26,  26,  26,  26,
-    26,  26,  26,  26, 621,  26, 347,  26, 622, 622, 622, 622, 622, 622, 622, 622,
-   622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622,
-   622, 622, 622, 622, 622, 622, 622,  26, 623, 623, 623, 623, 623, 623, 623, 623,
+   277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 280, 277, 277,
+   277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 348,  26,  26,  26,  26,
+   349,  26, 350, 351,  25,  25, 352, 353, 354,  25,  31,  31,  31,  31,  31,  31,
+    31,  31,  31,  31,  31,  31,  31,  31, 355,  26, 356,  31,  31,  31,  31,  31,
+    31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,
+    31,  31,  31,  31,  31,  31,  31, 357,  31,  31,  31,  31,  31,  31,  31,  31,
+    31,  31, 358,  31,  31,  31,  31,  31,  31, 359,  26,  26,  26,  26,  31,  31,
+     9,   9,   0, 315,   9, 360,   0,   0,   0,   0, 361,   0, 258, 296, 362,  31,
+    31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31,  31, 363,
+   364,   0,   0,   0,   1,   2,   2,   3,   1,   2,   2,   3, 365, 290, 289, 290,
+   290, 290, 290, 366, 169, 169, 169, 295, 367, 367, 367, 368, 258, 258,  26, 369,
+   370, 371, 370, 370, 372, 370, 370, 373, 370, 374, 370, 374,  26,  26,  26,  26,
+   370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 375,
+   376,   0,   0,   0,   0,   0, 377,   0,  14,  14,  14,  14,  14,  14,  14,  14,
+    14, 253,   0, 378, 379,  26,  26,  26,  26,  26,   0,   0,   0,   0,   0, 380,
+   381, 381, 381, 382, 383, 383, 383, 383, 383, 383, 384,  26, 385,   0,   0, 296,
+   386, 386, 386, 386, 387, 388, 389, 389, 389, 390, 391, 391, 391, 391, 391, 392,
+   393, 393, 393, 394, 395, 395, 395, 395, 396, 395, 397,  26,  26,  26,  26,  26,
+   398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 399, 399, 399, 399, 399, 399,
+   400, 400, 400, 401, 400, 402, 403, 403, 403, 403, 404, 403, 403, 403, 403, 404,
+   405, 405, 405, 405, 405,  26, 406, 406, 406, 406, 406, 406, 407, 408, 409, 410,
+   409, 410, 411, 409, 412, 409, 412, 413,  26,  26,  26,  26,  26,  26,  26,  26,
+   414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414,
+   414, 414, 414, 414, 414, 414, 415,  26, 414, 414, 416,  26, 414,  26,  26,  26,
+   417,   2,   2,   2,   2,   2, 418, 309,  26,  26,  26,  26,  26,  26,  26,  26,
+   419, 420, 421, 421, 421, 421, 422, 423, 424, 424, 425, 424, 426, 426, 426, 426,
+   427, 427, 427, 428, 429, 427,  26,  26,  26,  26,  26,  26, 430, 430, 431, 432,
+   433, 433, 433, 434, 435, 435, 435, 436,  26,  26,  26,  26,  26,  26,  26,  26,
+   437, 437, 437, 437, 438, 438, 438, 439, 438, 438, 440, 438, 438, 438, 438, 438,
+   441, 442, 443, 444, 445, 445, 446, 447, 445, 448, 445, 448, 449, 449, 449, 449,
+   450, 450, 450, 450,  26,  26,  26,  26, 451, 451, 451, 451, 452, 453, 452,  26,
+   454, 454, 454, 454, 454, 454, 455, 456, 457, 457, 458, 457, 459, 459, 460, 459,
+   461, 461, 462, 463,  26, 464,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+   465, 465, 465, 465, 465, 465, 465, 465, 465, 466,  26,  26,  26,  26,  26,  26,
+   467, 467, 467, 467, 467, 467, 468,  26, 467, 467, 467, 467, 467, 467, 468, 469,
+   470, 470, 470, 470, 470,  26, 470, 471,  26,  26,  26,  26,  26,  26,  26,  26,
+    26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  31,  31,  31,  50,
+   472, 472, 472, 472, 472, 473, 474,  26,  26,  26,  26,  26,  26,  26,  26, 475,
+   476, 476, 476, 476, 476,  26, 477, 477, 477, 477, 477, 478,  26,  26, 479, 479,
+   479, 480,  26,  26,  26,  26, 481, 481, 481, 482,  26,  26, 483, 483, 484,  26,
+   485, 485, 485, 485, 485, 485, 485, 485, 485, 486, 487, 485, 485, 485, 486, 488,
+   489, 489, 489, 489, 489, 489, 489, 489, 490, 491, 492, 492, 492, 493, 492, 494,
+   495, 495, 495, 495, 495, 495, 496, 495, 495,  26, 497, 497, 497, 497, 498,  26,
+   499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 500, 137, 501,  26,
+   502, 502, 503, 502, 502, 502, 502, 502, 504,  26,  26,  26,  26,  26,  26,  26,
+   505, 506, 507, 508, 507, 509, 510, 510, 510, 510, 510, 510, 510, 511, 510, 512,
+   513, 514, 515, 516, 516, 517, 518, 519, 514, 520, 521, 522, 523, 524, 524,  26,
+   525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 526, 527,  26,  26,  26,
+   528, 528, 528, 528, 528, 528, 528, 528, 528,  26, 528, 529,  26,  26,  26,  26,
+   530, 530, 530, 530, 530, 530, 531, 530, 530, 530, 530, 531,  26,  26,  26,  26,
+   532, 532, 532, 532, 532, 532, 532, 532, 533,  26, 532, 534, 198, 535,  26,  26,
+   536, 536, 536, 536, 536, 536, 536, 537, 536, 537,  26,  26,  26,  26,  26,  26,
+   538, 538, 538, 539, 538, 540, 538, 538, 541,  26,  26,  26,  26,  26,  26,  26,
+   542, 542, 542, 542, 542, 542, 542, 543,  26,  26,  26,  26,  26,  26,  26,  26,
+    26,  26,  26,  26, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 545, 546,
+   547, 548, 549, 550, 550, 550, 551, 552, 547,  26, 550, 553,  26,  26,  26,  26,
+    26,  26,  26,  26, 554, 555, 554, 554, 554, 554, 554, 555, 556,  26,  26,  26,
+   557, 557, 557, 557, 557, 557, 557, 557, 557,  26, 558, 558, 558, 558, 558, 558,
+   558, 558, 558, 558, 559,  26, 178, 178, 560, 560, 560, 560, 560, 560, 560, 561,
+    53, 562,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+   563, 564, 563, 563, 563, 563, 565, 563, 566,  26, 563, 563, 563, 567, 568, 568,
+   568, 568, 569, 568, 568, 570, 571,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+   572, 573, 574, 574, 574, 574, 572, 575, 574,  26, 574, 576, 577, 578, 579, 579,
+   579, 580, 581, 582, 579, 583,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+    26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26, 584, 584, 584, 585,
+   586, 586, 587, 586, 586, 586, 586, 588, 586, 586, 586, 589,  26,  26,  26,  26,
+    26,  26,  26,  26,  26,  26, 590,  26, 108, 108, 108, 108, 108, 108, 591, 592,
+   593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593,
+   593, 593, 593, 594,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+   593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 595, 596,  26,
+   593, 593, 593, 593, 593, 593, 593, 593, 597,  26,  26,  26,  26,  26,  26,  26,
+    26,  26, 598, 598, 598, 598, 598, 598, 598, 598, 598, 598, 598, 598, 599,  26,
+   600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600,
+   600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 601,  26,  26,  26,  26,  26,
+   602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602,
+   602, 602, 602, 602, 602, 602, 602, 602, 603,  26,  26,  26,  26,  26,  26,  26,
+   306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306,
+   306, 306, 306, 306, 306, 306, 306, 604, 605, 605, 605, 606, 605, 607, 608, 608,
+   608, 608, 608, 608, 608, 608, 608, 609, 608, 610, 611, 611, 611, 612, 612,  26,
+   613, 613, 613, 613, 613, 613, 613, 613, 614,  26, 613, 615, 615, 613, 613, 616,
+   613, 613,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+    26,  26,  26,  26,  26,  26,  26,  26, 617, 617, 617, 617, 617, 617, 617, 617,
+   617, 617, 617, 618,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+   619, 619, 619, 619, 619, 619, 619, 619, 619, 620, 619, 619, 619, 619, 619, 619,
+   619, 621, 619, 619,  26,  26,  26,  26,  26,  26,  26,  26, 622,  26, 348,  26,
    623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623,
-   623, 623, 624,  26,  26,  26,  26,  26, 622, 625,  26,  26,  26,  26,  26,  26,
-    26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
-    26,  26,  26,  26,  26,  26, 626, 627, 628, 287, 287, 287, 287, 287, 287, 287,
-   287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287,
-   287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 629,  26, 630,  26,
-    26,  26, 631,  26, 632,  26, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633,
-   633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633,
-   633, 633, 633, 633, 633, 633, 633, 634, 635, 635, 635, 635, 635, 635, 635, 635,
-   635, 635, 635, 635, 635, 636, 635, 637, 635, 638, 635, 639, 281,  26,  26,  26,
-    26,  26,  26,  26,  26,  26,  26,  26,   9,   9,   9,   9,   9, 640,   9,   9,
-   221,  26,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-   281,  26,  26,  26,  26,  26,  26,  26,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0, 276,  26,   0,   0,   0,   0, 258, 363,   0,   0,
-     0,   0,   0,   0, 641, 642,   0, 643, 644, 645,   0,   0,   0, 646,   0,   0,
-     0,   0,   0,   0,   0, 266,  26,  26,  14,  14,  14,  14,  14,  14,  14,  14,
-   247,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
-     0,   0, 281,  26,   0,   0, 281,  26,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0, 258,  26,   0,   0,   0, 260,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0, 255,   0,   0,   0,   0,   0,   0,   0,   0, 255, 647, 648,   0, 649,
-   650,   0,   0,   0,   0,   0,   0,   0, 269, 651, 255, 255,   0,   0,   0, 652,
-   653, 654, 655,   0,   0,   0,   0,   0,   0,   0,   0,   0, 276,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0, 268,   0,   0,   0,   0,   0,   0, 656, 656, 656, 656, 656, 656, 656, 656,
-   656, 656, 656, 656, 656, 656, 656, 656, 656, 657,  26, 658, 659, 656,  26,  26,
-    26,  26,  26,  26,  26,  26,  26,  26,   2,   2,   2, 348, 660, 308,  26,  26,
-    26,  26,  26,  26,  26,  26,  26,  26, 661, 270, 270, 662, 663, 664,  18,  18,
-    18,  18,  18,  18,  18, 665,  26,  26,  26, 666,  26,  26,  26,  26,  26,  26,
-    26,  26,  26,  26,  26,  26,  26,  26, 667, 667, 667, 667, 667, 668, 667, 669,
-   667, 670,  26,  26,  26,  26,  26,  26,  26,  26, 671, 671, 671, 672,  26,  26,
-   673, 673, 673, 673, 673, 673, 673, 674,  26,  26,  26,  26,  26,  26,  26,  26,
-    26,  26, 675, 675, 675, 675, 675, 676,  26,  26,  26,  26,  26,  26,  26,  26,
-    26,  26,  26,  26, 172, 677, 170, 172, 678, 678, 678, 678, 678, 678, 678, 678,
-   678, 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, 678,
-   679, 678, 680,  26,  26,  26,  26,  26, 681, 681, 681, 681, 681, 681, 681, 681,
-   681, 682, 681, 683,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
-    26,  26,  26,  26,  26,  26, 363,   0,   0,   0,   0,   0,   0,   0, 377,  26,
-    26,  26,  26,  26,  26,  26,  26,  26, 363,   0,   0,   0,   0,   0,   0, 276,
-    26,  26,  26,  26,  26,  26,  26,  26, 684,  31,  31,  31, 685, 686, 687, 688,
-   689, 690, 685, 691, 685, 687, 687, 692,  31, 693,  31, 694, 695, 693,  31, 694,
-    26,  26,  26,  26,  26,  26,  51,  26,   0,   0,   0,   0,   0, 281,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 281,  26,   0, 258, 363,   0,
-   363,   0, 363,   0,   0,   0, 276,  26,   0,   0,   0,   0,   0, 276,  26,  26,
-    26,  26,  26,  26, 696,   0,   0,   0, 697,  26,   0,   0,   0,   0,   0, 281,
-     0, 260, 314,  26, 276,  26,  26,  26,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0, 698,   0, 377,   0, 377,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0, 258, 699,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0, 314,   0, 281, 260,  26,   0, 281,   0,   0,   0,   0,   0,   0,
-     0,  26,   0, 314,   0,   0,   0,   0,   0,  26,   0,   0,   0, 276, 314,  26,
-    26,  26,  26,  26,  26,  26,  26,  26,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0, 281,  26,   0, 276,   0, 377,   0, 260,   0,   0,   0,   0,   0, 269,
-   276, 696,   0, 281,   0, 260,   0, 260,   0,   0, 360,   0,   0,   0,   0,   0,
-     0, 266,  26,  26,  26,  26,   0, 314, 277, 277, 277, 277, 277, 277, 277, 277,
-   277, 277, 277, 277,  26,  26,  26,  26, 277, 277, 277, 277, 277, 277, 277, 347,
-   277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 280, 277, 277, 277, 277,
-   277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 347,  26, 277, 277,
-   277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
-   277, 277, 277, 277, 700,  26,  26,  26, 277, 277, 277, 280,  26,  26,  26,  26,
-    26,  26,  26,  26,  26,  26,  26,  26, 277, 277, 277, 277, 277, 277, 277, 277,
-   277, 701, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,  26,  26,
-    26,  26,  26,  26,  26,  26,  26,  26, 702,  26,  26,  26,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   9,   9,   9,   9,   9,   9,   9,   9,
+   623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623,  26,
+   624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624,
+   624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 625,  26,  26,  26,  26,  26,
+   623, 626,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+    26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26, 627, 628,
+   629, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286,
+   286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286,
+   286, 286, 286, 286, 630,  26, 631,  26,  26,  26, 632,  26, 633,  26, 634, 634,
+   634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634,
+   634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 635,
+   636, 636, 636, 636, 636, 636, 636, 636, 636, 636, 636, 636, 636, 637, 636, 638,
+   636, 639, 636, 640, 296,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+     9,   9,   9,   9,   9, 641,   9,   9, 221,  26,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0, 296,  26,  26,  26,  26,  26,  26,  26,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 276,  26,
+     0,   0,   0,   0, 258, 364,   0,   0,   0,   0,   0,   0, 642, 643,   0, 644,
+   645, 646,   0,   0,   0, 647,   0,   0,   0,   0,   0,   0,   0, 266,  26,  26,
+    14,  14,  14,  14,  14,  14,  14,  14, 247,  26,  26,  26,  26,  26,  26,  26,
+    26,  26,  26,  26,  26,  26,  26,  26,   0,   0, 296,  26,   0,   0, 296,  26,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 258,  26,   0,   0,   0, 260,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 255,   0,   0,   0,   0,   0,
+     0,   0,   0, 255, 648, 649,   0, 650, 651,   0,   0,   0,   0,   0,   0,   0,
+   269, 652, 255, 255,   0,   0,   0, 653, 654, 655, 656,   0,   0,   0,   0,   0,
+     0,   0,   0,   0, 276,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0, 268,   0,   0,   0,   0,   0,   0,
+   657, 657, 657, 657, 657, 657, 657, 657, 657, 657, 657, 657, 657, 657, 657, 657,
+   657, 658,  26, 659, 660, 657,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+     2,   2,   2, 349, 661, 309,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+   662, 270, 270, 663, 664, 665,  18,  18,  18,  18,  18,  18,  18, 666,  26,  26,
+    26, 667,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+   668, 668, 668, 668, 668, 669, 668, 670, 668, 671,  26,  26,  26,  26,  26,  26,
+    26,  26, 672, 672, 672, 673,  26,  26, 674, 674, 674, 674, 674, 674, 674, 675,
+    26,  26,  26,  26,  26,  26,  26,  26,  26,  26, 676, 676, 676, 676, 676, 677,
+    26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26, 172, 678, 170, 172,
+   679, 679, 679, 679, 679, 679, 679, 679, 679, 679, 679, 679, 679, 679, 679, 679,
+   679, 679, 679, 679, 679, 679, 679, 679, 680, 679, 681,  26,  26,  26,  26,  26,
+   682, 682, 682, 682, 682, 682, 682, 682, 682, 683, 682, 684,  26,  26,  26,  26,
+    26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26, 364,   0,
+     0,   0,   0,   0,   0,   0, 378,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+   364,   0,   0,   0,   0,   0,   0, 276,  26,  26,  26,  26,  26,  26,  26,  26,
+   685,  31,  31,  31, 686, 687, 688, 689, 690, 691, 686, 692, 686, 688, 688, 693,
+    31, 694,  31, 695, 696, 694,  31, 695,  26,  26,  26,  26,  26,  26,  51,  26,
+     0,   0,   0,   0,   0, 296,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0, 296,  26,   0, 258, 364,   0, 364,   0, 364,   0,   0,   0, 276,  26,
+     0,   0,   0,   0,   0, 276,  26,  26,  26,  26,  26,  26, 697,   0,   0,   0,
+   698,  26,   0,   0,   0,   0,   0, 296,   0, 260, 315,  26, 276,  26,  26,  26,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 699,   0, 378,   0, 378,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 258, 700,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 315,   0, 296, 260,  26,
+     0, 296,   0,   0,   0,   0,   0,   0,   0,  26,   0, 315,   0,   0,   0,   0,
+     0,  26,   0,   0,   0, 276, 315,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 296,  26,   0, 276,   0, 378,
+     0, 260,   0,   0,   0,   0,   0, 269, 276, 697,   0, 296,   0, 260,   0, 260,
+     0,   0, 361,   0,   0,   0,   0,   0,   0, 266,  26,  26,  26,  26,   0, 315,
+   277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,  26,  26,  26,  26,
+   277, 277, 277, 277, 277, 277, 277, 348, 277, 277, 277, 277, 277, 277, 277, 277,
+   277, 277, 277, 280, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
+   277, 277, 277, 277, 348,  26, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
+   277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 701,  26, 277, 277,
+   277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 280,  26,  26,  26,  26,
+   277, 277, 277, 280,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+   277, 277, 277, 277, 277, 277, 277, 277, 277, 702, 277, 277, 277, 277, 277, 277,
+   277, 277, 277, 277, 277, 277,  26,  26,  26,  26,  26,  26,  26,  26,  26,  26,
+   703,  26,  26,  26,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
      9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,
-     9,   9,   9,   9,   9,   9,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0, 939, 940, 941, 942, 946, 948,   0, 962,
-   969, 970, 971, 976,1001,1002,1003,1008,   0,1033,1040,1041,1042,1043,1047,   0,
-     0,1080,1081,1082,1086,1110,   0,   0,1124,1125,1126,1127,1131,1133,   0,1147,
-  1154,1155,1156,1161,1187,1188,1189,1193,   0,1219,1226,1227,1228,1229,1233,   0,
-     0,1267,1268,1269,1273,1298,   0,1303, 943,1128, 944,1129, 954,1139, 958,1143,
-   959,1144, 960,1145, 961,1146, 964,1149,   0,   0, 973,1158, 974,1159, 975,1160,
-   983,1168, 978,1163, 988,1173, 990,1175, 991,1176, 993,1178, 994,1179,   0,   0,
-  1004,1190,1005,1191,1006,1192,1014,1199,1007,   0,   0,   0,1016,1201,1020,1206,
-     0,1022,1208,1025,1211,1023,1209,   0,   0,   0,   0,1032,1218,1037,1223,1035,
-  1221,   0,   0,   0,1044,1230,1045,1231,1049,1235,   0,   0,1058,1244,1064,1250,
-  1060,1246,1066,1252,1067,1253,1072,1258,1069,1255,1077,1264,1074,1261,   0,   0,
-  1083,1270,1084,1271,1085,1272,1088,1275,1089,1276,1096,1283,1103,1290,1111,1299,
-  1115,1118,1307,1120,1309,1121,1310,   0,1053,1239,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,1093,1280,   0,   0,   0,   0,   0,   0,   0,
+     9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   0,   0,
      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0, 949,1134,1010,1195,1050,1236,1090,1277,1341,1368,1340,
-  1367,1342,1369,1339,1366,   0,1320,1347,1418,1419,1323,1350,   0,   0, 992,1177,
-  1018,1204,1055,1241,1416,1417,1415,1424,1202,   0,   0,   0, 987,1172,   0,   0,
-  1031,1217,1321,1348,1322,1349,1338,1365, 950,1135, 951,1136, 979,1164, 980,1165,
-  1011,1196,1012,1197,1051,1237,1052,1238,1061,1247,1062,1248,1091,1278,1092,1279,
-  1071,1257,1076,1263,   0,   0, 997,1182,   0,   0,   0,   0,   0,   0, 945,1130,
-   982,1167,1337,1364,1335,1362,1046,1232,1422,1423,1113,1301,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   8,   9,   0,  10,1425,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   7,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,1314,1427,   5,
-  1434,1438,1443,   0,1450,   0,1455,1461,1514,   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,1446,1458,1468,1476,1480,1486,1517,   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,1489,1503,1494,1500,1508,   0,   0,   0,   0,1520,1521,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,1526,1528,   0,1525,   0,   0,   0,1522,
-     0,   0,   0,   0,1536,1532,1539,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,1534,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,1556,   0,   0,   0,   0,   0,   0,1548,1550,   0,1547,   0,   0,   0,1567,
-     0,   0,   0,   0,1558,1554,1561,   0,   0,   0,   0,   0,   0,   0,1568,1569,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,1529,1551,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,1523,1545,1524,1546,   0,   0,1527,1549,
-     0,   0,1570,1571,1530,1552,1531,1553,   0,   0,1533,1555,1535,1557,1537,1559,
-     0,   0,1572,1573,1544,1566,1538,1560,1540,1562,1541,1563,1542,1564,   0,   0,
-  1543,1565,   0,   0,   0,   0,   0,   0,   0,   0,1606,1607,1609,1608,1610,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,1613,   0,1611,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1612,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,1620,   0,   0,   0,   0,   0,   0,   0,1623,   0,   0,1624,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-  1614,1615,1616,1617,1618,1619,1621,1622,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,1628,1629,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,1625,1626,   0,1627,   0,   0,   0,1634,   0,   0,1635,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,1630,1631,1632,   0,   0,1633,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-  1639,   0,   0,1638,1640,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,1636,1637,   0,   0,   0,   0,   0,   0,1641,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,1642,1644,1643,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-  1645,   0,   0,   0,   0,   0,   0,   0,1646,   0,   0,   0,   0,   0,   0,1648,
-  1649,   0,1647,1650,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,1651,1653,1652,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,1654,   0,1655,1657,1656,   0,   0,   0,   0,1659,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,1660,   0,   0,   0,   0,1661,   0,   0,   0,   0,1662,
-     0,   0,   0,   0,1663,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,1658,   0,   0,   0,   0,   0,   0,   0,   0,   0,1664,   0,1665,1673,   0,
-  1674,   0,   0,   0,   0,   0,   0,   0,   0,1666,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1668,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,1669,   0,   0,   0,   0,1670,   0,   0,   0,   0,1671,
-     0,   0,   0,   0,1672,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,1667,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1675,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1676,   0,
-  1677,   0,1678,   0,1679,   0,1680,   0,   0,   0,1681,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,1682,   0,1683,   0,   0,1684,1685,   0,1686,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0, 953,1138, 955,1140, 956,1141, 957,1142,
-  1324,1351, 963,1148, 965,1150, 968,1153, 966,1151, 967,1152,1378,1380,1379,1381,
-   984,1169, 985,1170,1420,1421, 986,1171, 989,1174, 995,1180, 998,1183, 996,1181,
-   999,1184,1000,1185,1015,1200,1329,1356,1017,1203,1019,1205,1021,1207,1024,1210,
-  1687,1688,1027,1213,1026,1212,1028,1214,1029,1215,1030,1216,1034,1220,1036,1222,
-  1039,1225,1038,1224,1334,1361,1336,1363,1382,1384,1383,1385,1056,1242,1057,1243,
-  1059,1245,1063,1249,1689,1690,1065,1251,1068,1254,1070,1256,1386,1387,1388,1389,
-  1691,1692,1073,1259,1075,1262,1079,1266,1078,1265,1095,1282,1098,1285,1097,1284,
-  1390,1391,1392,1393,1099,1286,1100,1287,1101,1288,1102,1289,1105,1292,1104,1291,
-  1106,1294,1107,1295,1108,1296,1114,1302,1119,1308,1122,1311,1123,1312,1186,1260,
-  1293,1305,   0,1394,   0,   0,   0,   0, 952,1137, 947,1132,1317,1344,1316,1343,
-  1319,1346,1318,1345,1693,1695,1371,1375,1370,1374,1373,1377,1372,1376,1694,1696,
-   981,1166, 977,1162, 972,1157,1326,1353,1325,1352,1328,1355,1327,1354,1697,1698,
-  1009,1194,1013,1198,1054,1240,1048,1234,1331,1358,1330,1357,1333,1360,1332,1359,
-  1699,1700,1396,1401,1395,1400,1398,1403,1397,1402,1399,1404,1094,1281,1087,1274,
-  1406,1411,1405,1410,1408,1413,1407,1412,1409,1414,1109,1297,1117,1306,1116,1304,
-  1112,1300,   0,   0,   0,   0,   0,   0,1471,1472,1701,1705,1702,1706,1703,1707,
-  1430,1431,1715,1719,1716,1720,1717,1721,1477,1478,1729,1731,1730,1732,   0,   0,
-  1435,1436,1733,1735,1734,1736,   0,   0,1481,1482,1737,1741,1738,1742,1739,1743,
-  1439,1440,1751,1755,1752,1756,1753,1757,1490,1491,1765,1768,1766,1769,1767,1770,
-  1447,1448,1771,1774,1772,1775,1773,1776,1495,1496,1777,1779,1778,1780,   0,   0,
-  1451,1452,1781,1783,1782,1784,   0,   0,1504,1505,1785,1788,1786,1789,1787,1790,
-     0,1459,   0,1791,   0,1792,   0,1793,1509,1510,1794,1798,1795,1799,1796,1800,
-  1462,1463,1808,1812,1809,1813,1810,1814,1467,  21,1475,  22,1479,  23,1485,  24,
-  1493,  27,1499,  28,1507,  29,   0,   0,1704,1708,1709,1710,1711,1712,1713,1714,
-  1718,1722,1723,1724,1725,1726,1727,1728,1740,1744,1745,1746,1747,1748,1749,1750,
-  1754,1758,1759,1760,1761,1762,1763,1764,1797,1801,1802,1803,1804,1805,1806,1807,
-  1811,1815,1816,1817,1818,1819,1820,1821,1470,1469,1822,1474,1465,   0,1473,1825,
-  1429,1428,1426,  12,1432,   0,  26,   0,   0,1315,1823,1484,1466,   0,1483,1829,
-  1433,  13,1437,  14,1441,1826,1827,1828,1488,1487,1513,  19,   0,   0,1492,1515,
-  1445,1444,1442,  15,   0,1831,1832,1833,1502,1501,1516,  25,1497,1498,1506,1518,
-  1457,1456,1454,  17,1453,1313,  11,   3,   0,   0,1824,1512,1519,   0,1511,1830,
-  1449,  16,1460,  18,1464,   4,   0,   0,  30,  31,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  20,   0,
-     0,   0,   2,   6,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,1834,1835,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,1836,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,1837,1839,1838,   0,   0,   0,   0,1840,   0,   0,   0,
-     0,1841,   0,   0,1842,   0,   0,   0,   0,   0,   0,   0,1843,   0,1844,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,1845,   0,   0,1846,   0,   0,1847,
-     0,1848,   0,   0,   0,   0,   0,   0, 937,   0,1850,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,1849, 936, 938,1851,1852,   0,   0,1853,1854,   0,   0,
-  1855,1856,   0,   0,   0,   0,   0,   0,1857,1858,   0,   0,1861,1862,   0,   0,
-  1863,1864,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,1867,1868,1869,1870,1859,1860,1865,1866,   0,   0,   0,   0,
-     0,   0,1871,1872,1873,1874,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,  32,  33,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,1875,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,1877,   0,1878,   0,1879,   0,1880,   0,1881,   0,1882,   0,
-  1883,   0,1884,   0,1885,   0,1886,   0,1887,   0,1888,   0,   0,1889,   0,1890,
-     0,1891,   0,   0,   0,   0,   0,   0,1892,1893,   0,1894,1895,   0,1896,1897,
-     0,1898,1899,   0,1900,1901,   0,   0,   0,   0,   0,   0,1876,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,1902,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,1904,   0,1905,   0,1906,   0,1907,   0,1908,   0,1909,   0,
-  1910,   0,1911,   0,1912,   0,1913,   0,1914,   0,1915,   0,   0,1916,   0,1917,
-     0,1918,   0,   0,   0,   0,   0,   0,1919,1920,   0,1921,1922,   0,1923,1924,
-     0,1925,1926,   0,1927,1928,   0,   0,   0,   0,   0,   0,1903,   0,   0,1929,
-  1930,1931,1932,   0,   0,   0,1933,   0, 710, 385, 724, 715, 455, 103, 186, 825,
-   825, 242, 751, 205, 241, 336, 524, 601, 663, 676, 688, 738, 411, 434, 474, 500,
-   649, 746, 799, 108, 180, 416, 482, 662, 810, 275, 462, 658, 692, 344, 618, 679,
-   293, 388, 440, 492, 740, 116, 146, 168, 368, 414, 481, 527, 606, 660, 665, 722,
-   781, 803, 809, 538, 553, 588, 642, 758, 811, 701, 233, 299, 573, 612, 487, 540,
-   714, 779, 232, 267, 412, 445, 457, 585, 594, 766, 167, 613, 149, 148, 560, 589,
-   648, 768, 708, 345, 411, 704, 105, 259, 313, 496, 518, 174, 542, 120, 307, 101,
-   430, 372, 584, 183, 228, 529, 650, 697, 424, 732, 428, 349, 632, 355, 517, 110,
-   135, 147, 403, 580, 624, 700, 750, 170, 193, 245, 297, 374, 463, 543, 763, 801,
-   812, 815, 162, 384, 420, 730, 287, 330, 337, 366, 459, 476, 509, 558, 591, 610,
-   726, 652, 734, 759, 154, 163, 198, 473, 683, 697, 292, 311, 353, 423, 572, 494,
-   113, 217, 259, 280, 314, 499, 506, 603, 608, 752, 778, 782, 788, 117, 557, 748,
-   774, 320, 109, 126, 260, 265, 373, 411, 479, 523, 655, 737, 823, 380, 765, 161,
-   395, 398, 438, 451, 502, 516, 537, 583, 791, 136, 340, 769, 122, 273, 446, 727,
-   305, 322, 400, 496, 771, 155, 190, 269, 377, 391, 406, 432, 501, 519, 599, 684,
-   687, 749, 776, 175, 452, 191, 480, 510, 659, 772, 805, 813, 397, 444, 619, 566,
-   568, 575, 491, 471, 707, 111, 636, 156, 153, 288, 346, 578, 256, 435, 383, 729,
-   680, 767, 694, 295, 128, 210,   0,   0, 227,   0, 379,   0,   0, 150, 493, 525,
-   544, 551, 552, 556, 783, 576, 604,   0, 661,   0, 703,   0,   0, 735, 743,   0,
-     0,   0, 793, 794, 795, 808, 741, 773, 118, 127, 130, 166, 169, 177, 207, 213,
-   215, 226, 229, 268, 270, 317, 327, 329, 335, 369, 375, 381, 404, 441, 448, 458,
-   477, 484, 503, 539, 545, 547, 546, 548, 549, 550, 554, 555, 561, 564, 569, 591,
-   593, 595, 598, 607, 620, 625, 625, 651, 690, 695, 705, 706, 716, 717, 733, 735,
-   777, 786, 790, 315, 869, 623,   0,   0, 102, 145, 134, 115, 129, 138, 165, 171,
-   207, 202, 206, 212, 227, 231, 240, 243, 250, 254, 294, 296, 303, 308, 319, 325,
-   321, 329, 326, 335, 341, 357, 360, 362, 370, 379, 388, 389, 393, 421, 424, 438,
-   456, 454, 458, 465, 477, 535, 485, 490, 493, 507, 512, 514, 521, 522, 525, 526,
-   528, 533, 532, 541, 565, 569, 574, 586, 591, 597, 607, 637, 647, 674, 691, 693,
-   695, 698, 703, 699, 705, 704, 702, 706, 709, 717, 728, 736, 747, 754, 770, 777,
-   783, 784, 786, 787, 790, 802, 825, 848, 847, 857,  55,  65,  66, 883, 892, 916,
-   822, 824,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,1586,   0,1605,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,1602,1603,1934,1935,1574,1575,1576,1577,1579,1580,1581,1583,1584,   0,
-  1585,1587,1588,1589,1591,   0,1592,   0,1593,1594,   0,1595,1596,   0,1598,1599,
-  1600,1601,1604,1582,1578,1590,1597,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,1936,   0,1937,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,1938,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,1939,1940,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,1941,1942,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,1944,1943,   0,1945,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,1946,1947,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-  1948,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,1949,1950,1951,1952,1953,1954,1955,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,1956,1957,1958,1960,1959,1961,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0, 106, 104, 107, 826, 114, 118, 119, 121,
-   123, 124, 127, 125,  34, 830, 130, 131, 132, 137, 827,  35, 133, 139, 829, 142,
-   143, 112, 144, 145, 924, 151, 152,  37, 157, 158, 159, 160,  38, 165, 166, 169,
-   171, 172, 173, 174, 176, 177, 178, 179, 181, 182, 182, 182, 833, 468, 184, 185,
-   834, 187, 188, 189, 196, 192, 194, 195, 197, 199, 200, 201, 203, 204, 204, 206,
-   208, 209, 211, 218, 213, 219, 214, 216, 153, 234, 221, 222, 223, 220, 225, 224,
-   230, 835, 235, 236, 237, 238, 239, 244, 836, 837, 247, 248, 249, 246, 251,  39,
-    40, 253, 255, 255, 838, 257, 258, 259, 261, 839, 262, 263, 301, 264,  41, 266,
-   270, 272, 271, 841, 274, 842, 277, 276, 278, 281, 282,  42, 283, 284, 285, 286,
-    43, 843,  44, 289, 290, 291, 293, 934, 298, 845, 845, 621, 300, 300,  45, 852,
-   894, 302, 304,  46, 306, 309, 310, 312, 316,  48,  47, 317, 846, 318, 323, 324,
-   325, 324, 328, 329, 333, 331, 332, 334, 335, 336, 338, 339, 342, 343, 347, 351,
-   849, 350, 348, 352, 354, 359, 850, 361, 358, 356,  49, 363, 365, 367, 364,  50,
-   369, 371, 851, 376, 386, 378,  53, 381,  52,  51, 140, 141, 387, 382, 614,  78,
-   388, 389, 390, 394, 392, 856,  54, 399, 396, 402, 404, 858, 405, 401, 407,  55,
-   408, 409, 410, 413, 859, 415,  56, 417, 860, 418,  57, 419, 422, 424, 425, 861,
-   840, 862, 426, 863, 429, 431, 427, 433, 437, 441, 438, 439, 442, 443, 864, 436,
-   449, 450,  58, 454, 453, 865, 447, 460, 866, 867, 461, 466, 465, 464,  59, 467,
-   470, 469, 472, 828, 475, 868, 478, 870, 483, 485, 486, 871, 488, 489, 872, 873,
-   495, 497,  60, 498,  61,  61, 504, 505, 507, 508, 511,  62, 513, 874, 515, 875,
-   518, 844, 520, 876, 877, 878,  63,  64, 528, 880, 879, 881, 882, 530, 531, 531,
-   533,  66, 534,  67,  68, 884, 536, 538, 541,  69, 885, 549, 886, 887, 556, 559,
-    70, 561, 562, 563, 888, 889, 889, 567,  71, 890, 570, 571,  72, 891, 577,  73,
-   581, 579, 582, 893, 587,  74, 590, 592, 596,  75, 895, 896,  76, 897, 600, 898,
-   602, 605, 607, 899, 900, 609, 901, 611, 853,  77, 615, 616,  79, 617, 252, 902,
-   903, 854, 855, 621, 622, 731,  80, 627, 626, 628, 164, 629, 630, 631, 633, 904,
-   632, 634, 639, 640, 635, 641, 646, 651, 638, 643, 644, 645, 905, 907, 906,  81,
-   653, 654, 656, 911, 657, 908,  82,  83, 909, 910,  84, 664, 665, 666, 667, 669,
-   668, 671, 670, 674, 672, 673, 675,  85, 677, 678,  86, 681, 682, 912, 685, 686,
-    87, 689,  36, 913, 914,  88,  89, 696, 702, 709, 711, 915, 712, 713, 718, 719,
-   917, 831, 721, 720, 723, 832, 725, 728, 918, 919, 739, 742, 744, 920, 745, 753,
-   756, 757, 755, 760, 761, 921, 762,  90, 764, 922,  91, 775, 279, 780, 923, 925,
-    92,  93, 785, 926,  94, 927, 787, 787, 789, 928, 792,  95, 796, 797, 798, 800,
-    96, 929, 802, 804, 806,  97,  98, 807, 930,  99, 931, 932, 933, 814, 100, 816,
-   817, 818, 819, 820, 821, 935,   0,   0,
+   939, 940, 941, 942, 946, 948,   0, 962, 969, 970, 971, 976,1001,1002,1003,1008,
+     0,1033,1040,1041,1042,1043,1047,   0,   0,1080,1081,1082,1086,1110,   0,   0,
+  1124,1125,1126,1127,1131,1133,   0,1147,1154,1155,1156,1161,1187,1188,1189,1193,
+     0,1219,1226,1227,1228,1229,1233,   0,   0,1267,1268,1269,1273,1298,   0,1303,
+   943,1128, 944,1129, 954,1139, 958,1143, 959,1144, 960,1145, 961,1146, 964,1149,
+     0,   0, 973,1158, 974,1159, 975,1160, 983,1168, 978,1163, 988,1173, 990,1175,
+   991,1176, 993,1178, 994,1179,   0,   0,1004,1190,1005,1191,1006,1192,1014,1199,
+  1007,   0,   0,   0,1016,1201,1020,1206,   0,1022,1208,1025,1211,1023,1209,   0,
+     0,   0,   0,1032,1218,1037,1223,1035,1221,   0,   0,   0,1044,1230,1045,1231,
+  1049,1235,   0,   0,1058,1244,1064,1250,1060,1246,1066,1252,1067,1253,1072,1258,
+  1069,1255,1077,1264,1074,1261,   0,   0,1083,1270,1084,1271,1085,1272,1088,1275,
+  1089,1276,1096,1283,1103,1290,1111,1299,1115,1118,1307,1120,1309,1121,1310,   0,
+  1053,1239,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1093,
+  1280,   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, 949,1134,1010,
+  1195,1050,1236,1090,1277,1341,1368,1340,1367,1342,1369,1339,1366,   0,1320,1347,
+  1418,1419,1323,1350,   0,   0, 992,1177,1018,1204,1055,1241,1416,1417,1415,1424,
+  1202,   0,   0,   0, 987,1172,   0,   0,1031,1217,1321,1348,1322,1349,1338,1365,
+   950,1135, 951,1136, 979,1164, 980,1165,1011,1196,1012,1197,1051,1237,1052,1238,
+  1061,1247,1062,1248,1091,1278,1092,1279,1071,1257,1076,1263,   0,   0, 997,1182,
+     0,   0,   0,   0,   0,   0, 945,1130, 982,1167,1337,1364,1335,1362,1046,1232,
+  1422,1423,1113,1301,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     8,   9,   0,  10,1425,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   7,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,
+     0,   0,   0,   0,   0,1314,1427,   5,1434,1438,1443,   0,1450,   0,1455,1461,
+  1514,   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,1446,1458,1468,1476,1480,1486,
+  1517,   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,1489,1503,1494,1500,1508,   0,
+     0,   0,   0,1520,1521,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+  1526,1528,   0,1525,   0,   0,   0,1522,   0,   0,   0,   0,1536,1532,1539,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,1534,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,1556,   0,   0,   0,   0,   0,   0,
+  1548,1550,   0,1547,   0,   0,   0,1567,   0,   0,   0,   0,1558,1554,1561,   0,
+     0,   0,   0,   0,   0,   0,1568,1569,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,1529,1551,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+  1523,1545,1524,1546,   0,   0,1527,1549,   0,   0,1570,1571,1530,1552,1531,1553,
+     0,   0,1533,1555,1535,1557,1537,1559,   0,   0,1572,1573,1544,1566,1538,1560,
+  1540,1562,1541,1563,1542,1564,   0,   0,1543,1565,   0,   0,   0,   0,   0,   0,
+     0,   0,1606,1607,1609,1608,1610,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+  1613,   0,1611,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,1612,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,1620,   0,   0,   0,   0,   0,   0,
+     0,1623,   0,   0,1624,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,1614,1615,1616,1617,1618,1619,1621,1622,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1628,1629,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1625,1626,   0,1627,
+     0,   0,   0,1634,   0,   0,1635,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,1630,1631,1632,   0,   0,1633,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,1639,   0,   0,1638,1640,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1636,1637,   0,   0,
+     0,   0,   0,   0,1641,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1642,1644,1643,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,1645,   0,   0,   0,   0,   0,   0,   0,
+  1646,   0,   0,   0,   0,   0,   0,1648,1649,   0,1647,1650,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1651,1653,1652,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1654,   0,1655,1657,1656,   0,
+     0,   0,   0,1659,   0,   0,   0,   0,   0,   0,   0,   0,   0,1660,   0,   0,
+     0,   0,1661,   0,   0,   0,   0,1662,   0,   0,   0,   0,1663,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,1658,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,1664,   0,1665,1673,   0,1674,   0,   0,   0,   0,   0,   0,   0,
+     0,1666,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,1668,   0,   0,   0,   0,   0,   0,   0,   0,   0,1669,   0,   0,
+     0,   0,1670,   0,   0,   0,   0,1671,   0,   0,   0,   0,1672,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,1667,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,1675,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,1676,   0,1677,   0,1678,   0,1679,   0,1680,   0,
+     0,   0,1681,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1682,   0,1683,   0,   0,
+  1684,1685,   0,1686,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+   953,1138, 955,1140, 956,1141, 957,1142,1324,1351, 963,1148, 965,1150, 968,1153,
+   966,1151, 967,1152,1378,1380,1379,1381, 984,1169, 985,1170,1420,1421, 986,1171,
+   989,1174, 995,1180, 998,1183, 996,1181, 999,1184,1000,1185,1015,1200,1329,1356,
+  1017,1203,1019,1205,1021,1207,1024,1210,1687,1688,1027,1213,1026,1212,1028,1214,
+  1029,1215,1030,1216,1034,1220,1036,1222,1039,1225,1038,1224,1334,1361,1336,1363,
+  1382,1384,1383,1385,1056,1242,1057,1243,1059,1245,1063,1249,1689,1690,1065,1251,
+  1068,1254,1070,1256,1386,1387,1388,1389,1691,1692,1073,1259,1075,1262,1079,1266,
+  1078,1265,1095,1282,1098,1285,1097,1284,1390,1391,1392,1393,1099,1286,1100,1287,
+  1101,1288,1102,1289,1105,1292,1104,1291,1106,1294,1107,1295,1108,1296,1114,1302,
+  1119,1308,1122,1311,1123,1312,1186,1260,1293,1305,   0,1394,   0,   0,   0,   0,
+   952,1137, 947,1132,1317,1344,1316,1343,1319,1346,1318,1345,1693,1695,1371,1375,
+  1370,1374,1373,1377,1372,1376,1694,1696, 981,1166, 977,1162, 972,1157,1326,1353,
+  1325,1352,1328,1355,1327,1354,1697,1698,1009,1194,1013,1198,1054,1240,1048,1234,
+  1331,1358,1330,1357,1333,1360,1332,1359,1699,1700,1396,1401,1395,1400,1398,1403,
+  1397,1402,1399,1404,1094,1281,1087,1274,1406,1411,1405,1410,1408,1413,1407,1412,
+  1409,1414,1109,1297,1117,1306,1116,1304,1112,1300,   0,   0,   0,   0,   0,   0,
+  1471,1472,1701,1705,1702,1706,1703,1707,1430,1431,1715,1719,1716,1720,1717,1721,
+  1477,1478,1729,1731,1730,1732,   0,   0,1435,1436,1733,1735,1734,1736,   0,   0,
+  1481,1482,1737,1741,1738,1742,1739,1743,1439,1440,1751,1755,1752,1756,1753,1757,
+  1490,1491,1765,1768,1766,1769,1767,1770,1447,1448,1771,1774,1772,1775,1773,1776,
+  1495,1496,1777,1779,1778,1780,   0,   0,1451,1452,1781,1783,1782,1784,   0,   0,
+  1504,1505,1785,1788,1786,1789,1787,1790,   0,1459,   0,1791,   0,1792,   0,1793,
+  1509,1510,1794,1798,1795,1799,1796,1800,1462,1463,1808,1812,1809,1813,1810,1814,
+  1467,  21,1475,  22,1479,  23,1485,  24,1493,  27,1499,  28,1507,  29,   0,   0,
+  1704,1708,1709,1710,1711,1712,1713,1714,1718,1722,1723,1724,1725,1726,1727,1728,
+  1740,1744,1745,1746,1747,1748,1749,1750,1754,1758,1759,1760,1761,1762,1763,1764,
+  1797,1801,1802,1803,1804,1805,1806,1807,1811,1815,1816,1817,1818,1819,1820,1821,
+  1470,1469,1822,1474,1465,   0,1473,1825,1429,1428,1426,  12,1432,   0,  26,   0,
+     0,1315,1823,1484,1466,   0,1483,1829,1433,  13,1437,  14,1441,1826,1827,1828,
+  1488,1487,1513,  19,   0,   0,1492,1515,1445,1444,1442,  15,   0,1831,1832,1833,
+  1502,1501,1516,  25,1497,1498,1506,1518,1457,1456,1454,  17,1453,1313,  11,   3,
+     0,   0,1824,1512,1519,   0,1511,1830,1449,  16,1460,  18,1464,   4,   0,   0,
+    30,  31,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,  20,   0,   0,   0,   2,   6,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1834,1835,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1836,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1837,1839,1838,
+     0,   0,   0,   0,1840,   0,   0,   0,   0,1841,   0,   0,1842,   0,   0,   0,
+     0,   0,   0,   0,1843,   0,1844,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,1845,   0,   0,1846,   0,   0,1847,   0,1848,   0,   0,   0,   0,   0,   0,
+   937,   0,1850,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1849, 936, 938,
+  1851,1852,   0,   0,1853,1854,   0,   0,1855,1856,   0,   0,   0,   0,   0,   0,
+  1857,1858,   0,   0,1861,1862,   0,   0,1863,1864,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1867,1868,1869,1870,
+  1859,1860,1865,1866,   0,   0,   0,   0,   0,   0,1871,1872,1873,1874,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,  32,  33,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1875,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1877,   0,1878,   0,
+  1879,   0,1880,   0,1881,   0,1882,   0,1883,   0,1884,   0,1885,   0,1886,   0,
+  1887,   0,1888,   0,   0,1889,   0,1890,   0,1891,   0,   0,   0,   0,   0,   0,
+  1892,1893,   0,1894,1895,   0,1896,1897,   0,1898,1899,   0,1900,1901,   0,   0,
+     0,   0,   0,   0,1876,   0,   0,   0,   0,   0,   0,   0,   0,   0,1902,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1904,   0,1905,   0,
+  1906,   0,1907,   0,1908,   0,1909,   0,1910,   0,1911,   0,1912,   0,1913,   0,
+  1914,   0,1915,   0,   0,1916,   0,1917,   0,1918,   0,   0,   0,   0,   0,   0,
+  1919,1920,   0,1921,1922,   0,1923,1924,   0,1925,1926,   0,1927,1928,   0,   0,
+     0,   0,   0,   0,1903,   0,   0,1929,1930,1931,1932,   0,   0,   0,1933,   0,
+   710, 385, 724, 715, 455, 103, 186, 825, 825, 242, 751, 205, 241, 336, 524, 601,
+   663, 676, 688, 738, 411, 434, 474, 500, 649, 746, 799, 108, 180, 416, 482, 662,
+   810, 275, 462, 658, 692, 344, 618, 679, 293, 388, 440, 492, 740, 116, 146, 168,
+   368, 414, 481, 527, 606, 660, 665, 722, 781, 803, 809, 538, 553, 588, 642, 758,
+   811, 701, 233, 299, 573, 612, 487, 540, 714, 779, 232, 267, 412, 445, 457, 585,
+   594, 766, 167, 613, 149, 148, 560, 589, 648, 768, 708, 345, 411, 704, 105, 259,
+   313, 496, 518, 174, 542, 120, 307, 101, 430, 372, 584, 183, 228, 529, 650, 697,
+   424, 732, 428, 349, 632, 355, 517, 110, 135, 147, 403, 580, 624, 700, 750, 170,
+   193, 245, 297, 374, 463, 543, 763, 801, 812, 815, 162, 384, 420, 730, 287, 330,
+   337, 366, 459, 476, 509, 558, 591, 610, 726, 652, 734, 759, 154, 163, 198, 473,
+   683, 697, 292, 311, 353, 423, 572, 494, 113, 217, 259, 280, 314, 499, 506, 603,
+   608, 752, 778, 782, 788, 117, 557, 748, 774, 320, 109, 126, 260, 265, 373, 411,
+   479, 523, 655, 737, 823, 380, 765, 161, 395, 398, 438, 451, 502, 516, 537, 583,
+   791, 136, 340, 769, 122, 273, 446, 727, 305, 322, 400, 496, 771, 155, 190, 269,
+   377, 391, 406, 432, 501, 519, 599, 684, 687, 749, 776, 175, 452, 191, 480, 510,
+   659, 772, 805, 813, 397, 444, 619, 566, 568, 575, 491, 471, 707, 111, 636, 156,
+   153, 288, 346, 578, 256, 435, 383, 729, 680, 767, 694, 295, 128, 210,   0,   0,
+   227,   0, 379,   0,   0, 150, 493, 525, 544, 551, 552, 556, 783, 576, 604,   0,
+   661,   0, 703,   0,   0, 735, 743,   0,   0,   0, 793, 794, 795, 808, 741, 773,
+   118, 127, 130, 166, 169, 177, 207, 213, 215, 226, 229, 268, 270, 317, 327, 329,
+   335, 369, 375, 381, 404, 441, 448, 458, 477, 484, 503, 539, 545, 547, 546, 548,
+   549, 550, 554, 555, 561, 564, 569, 591, 593, 595, 598, 607, 620, 625, 625, 651,
+   690, 695, 705, 706, 716, 717, 733, 735, 777, 786, 790, 315, 869, 623,   0,   0,
+   102, 145, 134, 115, 129, 138, 165, 171, 207, 202, 206, 212, 227, 231, 240, 243,
+   250, 254, 294, 296, 303, 308, 319, 325, 321, 329, 326, 335, 341, 357, 360, 362,
+   370, 379, 388, 389, 393, 421, 424, 438, 456, 454, 458, 465, 477, 535, 485, 490,
+   493, 507, 512, 514, 521, 522, 525, 526, 528, 533, 532, 541, 565, 569, 574, 586,
+   591, 597, 607, 637, 647, 674, 691, 693, 695, 698, 703, 699, 705, 704, 702, 706,
+   709, 717, 728, 736, 747, 754, 770, 777, 783, 784, 786, 787, 790, 802, 825, 848,
+   847, 857,  55,  65,  66, 883, 892, 916, 822, 824,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1586,   0,1605,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1602,1603,1934,1935,1574,1575,
+  1576,1577,1579,1580,1581,1583,1584,   0,1585,1587,1588,1589,1591,   0,1592,   0,
+  1593,1594,   0,1595,1596,   0,1598,1599,1600,1601,1604,1582,1578,1590,1597,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1936,   0,1937,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1938,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1939,1940,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1941,1942,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1944,1943,   0,1945,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1946,1947,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,1948,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1949,1950,
+  1951,1952,1953,1954,1955,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1956,1957,1958,1960,1959,
+  1961,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+   106, 104, 107, 826, 114, 118, 119, 121, 123, 124, 127, 125,  34, 830, 130, 131,
+   132, 137, 827,  35, 133, 139, 829, 142, 143, 112, 144, 145, 924, 151, 152,  37,
+   157, 158, 159, 160,  38, 165, 166, 169, 171, 172, 173, 174, 176, 177, 178, 179,
+   181, 182, 182, 182, 833, 468, 184, 185, 834, 187, 188, 189, 196, 192, 194, 195,
+   197, 199, 200, 201, 203, 204, 204, 206, 208, 209, 211, 218, 213, 219, 214, 216,
+   153, 234, 221, 222, 223, 220, 225, 224, 230, 835, 235, 236, 237, 238, 239, 244,
+   836, 837, 247, 248, 249, 246, 251,  39,  40, 253, 255, 255, 838, 257, 258, 259,
+   261, 839, 262, 263, 301, 264,  41, 266, 270, 272, 271, 841, 274, 842, 277, 276,
+   278, 281, 282,  42, 283, 284, 285, 286,  43, 843,  44, 289, 290, 291, 293, 934,
+   298, 845, 845, 621, 300, 300,  45, 852, 894, 302, 304,  46, 306, 309, 310, 312,
+   316,  48,  47, 317, 846, 318, 323, 324, 325, 324, 328, 329, 333, 331, 332, 334,
+   335, 336, 338, 339, 342, 343, 347, 351, 849, 350, 348, 352, 354, 359, 850, 361,
+   358, 356,  49, 363, 365, 367, 364,  50, 369, 371, 851, 376, 386, 378,  53, 381,
+    52,  51, 140, 141, 387, 382, 614,  78, 388, 389, 390, 394, 392, 856,  54, 399,
+   396, 402, 404, 858, 405, 401, 407,  55, 408, 409, 410, 413, 859, 415,  56, 417,
+   860, 418,  57, 419, 422, 424, 425, 861, 840, 862, 426, 863, 429, 431, 427, 433,
+   437, 441, 438, 439, 442, 443, 864, 436, 449, 450,  58, 454, 453, 865, 447, 460,
+   866, 867, 461, 466, 465, 464,  59, 467, 470, 469, 472, 828, 475, 868, 478, 870,
+   483, 485, 486, 871, 488, 489, 872, 873, 495, 497,  60, 498,  61,  61, 504, 505,
+   507, 508, 511,  62, 513, 874, 515, 875, 518, 844, 520, 876, 877, 878,  63,  64,
+   528, 880, 879, 881, 882, 530, 531, 531, 533,  66, 534,  67,  68, 884, 536, 538,
+   541,  69, 885, 549, 886, 887, 556, 559,  70, 561, 562, 563, 888, 889, 889, 567,
+    71, 890, 570, 571,  72, 891, 577,  73, 581, 579, 582, 893, 587,  74, 590, 592,
+   596,  75, 895, 896,  76, 897, 600, 898, 602, 605, 607, 899, 900, 609, 901, 611,
+   853,  77, 615, 616,  79, 617, 252, 902, 903, 854, 855, 621, 622, 731,  80, 627,
+   626, 628, 164, 629, 630, 631, 633, 904, 632, 634, 639, 640, 635, 641, 646, 651,
+   638, 643, 644, 645, 905, 907, 906,  81, 653, 654, 656, 911, 657, 908,  82,  83,
+   909, 910,  84, 664, 665, 666, 667, 669, 668, 671, 670, 674, 672, 673, 675,  85,
+   677, 678,  86, 681, 682, 912, 685, 686,  87, 689,  36, 913, 914,  88,  89, 696,
+   702, 709, 711, 915, 712, 713, 718, 719, 917, 831, 721, 720, 723, 832, 725, 728,
+   918, 919, 739, 742, 744, 920, 745, 753, 756, 757, 755, 760, 761, 921, 762,  90,
+   764, 922,  91, 775, 279, 780, 923, 925,  92,  93, 785, 926,  94, 927, 787, 787,
+   789, 928, 792,  95, 796, 797, 798, 800,  96, 929, 802, 804, 806,  97,  98, 807,
+   930,  99, 931, 932, 933, 814, 100, 816, 817, 818, 819, 820, 821, 935,   0,   0,
 };
 static const int16_t
 _hb_ucd_i16[196] =
@@ -2797,12 +2799,12 @@
 static inline uint_fast8_t
 _hb_ucd_gc (unsigned u)
 {
-  return u<1114110u?_hb_ucd_u8[6800+(((_hb_ucd_u8[1312+(((_hb_ucd_u16[((_hb_ucd_u8[544+(((_hb_ucd_u8[u>>1>>3>>3>>4])<<4)+((u>>1>>3>>3)&15u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2;
+  return u<1114110u?_hb_ucd_u8[6808+(((_hb_ucd_u8[1312+(((_hb_ucd_u16[((_hb_ucd_u8[544+(((_hb_ucd_u8[u>>1>>3>>3>>4])<<4)+((u>>1>>3>>3)&15u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2;
 }
 static inline uint_fast8_t
 _hb_ucd_ccc (unsigned u)
 {
-  return u<125259u?_hb_ucd_u8[8792+(((_hb_ucd_u8[8236+(((_hb_ucd_u8[7776+(((_hb_ucd_u8[7424+(((_hb_ucd_u8[7178+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0;
+  return u<125259u?_hb_ucd_u8[8800+(((_hb_ucd_u8[8244+(((_hb_ucd_u8[7784+(((_hb_ucd_u8[7432+(((_hb_ucd_u8[7186+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0;
 }
 static inline unsigned
 _hb_ucd_b4 (const uint8_t* a, unsigned i)
@@ -2812,24 +2814,24 @@
 static inline int_fast16_t
 _hb_ucd_bmg (unsigned u)
 {
-  return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[9540+(((_hb_ucd_u8[9420+(((_hb_ucd_b4(9292+_hb_ucd_u8,u>>2>>3>>3))<<3)+((u>>2>>3)&7u))])<<3)+((u>>2)&7u))])<<2)+((u)&3u)]:0;
+  return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[9548+(((_hb_ucd_u8[9428+(((_hb_ucd_b4(9300+_hb_ucd_u8,u>>2>>3>>3))<<3)+((u>>2>>3)&7u))])<<3)+((u>>2)&7u))])<<2)+((u)&3u)]:0;
 }
 static inline uint_fast8_t
 _hb_ucd_sc (unsigned u)
 {
-  return u<918000u?_hb_ucd_u8[11062+(((_hb_ucd_u16[2040+(((_hb_ucd_u8[10326+(((_hb_ucd_u8[9876+(u>>3>>4>>4)])<<4)+((u>>3>>4)&15u))])<<4)+((u>>3)&15u))])<<3)+((u)&7u))]:2;
+  return u<918000u?_hb_ucd_u8[11070+(((_hb_ucd_u16[2048+(((_hb_ucd_u8[10334+(((_hb_ucd_u8[9884+(u>>3>>4>>4)])<<4)+((u>>3>>4)&15u))])<<4)+((u>>3)&15u))])<<3)+((u)&7u))]:2;
 }
 static inline uint_fast16_t
 _hb_ucd_dm (unsigned u)
 {
-  return u<195102u?_hb_ucd_u16[6008+(((_hb_ucd_u8[17068+(((_hb_ucd_u8[16686+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0;
+  return u<195102u?_hb_ucd_u16[6032+(((_hb_ucd_u8[17084+(((_hb_ucd_u8[16702+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0;
 }
 
 
 #elif !defined(HB_NO_UCD_UNASSIGNED)
 
 static const uint8_t
-_hb_ucd_u8[14744] =
+_hb_ucd_u8[14752] =
 {
     0,  1,  2,  3,  4,  5,  6,  7,  7,  8,  7,  7,  7,  7,  7,  7,
     7,  7,  7,  7,  9, 10,  7,  7,  7,  7, 11, 12, 13, 13, 13, 14,
@@ -2906,13 +2908,13 @@
    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,243, 34,
   244, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
    34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,245, 34, 34,
-   34, 34, 34, 34, 34, 34, 34,246,122,122,122,122,122,122,122,122,
-   34, 34, 34, 34,247,122,122,122,122,122,122,122,122,122,122,122,
-   34, 34, 34, 34, 34, 34,248, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-   34, 34, 34, 34, 34, 34, 34,249,122,122,122,122,122,122,122,122,
-  250,122,251,252,122,122,122,122,122,122,122,122,122,122,122,122,
-  107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,253,
+   34, 34, 34, 34, 34, 34, 34,246, 34, 34, 34, 34,247,122,122,122,
+   34, 34, 34, 34,248,122,122,122,122,122,122,122,122,122,122,122,
+   34, 34, 34, 34, 34, 34,249, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+   34, 34, 34, 34, 34, 34, 34,250,122,122,122,122,122,122,122,122,
+  251,122,252,253,122,122,122,122,122,122,122,122,122,122,122,122,
   107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,254,
+  107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,255,
     0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  3,  2,  4,  5,  6,  2,
     7,  7,  7,  7,  7,  2,  8,  9, 10, 11, 11, 11, 11, 11, 11, 11,
    11, 11, 11, 11, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16,
@@ -3075,11 +3077,11 @@
   121,  4,  4,  4,  4,  2,  2, 88,  2,  2,  2,  2,  2,120,  2,  2,
   108,151,  2,  2,  2,  2,  2,  2, 67,  2,152,148,148,148,153, 44,
    67, 67, 67, 67, 67, 55, 67, 67, 67, 67, 44, 44, 44, 44, 44, 44,
-   67, 67, 67, 44, 44, 44, 44, 44, 67, 67, 67, 67, 67, 67, 44, 44,
-    1,  2,154,155,  4,  4,  4,  4,  4, 67,  4,  4,  4,  4,156,157,
-  158,105,105,105,105, 43, 43, 86,159, 40, 40, 67,105,160, 63, 67,
-   36, 36, 36, 61, 57,161,162, 69, 36, 36, 36, 36, 36, 63, 40, 69,
-   44, 44, 62, 36, 36, 36, 36, 36, 67, 27, 27, 67, 67, 67, 67, 67,
+   67, 67, 67, 44, 44, 44, 44, 44,  1,  2,154,155,  4,  4,  4,  4,
+    4, 67,  4,  4,  4,  4,156,157,158,105,105,105,105, 43, 43, 86,
+  159, 40, 40, 67,105,160, 63, 67, 36, 36, 36, 61, 57,161,162, 69,
+   36, 36, 36, 36, 36, 63, 40, 69, 44, 44, 62, 36, 36, 36, 36, 36,
+   67, 27, 27, 67, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44, 44, 55,
    67, 67, 67, 67, 67, 67, 67, 92, 27, 27, 27, 27, 27, 67, 67, 67,
    67, 67, 67, 67, 27, 27, 27, 27,163, 27, 27, 27, 27, 27, 27, 27,
    36, 36, 83, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,164,  2,
@@ -3247,218 +3249,218 @@
    44, 61, 44, 62, 62, 62, 62, 36, 62, 61, 61, 62, 62, 62, 62, 62,
    62, 61, 61, 62, 36, 61, 36, 36, 36, 61, 36, 36, 62, 36, 61, 61,
    36, 36, 36, 36, 36, 62, 36, 36, 62, 36, 62, 36, 36, 62, 36, 36,
-    8, 44, 44, 44, 44, 44, 44, 44, 55, 67, 67, 67, 67, 67, 67, 67,
-   27, 27, 27, 27, 27, 27, 91, 67, 67, 67, 67, 67, 67, 67, 67, 44,
-   44, 44, 44, 67, 67, 67, 67, 67, 67, 92, 44, 44, 44, 44, 44, 44,
-   67, 67, 67, 67, 92, 44, 44, 44, 67, 44, 44, 44, 44, 44, 44, 44,
-   67, 67, 67, 67, 67, 25, 41, 41, 67, 67, 67, 67, 44, 44, 67, 67,
-   67, 67, 67, 92, 44, 55, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44,
-   67, 67, 67, 67, 67, 67, 67, 55, 67, 67, 67, 44, 44, 44, 44, 67,
-   67, 92, 67, 67, 67, 67, 67, 67, 79, 44, 44, 44, 44, 44, 44, 44,
-  171,171,171,171,171,171,171, 44,171,171,171,171,171,171,171,  0,
-    0,  0, 29, 21, 21, 21, 23, 21, 22, 18, 21, 25, 21, 17, 13, 13,
-   25, 25, 25, 21, 21,  9,  9,  9,  9, 22, 21, 18, 24, 16, 24,  5,
-    5,  5,  5, 22, 25, 18, 25,  0, 23, 23, 26, 21, 24, 26,  7, 20,
-   25,  1, 26, 24, 26, 25, 15, 15, 24, 15,  7, 19, 15, 21,  9, 25,
-    9,  5,  5, 25,  5,  9,  5,  7,  7,  7,  9,  8,  8,  5,  7,  5,
-    6,  6, 24, 24,  6, 24, 12, 12,  2,  2,  6,  5,  9, 21,  9,  2,
-    2,  9, 25,  9, 26, 12, 11, 11,  2,  6,  5, 21, 17,  2,  2, 26,
-   26, 23,  2, 12, 17, 12, 21, 12, 12, 21,  7,  2,  2,  7,  7, 21,
-   21,  2,  1,  1, 21, 23, 26, 26,  1, 21,  6,  7,  7, 12, 12,  7,
-   21,  7, 12,  1, 12,  6,  6, 12, 12, 26,  7, 26, 26,  7,  2,  1,
-   12,  2,  6,  2, 24,  7,  7,  6,  1, 12, 12, 10, 10, 10, 10, 12,
-   21,  6,  2, 10, 10,  2, 15, 26, 26,  2,  2, 21,  7, 10, 15,  7,
-    2, 23, 21, 26, 10,  7, 21, 15, 15,  2, 17,  7, 29,  7,  7, 22,
-   18,  2, 14, 14, 14,  7, 10, 21, 17, 21, 11, 12,  5,  2,  5,  6,
-    8,  8,  8, 24,  5, 24,  2, 24,  9, 24, 24,  2, 29, 29, 29,  1,
-   17, 17, 20, 19, 22, 20, 27, 28,  1, 29, 21, 20, 19, 21, 21, 16,
-   16, 21, 25, 22, 18, 21, 21, 29,  1,  2, 15,  6, 18,  6, 23,  2,
-   12, 11,  9, 26, 26,  9, 26,  5,  5, 26, 14,  9,  5, 14, 14, 15,
-   25, 26, 26, 22, 18, 26, 18, 25, 18, 22,  5, 12,  2,  5, 22, 21,
-   21, 22, 18, 17, 26,  6,  7, 14, 17, 22, 18, 18, 26, 14, 17,  6,
-   14,  6, 12, 24, 24,  6, 26, 15,  6, 21, 11, 21, 24,  9,  6,  9,
-   23, 26,  6, 10,  4,  4,  3,  3,  7, 25, 17, 16, 16, 22, 16, 16,
-   25, 17, 25,  2, 25, 24,  2, 15, 12, 15, 14,  2, 21, 14,  7, 15,
-   12, 17, 21,  1, 26, 10, 10,  1, 23, 15,  0,  1,  2,  3,  4,  5,
-    6,  7,  8,  9,  0, 10, 11, 12, 13,  0, 14,  0,  0,  0,  0,  0,
-   15,  0, 16,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    8, 44, 44, 44, 44, 44, 44, 44, 67, 67, 67, 67, 67, 67, 44, 44,
+   55, 67, 67, 67, 67, 67, 67, 67, 27, 27, 27, 27, 27, 27, 91, 67,
+   67, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44, 67, 67, 67, 67, 67,
+   67, 92, 44, 44, 44, 44, 44, 44, 67, 67, 67, 67, 92, 44, 44, 44,
+   67, 44, 44, 44, 44, 44, 44, 44, 67, 67, 67, 67, 67, 25, 41, 41,
+   67, 67, 67, 67, 44, 44, 67, 67, 67, 67, 67, 92, 44, 55, 67, 67,
+   67, 67, 67, 67, 44, 44, 44, 44, 67, 67, 67, 67, 67, 67, 67, 55,
+   67, 67, 67, 44, 44, 44, 44, 67, 67, 92, 67, 67, 67, 67, 67, 67,
+   79, 44, 44, 44, 44, 44, 44, 44,171,171,171,171,171,171,171, 44,
+  171,171,171,171,171,171,171,  0,  0,  0, 29, 21, 21, 21, 23, 21,
+   22, 18, 21, 25, 21, 17, 13, 13, 25, 25, 25, 21, 21,  9,  9,  9,
+    9, 22, 21, 18, 24, 16, 24,  5,  5,  5,  5, 22, 25, 18, 25,  0,
+   23, 23, 26, 21, 24, 26,  7, 20, 25,  1, 26, 24, 26, 25, 15, 15,
+   24, 15,  7, 19, 15, 21,  9, 25,  9,  5,  5, 25,  5,  9,  5,  7,
+    7,  7,  9,  8,  8,  5,  7,  5,  6,  6, 24, 24,  6, 24, 12, 12,
+    2,  2,  6,  5,  9, 21,  9,  2,  2,  9, 25,  9, 26, 12, 11, 11,
+    2,  6,  5, 21, 17,  2,  2, 26, 26, 23,  2, 12, 17, 12, 21, 12,
+   12, 21,  7,  2,  2,  7,  7, 21, 21,  2,  1,  1, 21, 23, 26, 26,
+    1, 21,  6,  7,  7, 12, 12,  7, 21,  7, 12,  1, 12,  6,  6, 12,
+   12, 26,  7, 26, 26,  7,  2,  1, 12,  2,  6,  2, 24,  7,  7,  6,
+    1, 12, 12, 10, 10, 10, 10, 12, 21,  6,  2, 10, 10,  2, 15, 26,
+   26,  2,  2, 21,  7, 10, 15,  7,  2, 23, 21, 26, 10,  7, 21, 15,
+   15,  2, 17,  7, 29,  7,  7, 22, 18,  2, 14, 14, 14,  7, 10, 21,
+   17, 21, 11, 12,  5,  2,  5,  6,  8,  8,  8, 24,  5, 24,  2, 24,
+    9, 24, 24,  2, 29, 29, 29,  1, 17, 17, 20, 19, 22, 20, 27, 28,
+    1, 29, 21, 20, 19, 21, 21, 16, 16, 21, 25, 22, 18, 21, 21, 29,
+    1,  2, 15,  6, 18,  6, 23,  2, 12, 11,  9, 26, 26,  9, 26,  5,
+    5, 26, 14,  9,  5, 14, 14, 15, 25, 26, 26, 22, 18, 26, 18, 25,
+   18, 22,  5, 12,  2,  5, 22, 21, 21, 22, 18, 17, 26,  6,  7, 14,
+   17, 22, 18, 18, 26, 14, 17,  6, 14,  6, 12, 24, 24,  6, 26, 15,
+    6, 21, 11, 21, 24,  9,  6,  9, 23, 26,  6, 10,  4,  4,  3,  3,
+    7, 25, 17, 16, 16, 22, 16, 16, 25, 17, 25,  2, 25, 24,  2, 15,
+   12, 15, 14,  2, 21, 14,  7, 15, 12, 17, 21,  1, 26, 10, 10,  1,
+   23, 15,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  0, 10, 11, 12,
+   13,  0, 14,  0,  0,  0,  0,  0, 15,  0, 16,  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, 17, 18, 19,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0, 17, 18, 19,  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, 20,
+    0, 21, 22, 23,  0,  0,  0, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+   33, 34,  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, 35,  0, 36,  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, 20,  0, 21, 22, 23,  0,  0,  0, 24,
-   25, 26, 27, 28, 29, 30, 31, 32, 33, 34,  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, 35,
-    0, 36,  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, 37,  0,  0,  0,  0,  0,  0,  0,
-    0,  0, 38, 39,  0,  0,  0,  0,  0,  0, 40, 41, 42,  0, 43,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  0,  0,
-    0,  0,  3,  0,  0,  0,  4,  5,  6,  7,  0,  8,  9, 10,  0, 11,
-   12, 13, 14, 15, 16, 17, 16, 18, 16, 19, 16, 19, 16, 19,  0, 19,
-   16, 20, 16, 19, 21, 19,  0, 22, 23, 24, 25, 26, 27, 28, 29, 30,
-   31,  0, 32,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 33,  0,  0,
-    0,  0,  0,  0, 34,  0,  0, 35,  0,  0, 36,  0, 37,  0,  0,  0,
-   38, 39, 40, 41, 42, 43, 44, 45, 46,  0,  0, 47,  0,  0,  0, 48,
-    0,  0,  0, 49,  0,  0,  0,  0,  0,  0,  0, 50,  0, 51,  0, 52,
-   53,  0, 54,  0,  0,  0,  0,  0,  0, 55, 56, 57,  0,  0,  0,  0,
-   58,  0,  0, 59, 60, 61, 62, 63,  0,  0, 64, 65,  0,  0,  0, 66,
-    0,  0,  0,  0, 67,  0,  0,  0, 68,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0, 69,  0,  0,  0, 70,  0, 71,  0,  0,
-   72,  0,  0, 73,  0,  0,  0,  0,  0,  0,  0,  0, 74,  0,  0,  0,
-    0,  0, 75, 76,  0, 77, 78,  0,  0, 79, 80,  0, 81, 62,  0, 82,
-   83,  0,  0, 84, 85, 86,  0,  0,  0, 87,  0, 88,  0,  0, 51, 89,
-   51,  0, 90,  0, 91,  0,  0,  0, 80,  0,  0,  0, 92, 93,  0, 94,
-   95, 96, 97,  0,  0,  0,  0,  0, 51,  0,  0,  0,  0, 98, 99,  0,
-    0,  0,  0,  0,  0,100,  0,  0,  0,  0,  0,101,102,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,103,  0,  0,104,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,105,106,  0,  0,107,  0,  0,  0,  0,  0,  0,
-  108,  0,109,  0,102,  0,  0,  0,  0,  0,110,111,  0,  0,  0,  0,
-    0,  0,  0,112,  0,  0,  0,  0,  0,  0,  0,113,  0,114,  0,  0,
-    0,  0,  0,  0,  1,  2,  3,  4,  5,  6,  7,  0,  8,  0,  0,  0,
-    0,  9, 10, 11, 12,  0,  0,  0,  0, 13,  0,  0, 14, 15,  0, 16,
-    0, 17, 18,  0,  0, 19,  0, 20, 21,  0,  0,  0,  0,  0, 22, 23,
-    0, 24, 25,  0,  0, 26,  0,  0,  0, 27,  0,  0, 28, 29, 30, 31,
-    0,  0,  0, 32, 33, 34,  0,  0, 33,  0,  0, 35, 33,  0,  0,  0,
-   33, 36,  0,  0,  0,  0,  0, 37, 38,  0,  0,  0,  0,  0,  0, 39,
-   40,  0,  0,  0,  0,  0,  0, 41, 42,  0,  0,  0,  0, 43,  0, 44,
-    0,  0,  0, 45, 46,  0,  0,  0, 47,  0,  0,  0,  0,  0,  0, 48,
-   49,  0,  0,  0,  0, 50,  0,  0,  0, 51,  0, 52,  0, 53,  0,  0,
-    0,  0, 54,  0,  0,  0,  0, 55,  0, 56,  0,  0,  0,  0, 57, 58,
-    0,  0,  0, 59, 60,  0,  0,  0,  0,  0,  0, 61, 52,  0, 62, 63,
-    0,  0, 64,  0,  0,  0, 65, 66,  0,  0,  0, 67,  0, 68, 69, 70,
-   71, 72,  1, 73,  0, 74, 75, 76,  0,  0, 77, 78,  0,  0,  0, 79,
-    0,  0,  1,  1,  0,  0, 80,  0,  0, 81,  0,  0,  0,  0, 77, 82,
-    0, 83,  0,  0,  0,  0,  0, 78, 84,  0, 85,  0, 52,  0,  1, 78,
-    0,  0, 86,  0,  0, 87,  0,  0,  0,  0,  0, 88, 57,  0,  0,  0,
-    0,  0,  0, 89, 90,  0,  0, 84,  0,  0, 33,  0,  0, 91,  0,  0,
-    0,  0, 92,  0,  0,  0,  0, 49,  0,  0, 93,  0,  0,  0,  0, 94,
-   95,  0,  0, 96,  0,  0, 97,  0,  0,  0, 98,  0,  0,  0, 99,  0,
-    0,  0,  0,100,101, 93,  0,  0,102,  0,  0,  0, 84,  0,  0,103,
-    0,  0,  0,104,105,  0,  0,106,107,  0,  0,  0,  0,  0,  0,108,
-    0,  0,109,  0,  0,  0,  0,110, 33,  0,111,112,113, 35,  0,  0,
-  114,  0,  0,  0,115,  0,  0,  0,  0,  0,  0,116,  0,  0,117,  0,
-    0,  0,  0,118, 88,  0,  0,  0,  0,  0, 57,  0,  0,  0,  0, 52,
-  119,  0,  0,  0,  0,120,  0,  0,121,  0,  0,  0,  0,119,  0,  0,
-  122,  0,  0,  0,  0,  0,  0,123,  0,  0,  0,124,  0,  0,  0,125,
-    0,126,  0,  0,  0,  0,127,128,129,  0,130,  0,131,  0,  0,  0,
-  132,133,134,  0, 77,  0,  0,  0,  0,  0, 35,  0,  0,  0,135,  0,
-    0,  0,136,  0,  0,137,  0,  0,138,  0,  0,  0,  0,  0,  0,  0,
-    1,  1,  1,  1,  1,  2,  3,  4,  5,  6,  7,  4,  4,  8,  9, 10,
-    1, 11, 12, 13, 14, 15, 16, 17, 18,  1,  1,  1, 19,  1,  0,  0,
-   20, 21, 22,  1, 23,  4, 21, 24, 25, 26, 27, 28, 29, 30,  0,  0,
-    1,  1, 31,  0,  0,  0, 32, 33, 34, 35,  1, 36, 37,  0,  0,  0,
-    0, 38,  1, 39, 14, 39, 40, 41, 42,  0,  0,  0, 43, 36, 44, 45,
-   21, 45, 46,  0,  0,  0, 19,  1, 21,  0,  0, 47,  0, 38, 48,  1,
-    1, 49, 49, 50,  0,  0, 51,  0,  0,  0, 52,  1,  0,  0, 38, 14,
-    4,  1,  1,  1, 53, 21, 43, 52, 54, 21, 35,  1,  0,  0,  0, 55,
-    0,  0,  0, 56, 57, 58,  0,  0,  0,  0,  0, 59,  0, 60,  0,  0,
-    0,  0, 61, 62,  0,  0, 63,  0,  0,  0, 64,  0,  0,  0, 65,  0,
-    0,  0, 66,  0,  0,  0, 67,  0,  0,  0, 68,  0,  0, 69, 70,  0,
-   71, 72, 73, 74, 75, 76,  0,  0,  0, 77,  0,  0,  0, 78, 79,  0,
-    0,  0,  0, 47,  0,  0,  0, 49,  0, 80,  0,  0,  0, 62,  0,  0,
-   63,  0,  0, 81,  0,  0, 82,  0,  0,  0, 83,  0,  0, 19, 84,  0,
-   62,  0,  0,  0,  0, 49,  1, 85,  1, 52, 15, 86, 36, 10, 21, 87,
-    0, 55,  0,  0,  0,  0, 19, 10,  1,  0,  0,  0,  0,  0, 88,  0,
-    0, 89,  0,  0, 88,  0,  0,  0,  0, 78,  0,  0, 87,  9, 12,  4,
-   90,  8, 91, 47,  0, 58, 50,  0, 21,  1, 21, 92, 93,  1,  1,  1,
-    1, 94, 95, 96, 97,  1, 98, 58, 81, 99,100,  4, 58,  0,  0,  0,
-    0,  0,  0, 19, 50,  0,  0,  0,  0,  0,  0, 61,  0,  0,101,102,
-    0,  0,103,  0,  0,  1,  1, 50,  0,  0,  0, 38,  0, 63,  0,  0,
-    0,  0,  0, 62,  0,  0,104, 68, 61,  0,  0,  0, 78,  0,  0,  0,
-  105,106, 58, 38, 81,  0,  0,  0,  0,  0,  0,107,  1, 14,  4, 12,
-   84,  0,  0,  0,  0, 38, 87,  0,  0,  0,  0,108,  0,  0,109, 61,
-    0,110,  0,  0,  0,  1,  0,  0,  0,  0, 19, 58,  0,  0,  0, 51,
-    0,111, 14, 52,112, 41,  0,  0, 62,  0,  0, 61,  0,  0,113,  0,
-   87,  0,  0,  0, 61, 62,  0,  0, 62,  0, 89,  0,  0,113,  0,  0,
-    0,  0,114,  0,  0,  0, 78, 55,  0, 38,  1, 58,  1, 58,  0,  0,
-   63, 89,  0,  0,115,  0,  0,  0, 55,  0,  0,  0,  0,115,  0,  0,
-    0,  0, 61,  0,  0,  0,  0, 79,  0, 61,  0,  0,  0,  0, 56,  0,
-   89, 80,  0,  0, 79,  0,  0,  0,  8, 91,  0,  0,  1, 87,  0,  0,
-  116,  0,  0,  0,  0,  0,  0,117,  0,118,119,120,121,  0,104,  4,
-  122, 49, 23,  0,  0,  0, 38, 50, 38, 58,  0,  0,  1, 87,  1,  1,
-    1,  1, 39,  1, 48,105, 87,  0,  0,  0,  0,  1,  0,  0,  0,123,
-    4,122,  0,  0,  0,  1,124,  0,  0,  0,  0,  0,230,230,230,230,
-  230,232,220,220,220,220,232,216,220,220,220,220,220,202,202,220,
-  220,220,220,202,202,220,220,220,  1,  1,  1,  1,  1,220,220,220,
-  220,230,230,230,230,240,230,220,220,220,230,230,230,220,220,  0,
-  230,230,230,220,220,220,220,230,232,220,220,230,233,234,234,233,
-  234,234,233,230,  0,  0,  0,230,  0,220,230,230,230,230,220,230,
-  230,230,222,220,230,230,220,220,230,222,228,230, 10, 11, 12, 13,
-   14, 15, 16, 17, 18, 19, 19, 20, 21, 22,  0, 23,  0, 24, 25,  0,
-  230,220,  0, 18, 30, 31, 32,  0,  0,  0,  0, 27, 28, 29, 30, 31,
-   32, 33, 34,230,230,220,220,230,220,230,230,220, 35,  0,  0,  0,
-    0,  0,230,230,230,  0,  0,230,230,  0,220,230,230,220,  0,  0,
-    0, 36,  0,  0,230,220,230,230,220,220,230,220,220,230,220,230,
-  220,230,230,  0,  0,220,  0,  0,230,230,  0,230,  0,230,230,230,
-  230,230,  0,  0,  0,220,220,220,230,220,220,220,230,230,  0,220,
-   27, 28, 29,230,  7,  0,  0,  0,  0,  9,  0,  0,  0,230,220,230,
-  230,  0,  0,  0,  0,  0,230,  0,  0, 84, 91,  0,  0,  0,  0,  9,
-    9,  0,  0,  0,  0,  0,  9,  0,103,103,  9,  0,107,107,107,107,
-  118,118,  9,  0,122,122,122,122,220,220,  0,  0,  0,220,  0,220,
-    0,216,  0,  0,  0,129,130,  0,132,  0,  0,  0,  0,  0,130,130,
-  130,130,  0,  0,130,  0,230,230,  9,  0,230,230,  0,  0,220,  0,
-    0,  0,  0,  7,  0,  9,  9,  0,  9,  9,  0,  0,  0,230,  0,  0,
-    0,228,  0,  0,  0,222,230,220,220,  0,  0,  0,230,  0,  0,220,
-  230,220,  0,220,230,230,230,  0,  0,  0,  9,  9,  0,  0,  7,  0,
-  230,  0,  1,  1,  1,  0,  0,  0,230,234,214,220,202,230,230,230,
-  230,230,232,228,228,220,218,230,233,220,230,220,230,230,  1,  1,
-    1,  1,  1,230,  0,  1,  1,230,220,230,  1,  1,  0,  0,218,228,
-  232,222,224,224,  0,  8,  8,  0,  0,  0,  0,220,230,  0,230,230,
-  220,  0,  0,230,  0,  0, 26,  0,  0,220,  0,230,230,  1,220,  0,
-    0,230,220,  0,  0,  0,220,220,  0,  0,230,220,  0,  9,  7,  0,
-    0,  7,  9,  0,  0,  0,  9,  7,  6,  6,  0,  0,  0,  0,  1,  0,
-    0,216,216,  1,  1,  1,  0,  0,  0,226,216,216,216,216,216,  0,
-  220,220,220,  0,232,232,220,230,230,230,  7,  0, 16, 17, 17, 33,
-   17, 49, 17, 17, 84, 97,135,145, 26, 17, 17, 17, 17, 17, 17, 17,
+   37,  0,  0,  0,  0,  0,  0,  0,  0,  0, 38, 39,  0,  0,  0,  0,
+    0,  0, 40, 41, 42,  0, 43,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  1,  2,  0,  0,  0,  0,  3,  0,  0,  0,  4,  5,
+    6,  7,  0,  8,  9, 10,  0, 11, 12, 13, 14, 15, 16, 17, 16, 18,
+   16, 19, 16, 19, 16, 19,  0, 19, 16, 20, 16, 19, 21, 19,  0, 22,
+   23, 24, 25, 26, 27, 28, 29, 30, 31,  0, 32,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0, 33,  0,  0,  0,  0,  0,  0, 34,  0,  0, 35,
+    0,  0, 36,  0, 37,  0,  0,  0, 38, 39, 40, 41, 42, 43, 44, 45,
+   46,  0,  0, 47,  0,  0,  0, 48,  0,  0,  0, 49,  0,  0,  0,  0,
+    0,  0,  0, 50,  0, 51,  0, 52, 53,  0, 54,  0,  0,  0,  0,  0,
+    0, 55, 56, 57,  0,  0,  0,  0, 58,  0,  0, 59, 60, 61, 62, 63,
+    0,  0, 64, 65,  0,  0,  0, 66,  0,  0,  0,  0, 67,  0,  0,  0,
+   68,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 69,
+    0,  0,  0, 70,  0, 71,  0,  0, 72,  0,  0, 73,  0,  0,  0,  0,
+    0,  0,  0,  0, 74,  0,  0,  0,  0,  0, 75, 76,  0, 77, 78,  0,
+    0, 79, 80,  0, 81, 62,  0, 82, 83,  0,  0, 84, 85, 86,  0,  0,
+    0, 87,  0, 88,  0,  0, 51, 89, 51,  0, 90,  0, 91,  0,  0,  0,
+   80,  0,  0,  0, 92, 93,  0, 94, 95, 96, 97,  0,  0,  0,  0,  0,
+   51,  0,  0,  0,  0, 98, 99,  0,  0,  0,  0,  0,  0,100,  0,  0,
+    0,  0,  0,101,102,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,103,
+    0,  0,104,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,105,106,  0,
+    0,107,  0,  0,  0,  0,  0,  0,108,  0,109,  0,102,  0,  0,  0,
+    0,  0,110,111,  0,  0,  0,  0,  0,  0,  0,112,  0,  0,  0,  0,
+    0,  0,  0,113,  0,114,  0,  0,  0,  0,  0,  0,  1,  2,  3,  4,
+    5,  6,  7,  0,  8,  0,  0,  0,  0,  9, 10, 11, 12,  0,  0,  0,
+    0, 13,  0,  0, 14, 15,  0, 16,  0, 17, 18,  0,  0, 19,  0, 20,
+   21,  0,  0,  0,  0,  0, 22, 23,  0, 24, 25,  0,  0, 26,  0,  0,
+    0, 27,  0,  0, 28, 29, 30, 31,  0,  0,  0, 32, 33, 34,  0,  0,
+   33,  0,  0, 35, 33,  0,  0,  0, 33, 36,  0,  0,  0,  0,  0, 37,
+   38,  0,  0,  0,  0,  0,  0, 39, 40,  0,  0,  0,  0,  0,  0, 41,
+   42,  0,  0,  0,  0, 43,  0, 44,  0,  0,  0, 45, 46,  0,  0,  0,
+   47,  0,  0,  0,  0,  0,  0, 48, 49,  0,  0,  0,  0, 50,  0,  0,
+    0, 51,  0, 52,  0, 53,  0,  0,  0,  0, 54,  0,  0,  0,  0, 55,
+    0, 56,  0,  0,  0,  0, 57, 58,  0,  0,  0, 59, 60,  0,  0,  0,
+    0,  0,  0, 61, 52,  0, 62, 63,  0,  0, 64,  0,  0,  0, 65, 66,
+    0,  0,  0, 67,  0, 68, 69, 70, 71, 72,  1, 73,  0, 74, 75, 76,
+    0,  0, 77, 78,  0,  0,  0, 79,  0,  0,  1,  1,  0,  0, 80,  0,
+    0, 81,  0,  0,  0,  0, 77, 82,  0, 83,  0,  0,  0,  0,  0, 78,
+   84,  0, 85,  0, 52,  0,  1, 78,  0,  0, 86,  0,  0, 87,  0,  0,
+    0,  0,  0, 88, 57,  0,  0,  0,  0,  0,  0, 89, 90,  0,  0, 84,
+    0,  0, 33,  0,  0, 91,  0,  0,  0,  0, 92,  0,  0,  0,  0, 49,
+    0,  0, 93,  0,  0,  0,  0, 94, 95,  0,  0, 96,  0,  0, 97,  0,
+    0,  0, 98,  0,  0,  0, 99,  0,  0,  0,  0,100,101, 93,  0,  0,
+  102,  0,  0,  0, 84,  0,  0,103,  0,  0,  0,104,105,  0,  0,106,
+  107,  0,  0,  0,  0,  0,  0,108,  0,  0,109,  0,  0,  0,  0,110,
+   33,  0,111,112,113, 35,  0,  0,114,  0,  0,  0,115,  0,  0,  0,
+    0,  0,  0,116,  0,  0,117,  0,  0,  0,  0,118, 88,  0,  0,  0,
+    0,  0, 57,  0,  0,  0,  0, 52,119,  0,  0,  0,  0,120,  0,  0,
+  121,  0,  0,  0,  0,119,  0,  0,122,  0,  0,  0,  0,  0,  0,123,
+    0,  0,  0,124,  0,  0,  0,125,  0,126,  0,  0,  0,  0,127,128,
+  129,  0,130,  0,131,  0,  0,  0,132,133,134,  0, 77,  0,  0,  0,
+    0,  0, 35,  0,  0,  0,135,  0,  0,  0,136,  0,  0,137,  0,  0,
+  138,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  1,  2,  3,  4,
+    5,  6,  7,  4,  4,  8,  9, 10,  1, 11, 12, 13, 14, 15, 16, 17,
+   18,  1,  1,  1, 19,  1,  0,  0, 20, 21, 22,  1, 23,  4, 21, 24,
+   25, 26, 27, 28, 29, 30,  0,  0,  1,  1, 31,  0,  0,  0, 32, 33,
+   34, 35,  1, 36, 37,  0,  0,  0,  0, 38,  1, 39, 14, 39, 40, 41,
+   42,  0,  0,  0, 43, 36, 44, 45, 21, 45, 46,  0,  0,  0, 19,  1,
+   21,  0,  0, 47,  0, 38, 48,  1,  1, 49, 49, 50,  0,  0, 51,  0,
+    0,  0, 52,  1,  0,  0, 38, 14,  4,  1,  1,  1, 53, 21, 43, 52,
+   54, 21, 35,  1,  0,  0,  0, 55,  0,  0,  0, 56, 57, 58,  0,  0,
+    0,  0,  0, 59,  0, 60,  0,  0,  0,  0, 61, 62,  0,  0, 63,  0,
+    0,  0, 64,  0,  0,  0, 65,  0,  0,  0, 66,  0,  0,  0, 67,  0,
+    0,  0, 68,  0,  0, 69, 70,  0, 71, 72, 73, 74, 75, 76,  0,  0,
+    0, 77,  0,  0,  0, 78, 79,  0,  0,  0,  0, 47,  0,  0,  0, 49,
+    0, 80,  0,  0,  0, 62,  0,  0, 63,  0,  0, 81,  0,  0, 82,  0,
+    0,  0, 83,  0,  0, 19, 84,  0, 62,  0,  0,  0,  0, 49,  1, 85,
+    1, 52, 15, 86, 36, 10, 21, 87,  0, 55,  0,  0,  0,  0, 19, 10,
+    1,  0,  0,  0,  0,  0, 88,  0,  0, 89,  0,  0, 88,  0,  0,  0,
+    0, 78,  0,  0, 87,  9, 12,  4, 90,  8, 91, 47,  0, 58, 50,  0,
+   21,  1, 21, 92, 93,  1,  1,  1,  1, 94, 95, 96, 97,  1, 98, 58,
+   81, 99,100,  4, 58,  0,  0,  0,  0,  0,  0, 19, 50,  0,  0,  0,
+    0,  0,  0, 61,  0,  0,101,102,  0,  0,103,  0,  0,  1,  1, 50,
+    0,  0,  0, 38,  0, 63,  0,  0,  0,  0,  0, 62,  0,  0,104, 68,
+   61,  0,  0,  0, 78,  0,  0,  0,105,106, 58, 38, 81,  0,  0,  0,
+    0,  0,  0,107,  1, 14,  4, 12, 84,  0,  0,  0,  0, 38, 87,  0,
+    0,  0,  0,108,  0,  0,109, 61,  0,110,  0,  0,  0,  1,  0,  0,
+    0,  0, 19, 58,  0,  0,  0, 51,  0,111, 14, 52,112, 41,  0,  0,
+   62,  0,  0, 61,  0,  0,113,  0, 87,  0,  0,  0, 61, 62,  0,  0,
+   62,  0, 89,  0,  0,113,  0,  0,  0,  0,114,  0,  0,  0, 78, 55,
+    0, 38,  1, 58,  1, 58,  0,  0, 63, 89,  0,  0,115,  0,  0,  0,
+   55,  0,  0,  0,  0,115,  0,  0,  0,  0, 61,  0,  0,  0,  0, 79,
+    0, 61,  0,  0,  0,  0, 56,  0, 89, 80,  0,  0, 79,  0,  0,  0,
+    8, 91,  0,  0,  1, 87,  0,  0,116,  0,  0,  0,  0,  0,  0,117,
+    0,118,119,120,121,  0,104,  4,122, 49, 23,  0,  0,  0, 38, 50,
+   38, 58,  0,  0,  1, 87,  1,  1,  1,  1, 39,  1, 48,105, 87,  0,
+    0,  0,  0,  1,  0,  0,  0,123,  4,122,  0,  0,  0,  1,124,  0,
+    0,  0,  0,  0,230,230,230,230,230,232,220,220,220,220,232,216,
+  220,220,220,220,220,202,202,220,220,220,220,202,202,220,220,220,
+    1,  1,  1,  1,  1,220,220,220,220,230,230,230,230,240,230,220,
+  220,220,230,230,230,220,220,  0,230,230,230,220,220,220,220,230,
+  232,220,220,230,233,234,234,233,234,234,233,230,  0,  0,  0,230,
+    0,220,230,230,230,230,220,230,230,230,222,220,230,230,220,220,
+  230,222,228,230, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20,
+   21, 22,  0, 23,  0, 24, 25,  0,230,220,  0, 18, 30, 31, 32,  0,
+    0,  0,  0, 27, 28, 29, 30, 31, 32, 33, 34,230,230,220,220,230,
+  220,230,230,220, 35,  0,  0,  0,  0,  0,230,230,230,  0,  0,230,
+  230,  0,220,230,230,220,  0,  0,  0, 36,  0,  0,230,220,230,230,
+  220,220,230,220,220,230,220,230,220,230,230,  0,  0,220,  0,  0,
+  230,230,  0,230,  0,230,230,230,230,230,  0,  0,  0,220,220,220,
+  230,220,220,220,230,230,  0,220, 27, 28, 29,230,  7,  0,  0,  0,
+    0,  9,  0,  0,  0,230,220,230,230,  0,  0,  0,  0,  0,230,  0,
+    0, 84, 91,  0,  0,  0,  0,  9,  9,  0,  0,  0,  0,  0,  9,  0,
+  103,103,  9,  0,107,107,107,107,118,118,  9,  0,122,122,122,122,
+  220,220,  0,  0,  0,220,  0,220,  0,216,  0,  0,  0,129,130,  0,
+  132,  0,  0,  0,  0,  0,130,130,130,130,  0,  0,130,  0,230,230,
+    9,  0,230,230,  0,  0,220,  0,  0,  0,  0,  7,  0,  9,  9,  0,
+    9,  9,  0,  0,  0,230,  0,  0,  0,228,  0,  0,  0,222,230,220,
+  220,  0,  0,  0,230,  0,  0,220,230,220,  0,220,230,230,230,  0,
+    0,  0,  9,  9,  0,  0,  7,  0,230,  0,  1,  1,  1,  0,  0,  0,
+  230,234,214,220,202,230,230,230,230,230,232,228,228,220,218,230,
+  233,220,230,220,230,230,  1,  1,  1,  1,  1,230,  0,  1,  1,230,
+  220,230,  1,  1,  0,  0,218,228,232,222,224,224,  0,  8,  8,  0,
+    0,  0,  0,220,230,  0,230,230,220,  0,  0,230,  0,  0, 26,  0,
+    0,220,  0,230,230,  1,220,  0,  0,230,220,  0,  0,  0,220,220,
+    0,  0,230,220,  0,  9,  7,  0,  0,  7,  9,  0,  0,  0,  9,  7,
+    6,  6,  0,  0,  0,  0,  1,  0,  0,216,216,  1,  1,  1,  0,  0,
+    0,226,216,216,216,216,216,  0,220,220,220,  0,232,232,220,230,
+  230,230,  7,  0, 16, 17, 17, 33, 17, 49, 17, 17, 84, 97,135,145,
+   26, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
-   17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,177,  0,  1,  2,  3,
-    3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,
-    4,  3,  3,  3,  3,  3,  5,  3,  3,  3,  3,  3,  6,  7,  8,  3,
-    3,  3,  3,  3,  9, 10, 11, 12, 13,  3,  3,  3,  3,  3,  3,  3,
-    3, 14,  3, 15,  3,  3,  3,  3,  3,  3, 16, 17, 18, 19, 20, 21,
-    3,  3,  3, 22, 23, 24,  3,  3,  3,  3,  3,  3, 25,  3,  3,  3,
-    3,  3,  3,  3,  3, 26,  3,  3, 27, 28,  0,  1,  0,  0,  0,  0,
-    0,  1,  0,  2,  0,  0,  0,  3,  0,  0,  0,  3,  0,  0,  0,  0,
-    0,  4,  0,  5,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  6,  0,  0,  0,  7,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  8,  9,  0,  0,  0,  0,  0,  0,  9,  0,  9,  0,  0,
-    0,  0,  0,  0,  0, 10, 11, 12, 13,  0,  0, 14, 15, 16,  6,  0,
-   17, 18, 19, 19, 19, 20, 21, 22, 23, 24, 19, 25,  0, 26, 27, 19,
-   19, 28, 29, 30,  0, 31,  0,  0,  0,  8,  0,  0,  0,  0,  0,  0,
-    0, 19, 28,  0, 32, 33,  9, 34, 35, 19,  0,  0, 36, 37, 38, 39,
-   40, 19,  0, 41, 42, 43, 44, 31,  0,  1, 45, 42,  0,  0,  0,  0,
-    0, 32, 14, 14,  0,  0,  0,  0, 14,  0,  0, 46, 47, 47, 47, 47,
-   48, 49, 47, 47, 47, 47, 50, 51, 52, 53, 43, 21,  0,  0,  0,  0,
-    0,  0,  0, 54,  6, 55,  0, 14, 19,  1,  0,  0,  0,  0, 56, 57,
-    0,  0,  0,  0,  0, 19, 58, 31,  0,  0,  0,  0,  0,  0,  0, 59,
-   14,  0,  0,  0,  0,  1,  0,  2,  0,  0,  0,  3,  0,  0,  0, 60,
-   61,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,  0,  2,  3,
-    0,  4,  5,  0,  0,  6,  0,  0,  0,  7,  0,  0,  0,  1,  1,  0,
-    0,  8,  9,  0,  8,  9,  0,  0,  0,  0,  8,  9, 10, 11, 12,  0,
-    0,  0, 13,  0,  0,  0,  0, 14, 15, 16, 17,  0,  0,  0,  1,  0,
-    0, 18, 19,  0,  0,  0, 20,  0,  0,  0,  1,  1,  1,  1,  0,  1,
-    1,  1,  1,  1,  1,  1,  0,  8, 21,  9,  0,  0, 22,  0,  0,  0,
-    0,  1,  0, 23, 24, 25,  0,  0, 26,  0,  0,  0,  8, 21, 27,  0,
-    1,  0,  0,  1,  1,  1,  1,  0,  1, 28, 29, 30,  0, 31, 32, 20,
-    1,  1,  0,  0,  0,  8, 21,  9,  1,  4,  5,  0,  0,  0, 33,  9,
-    0,  1,  1,  1,  0,  8, 21, 21, 21, 21, 34,  1, 35, 21, 21, 21,
-    9, 36,  0,  0, 37, 38,  1,  0, 39,  0,  0,  0,  1,  0,  1,  0,
-    0,  0,  0,  8, 21,  9,  1,  0,  0,  0, 40,  0,  8, 21, 21, 21,
-   21, 21, 21, 21, 21,  9,  0,  1,  1,  1,  1,  8, 21, 21, 21,  9,
-    0,  0,  0, 41,  0, 42, 43,  0,  0,  0,  1, 44,  0,  0,  0, 45,
-    8,  9,  1,  0,  0,  0,  8, 21, 21, 21,  9,  0,  1,  0,  1,  1,
-    8, 21, 21,  9,  0,  4,  5,  8,  9,  1,  0,  0,  0,  1,  2,  3,
-    4,  5,  6,  7,  7,  8,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
-    9, 10, 11, 11, 11, 11, 12, 13, 13, 13, 13, 14, 15, 16, 17, 18,
-   19, 20, 21, 13, 22, 13, 13, 13, 13, 23, 24, 24, 25, 26, 13, 13,
-   13, 27, 28, 29, 13, 30, 31, 32, 33, 34, 35, 36,  7,  7,  7,  7,
-    7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
-   37,  7, 38, 39,  7, 40,  7,  7,  7, 41, 13, 42,  7,  7, 43,  7,
-   44, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+   17, 17, 17,177,  0,  1,  2,  3,  3,  3,  3,  3,  3,  3,  3,  3,
+    3,  3,  3,  3,  3,  3,  3,  3,  4,  3,  3,  3,  3,  3,  5,  3,
+    3,  3,  3,  3,  6,  7,  8,  3,  3,  3,  3,  3,  9, 10, 11, 12,
+   13,  3,  3,  3,  3,  3,  3,  3,  3, 14,  3, 15,  3,  3,  3,  3,
+    3,  3, 16, 17, 18, 19, 20, 21,  3,  3,  3, 22, 23, 24,  3,  3,
+    3,  3,  3,  3, 25,  3,  3,  3,  3,  3,  3,  3,  3, 26,  3,  3,
+   27, 28,  0,  1,  0,  0,  0,  0,  0,  1,  0,  2,  0,  0,  0,  3,
+    0,  0,  0,  3,  0,  0,  0,  0,  0,  4,  0,  5,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  6,  0,  0,  0,  7,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  8,  9,  0,  0,  0,
+    0,  0,  0,  9,  0,  9,  0,  0,  0,  0,  0,  0,  0, 10, 11, 12,
+   13,  0,  0, 14, 15, 16,  6,  0, 17, 18, 19, 19, 19, 20, 21, 22,
+   23, 24, 19, 25,  0, 26, 27, 19, 19, 28, 29, 30,  0, 31,  0,  0,
+    0,  8,  0,  0,  0,  0,  0,  0,  0, 19, 28,  0, 32, 33,  9, 34,
+   35, 19,  0,  0, 36, 37, 38, 39, 40, 19,  0, 41, 42, 43, 44, 31,
+    0,  1, 45, 42,  0,  0,  0,  0,  0, 32, 14, 14,  0,  0,  0,  0,
+   14,  0,  0, 46, 47, 47, 47, 47, 48, 49, 47, 47, 47, 47, 50, 51,
+   52, 53, 43, 21,  0,  0,  0,  0,  0,  0,  0, 54,  6, 55,  0, 14,
+   19,  1,  0,  0,  0,  0, 56, 57,  0,  0,  0,  0,  0, 19, 58, 31,
+    0,  0,  0,  0,  0,  0,  0, 59, 14,  0,  0,  0,  0,  1,  0,  2,
+    0,  0,  0,  3,  0,  0,  0, 60, 61,  0,  0,  0,  0,  0,  0,  0,
+    1,  0,  0,  0,  0,  0,  2,  3,  0,  4,  5,  0,  0,  6,  0,  0,
+    0,  7,  0,  0,  0,  1,  1,  0,  0,  8,  9,  0,  8,  9,  0,  0,
+    0,  0,  8,  9, 10, 11, 12,  0,  0,  0, 13,  0,  0,  0,  0, 14,
+   15, 16, 17,  0,  0,  0,  1,  0,  0, 18, 19,  0,  0,  0, 20,  0,
+    0,  0,  1,  1,  1,  1,  0,  1,  1,  1,  1,  1,  1,  1,  0,  8,
+   21,  9,  0,  0, 22,  0,  0,  0,  0,  1,  0, 23, 24, 25,  0,  0,
+   26,  0,  0,  0,  8, 21, 27,  0,  1,  0,  0,  1,  1,  1,  1,  0,
+    1, 28, 29, 30,  0, 31, 32, 20,  1,  1,  0,  0,  0,  8, 21,  9,
+    1,  4,  5,  0,  0,  0, 33,  9,  0,  1,  1,  1,  0,  8, 21, 21,
+   21, 21, 34,  1, 35, 21, 21, 21,  9, 36,  0,  0, 37, 38,  1,  0,
+   39,  0,  0,  0,  1,  0,  1,  0,  0,  0,  0,  8, 21,  9,  1,  0,
+    0,  0, 40,  0,  8, 21, 21, 21, 21, 21, 21, 21, 21,  9,  0,  1,
+    1,  1,  1,  8, 21, 21, 21,  9,  0,  0,  0, 41,  0, 42, 43,  0,
+    0,  0,  1, 44,  0,  0,  0, 45,  8,  9,  1,  0,  0,  0,  8, 21,
+   21, 21,  9,  0,  1,  0,  1,  1,  8, 21, 21,  9,  0,  4,  5,  8,
+    9,  1,  0,  0,  0,  1,  2,  3,  4,  5,  6,  7,  7,  8,  7,  7,
+    7,  7,  7,  7,  7,  7,  7,  7,  9, 10, 11, 11, 11, 11, 12, 13,
+   13, 13, 13, 14, 15, 16, 17, 18, 19, 20, 21, 13, 22, 13, 13, 13,
+   13, 23, 24, 24, 25, 26, 13, 13, 13, 27, 28, 29, 13, 30, 31, 32,
+   33, 34, 35, 36,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,  7,
+    7,  7,  7,  7,  7,  7,  7,  7, 37,  7, 38, 39,  7, 40,  7,  7,
+    7, 41, 13, 42,  7,  7, 43,  7, 44, 13, 13, 13, 13, 13, 13, 13,
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
@@ -3479,221 +3481,221 @@
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
-   13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 45,  0,  0,  1,
-    2,  2,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
-   16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
-   32, 32, 33, 34, 35, 36, 37, 37, 37, 37, 37, 38, 39, 40, 41, 42,
-   43, 44, 45, 46, 47, 48, 49, 50, 51, 52,  2,  2, 53, 54, 55, 56,
-   57, 58, 59, 59, 59, 59, 60, 59, 59, 59, 59, 59, 59, 59, 61, 61,
-   59, 59, 59, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
-   74, 75, 76, 77, 78, 59, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
+   13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+   13, 13, 13, 13, 45,  0,  0,  1,  2,  2,  2,  3,  4,  5,  6,  7,
+    8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+   24, 25, 26, 27, 28, 29, 30, 31, 32, 32, 33, 34, 35, 36, 37, 37,
+   37, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+   51, 52,  2,  2, 53, 54, 55, 56, 57, 58, 59, 59, 59, 59, 60, 59,
+   59, 59, 59, 59, 59, 59, 61, 61, 59, 59, 59, 59, 62, 63, 64, 65,
+   66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 59, 70, 70,
    70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
-   70, 70, 70, 70, 70, 70, 70, 70, 70, 79, 70, 70, 70, 70, 80, 80,
-   80, 80, 80, 80, 80, 80, 80, 81, 82, 82, 83, 84, 85, 86, 87, 88,
-   89, 90, 91, 92, 93, 94, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+   70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
+   70, 79, 70, 70, 70, 70, 80, 80, 80, 80, 80, 80, 80, 80, 80, 81,
+   82, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 32, 32,
    32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
-   32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 95, 96, 96,
-   96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-   70, 70, 97, 98, 99,100,101,101,102,103,104,105,106,107,108,109,
-  110,111, 96,112,113,114,115,116,117,118,119,119,120,121,122,123,
-  124,125,126,127,128,129,130,131,132, 96,133,134,135,136,137,138,
-  139,140,141,142,143, 96,144,145, 96,146,147,148,149, 96,150,151,
-  152,153,154,155,156, 96,157,158,159,160, 96,161,162,163,164,164,
-  164,164,164,164,164,165,166,164,167, 96, 96, 96, 96, 96, 96, 96,
-   96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,168,169,169,
-  169,169,169,169,169,169,170, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-   96, 96, 96, 96, 96, 96,171,171,171,171,172, 96, 96, 96,173,173,
-  173,173,174,175,176,177, 96, 96, 96, 96,178,179,180,181,182,182,
+   32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
+   32, 32, 32, 32, 32, 95, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
+   96, 96, 96, 96, 96, 96, 96, 96, 70, 70, 97, 98, 99,100,101,101,
+  102,103,104,105,106,107,108,109,110,111, 96,112,113,114,115,116,
+  117,118,119,119,120,121,122,123,124,125,126,127,128,129,130,131,
+  132, 96,133,134,135,136,137,138,139,140,141,142,143, 96,144,145,
+   96,146,147,148,149, 96,150,151,152,153,154,155,156, 96,157,158,
+  159,160, 96,161,162,163,164,164,164,164,164,164,164,165,166,164,
+  167, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
+   96, 96, 96, 96, 96,168,169,169,169,169,169,169,169,169,170, 96,
+   96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,171,171,
+  171,171,172, 96, 96, 96,173,173,173,173,174,175,176,177, 96, 96,
+   96, 96,178,179,180,181,182,182,182,182,182,182,182,182,182,182,
   182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,
-  182,182,182,182,182,182,182,182,182,182,182,182,182,183,182,182,
-  182,182,182,182,184,184,184,185,186, 96, 96, 96, 96, 96, 96, 96,
-   96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,187,188,189,
-  190,191,191,192, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
-   96, 96, 96, 96, 96, 96,193,194, 96, 96, 96, 96, 96, 96, 96, 96,
-   96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,195,196, 59,197,
-  198,199,200,201,202, 96,203,204,205, 59, 59,206, 59,207,208,208,
-  208,208,208,209, 96, 96, 96, 96, 96, 96, 96, 96,210, 96,211,212,
-  213, 96, 96,214, 96, 96, 96,215, 96, 96, 96, 96, 96,216,217,218,
-  219, 96, 96, 96, 96, 96,220,221,222, 96,223,224, 96, 96,225,226,
-   59,227,228, 96, 59, 59, 59, 59, 59, 59, 59,229,230,231,232,233,
-   59, 59,234,235, 59,236, 96, 96, 96, 96, 96, 96, 96, 96, 70, 70,
-   70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,237, 70, 70, 70, 70,
-   70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,238, 70,239, 70,
+  182,182,182,182,182,183,182,182,182,182,182,182,184,184,184,185,
+  186, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
+   96, 96, 96, 96, 96,187,188,189,190,191,191,192, 96, 96, 96, 96,
+   96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,193,194,
+   96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
+   96, 96, 96, 96,195,196, 59,197,198,199,200,201,202, 96,203,204,
+  205, 59, 59,206, 59,207,208,208,208,208,208,209, 96, 96, 96, 96,
+   96, 96, 96, 96,210, 96,211,212,213, 96, 96,214, 96, 96, 96,215,
+   96, 96, 96, 96, 96,216,217,218,219, 96, 96, 96, 96, 96,220,221,
+  222, 96,223,224, 96, 96,225,226, 59,227,228, 96, 59, 59, 59, 59,
+   59, 59, 59,229,230,231,232,233, 59, 59,234,235, 59,236, 96, 96,
+   96, 96, 96, 96, 96, 96, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
+   70, 70, 70,237, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
+   70, 70, 70, 70,238, 70,239, 70, 70, 70, 70, 70, 70, 70, 70, 70,
    70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
-   70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,240, 70, 70, 70, 70,
-   70, 70, 70, 70, 70,241, 96, 96, 96, 96, 96, 96, 96, 96, 70, 70,
-   70, 70,242, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 70, 70,
-   70, 70, 70, 70,243, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,
-   70, 70, 70, 70, 70,244, 96, 96, 96, 96, 96, 96, 96, 96,245, 96,
-  246,247,  0,  1,  2,  2,  0,  1,  2,  2,  2,  3,  4,  5,  0,  0,
-    0,  0,  0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,  0,  0,  0,
-   19,  0, 19,  0,  0,  0,  0,  0, 26, 26,  1,  1,  1,  1,  9,  9,
-    9,  9,  0,  9,  9,  9,  2,  2,  9,  9,  9,  9,  0,  9,  2,  2,
-    2,  2,  9,  0,  9,  0,  9,  9,  9,  2,  9,  2,  9,  9,  9,  9,
-    2,  9,  9,  9, 55, 55, 55, 55, 55, 55,  6,  6,  6,  6,  6,  1,
-    1,  6,  2,  4,  4,  4,  4,  4,  4,  4,  4,  4,  4,  2,  2, 14,
-   14, 14, 14, 14, 14, 14, 14, 14, 14,  2,  2,  2,  2, 14, 14,  2,
-    2,  2,  3,  3,  3,  3,  3,  0,  3,  3,  0,  3,  3,  3,  3,  3,
-    3,  0,  3,  3,  3,  1,  1,  1,  3,  3,  1,  3,  3,  3, 37, 37,
-   37, 37, 37, 37,  2, 37, 37, 37, 37,  2,  2, 37, 37, 37, 38, 38,
-   38, 38, 38, 38,  2,  2, 64, 64, 64, 64, 64, 64, 64,  2,  2, 64,
-   64, 64, 90, 90, 90, 90, 90, 90,  2,  2, 90, 90, 90,  2, 95, 95,
-   95, 95,  2,  2, 95,  2,  3,  3,  3,  2,  3,  3,  2,  2,  3,  3,
-    0,  3,  7,  7,  7,  7,  7,  1,  1,  1,  1,  7,  7,  7,  0,  0,
-    7,  7,  5,  5,  5,  5,  2,  5,  5,  5,  5,  2,  2,  5,  5,  2,
-    5,  5,  5,  2,  5,  2,  2,  2,  5,  5,  5,  5,  2,  2,  5,  5,
-    5,  2,  2,  2,  2,  5,  5,  5,  2,  5,  2, 11, 11, 11, 11, 11,
-   11,  2,  2,  2,  2, 11, 11,  2,  2, 11, 11, 11, 11, 11, 11,  2,
-   11, 11,  2, 11, 11,  2, 11, 11,  2,  2,  2, 11,  2,  2, 11,  2,
-   11,  2,  2,  2, 11, 11,  2, 10, 10, 10, 10, 10, 10, 10, 10, 10,
-    2, 10, 10,  2, 10, 10, 10, 10,  2,  2, 10,  2,  2,  2,  2,  2,
-   10, 10,  2, 21, 21, 21, 21, 21, 21, 21, 21,  2,  2, 21, 21,  2,
-   21, 21, 21, 21,  2,  2, 21, 21,  2, 21,  2,  2, 21, 21,  2,  2,
-   22, 22,  2, 22, 22, 22, 22, 22, 22,  2, 22,  2, 22, 22, 22, 22,
-    2,  2,  2, 22, 22,  2,  2,  2,  2, 22, 22,  2,  2,  2, 22, 22,
-   22, 22, 23, 23, 23, 23, 23,  2, 23, 23, 23, 23,  2,  2,  2, 23,
-   23,  2, 23, 23, 23,  2,  2, 23,  2,  2,  2,  2, 23, 23,  2,  2,
-    2, 23, 16, 16, 16, 16, 16,  2, 16, 16,  2, 16, 16, 16, 16, 16,
-    2,  2,  2, 16, 16,  2,  2,  2, 16, 16, 20, 20, 20, 20, 20,  2,
-   20, 20,  2,  2, 20, 20,  2, 36, 36, 36, 36, 36, 36, 36, 36, 36,
-   36,  2,  2,  2, 36, 36, 36, 36,  2, 36,  2, 36,  2,  2,  2,  2,
-   36,  2,  2,  2,  2, 36, 36,  2, 36,  2, 36,  2,  2,  2,  2, 24,
-   24, 24, 24, 24, 24, 24, 24, 24, 24,  2,  2,  2,  2,  0,  2, 18,
-   18,  2, 18,  2, 18, 18, 18, 18, 18,  2, 18, 18, 18, 18,  2, 18,
-    2, 18, 18, 18,  2,  2, 18,  2, 18,  2, 25, 25, 25, 25,  2, 25,
-   25, 25, 25,  2,  2,  2, 25,  2, 25, 25, 25,  0,  0,  0,  0, 25,
-   25,  2, 33, 33, 33, 33,  8,  8,  8,  8,  8,  8,  2,  8,  2,  8,
-    2,  2,  8,  8,  8,  0, 12, 12, 12, 12, 30, 30, 30, 30, 30,  2,
-   30, 30, 30, 30,  2,  2, 30, 30, 30,  2,  2, 30, 30, 30, 30,  2,
-    2,  2, 29, 29, 29, 29, 29, 29,  2,  2, 28, 28, 28, 28, 34, 34,
-   34, 34, 34,  2,  2,  2, 35, 35, 35, 35, 35, 35, 35,  0,  0,  0,
-   35, 35, 35,  2,  2,  2, 45, 45, 45, 45, 45, 45,  2,  2,  2,  2,
-    2, 45, 44, 44, 44, 44, 44,  0,  0,  2, 43, 43, 43, 43, 46, 46,
-   46, 46, 46,  2, 46, 46, 31, 31, 31, 31, 31, 31,  2,  2, 32, 32,
-    0,  0, 32,  0, 32, 32, 32, 32, 32, 32, 32, 32,  2,  2, 32,  2,
-    2,  2, 32, 32, 32,  2, 28, 28,  2,  2, 48, 48, 48, 48, 48, 48,
-   48,  2, 48,  2,  2,  2, 52, 52, 52, 52, 52, 52,  2,  2, 52,  2,
-    2,  2, 58, 58, 58, 58, 58, 58,  2,  2, 58, 58, 58,  2,  2,  2,
-   58, 58, 54, 54, 54, 54,  2,  2, 54, 54, 91, 91, 91, 91, 91, 91,
-   91,  2, 91,  2,  2, 91, 91, 91,  2,  2,  1,  1,  1,  2, 62, 62,
-   62, 62, 62,  2,  2,  2, 62, 62, 62,  2, 76, 76, 76, 76, 93, 93,
-   93, 93, 70, 70, 70, 70,  2,  2,  2, 70, 70, 70,  2,  2,  2, 70,
-   70, 70, 73, 73, 73, 73,  6,  2,  2,  2,  8,  8,  8,  2,  2,  8,
-    8,  8,  1,  1,  1,  0,  1,  0,  1,  1,  1,  0,  0,  0,  0,  1,
-    0,  0,  1,  1,  0,  2, 19, 19,  9,  9,  9,  9,  9,  6, 19,  9,
-    9,  9,  9,  9, 19, 19,  9,  9,  9, 19,  6, 19, 19, 19, 19, 19,
-   19,  9,  9,  9,  2,  2,  2,  9,  2,  9,  2,  9,  9,  9,  1,  1,
-    0,  0,  0,  2,  0,  0,  0, 19,  2,  2,  0,  0,  0, 19,  0,  0,
-    0,  2, 19,  2,  2,  2,  0,  2,  2,  2,  1,  2,  2,  2,  0,  0,
-    9,  0,  0,  0, 19, 19, 27, 27, 27, 27,  2,  2,  0,  0,  0,  0,
-    2,  0, 56, 56, 56, 56,  2, 55, 55, 55, 61, 61, 61, 61,  2,  2,
-    2, 61, 61,  2,  2,  2,  0,  0,  2,  2, 13, 13, 13, 13, 13, 13,
-    2, 13, 13, 13,  2,  2,  0, 13,  0, 13,  0, 13, 13, 13, 13, 13,
-    1,  1,  1,  1, 12, 12,  2, 15, 15, 15, 15, 15, 15, 15, 15, 15,
-   15,  2,  2,  1,  1,  0,  0, 15, 15, 15,  0, 17, 17, 17, 17, 17,
-   17, 17, 17, 17, 17,  0,  2, 26, 26, 26, 26, 26, 26, 26,  2, 12,
-   12, 12, 12, 12, 12,  2, 12, 12, 12,  0, 39, 39, 39, 39, 39,  2,
-    2,  2, 39, 39, 39,  2, 86, 86, 86, 86, 77, 77, 77, 77, 79, 79,
-   79, 79, 19, 19, 19,  2, 19, 19,  2, 19,  2, 19, 19, 19, 19, 19,
-    2,  2,  2,  2, 19, 19, 60, 60, 60, 60, 60,  2,  2,  2, 65, 65,
-   65, 65, 75, 75, 75, 75, 75, 75,  2,  2,  2,  2, 75, 75, 69, 69,
-   69, 69, 69, 69,  0, 69, 74, 74, 74, 74,  2,  2,  2, 74, 12,  2,
-    2,  2, 84, 84, 84, 84, 84, 84,  2,  0, 84, 84,  2,  2,  2,  2,
-   84, 84, 33, 33, 33,  2, 68, 68, 68, 68, 68, 68, 68,  2, 68, 68,
-    2,  2, 92, 92, 92, 92, 92, 92, 92,  2,  2,  2,  2, 92, 87, 87,
-   87, 87, 87, 87, 87,  2, 19,  9, 19, 19, 19, 19,  0,  0, 87, 87,
-    2,  2,  2,  2,  2, 12,  2,  2,  2,  4, 14,  2, 14,  2, 14, 14,
-    2, 14, 14,  2, 14, 14,  2,  2,  2,  3,  3,  3,  0,  0,  2,  2,
-    3,  3,  1,  1,  6,  6,  3,  2,  3,  3,  3,  2,  2,  0,  2,  0,
-    0,  0,  0,  0, 17, 17, 17, 17,  0,  0,  2,  2, 12, 12, 49, 49,
-   49, 49,  2, 49, 49, 49, 49, 49, 49,  2, 49, 49,  2, 49, 49, 49,
-    2,  2,  9,  2,  2,  2,  0,  1,  2,  2, 71, 71, 71, 71, 71,  2,
-    2,  2, 67, 67, 67, 67, 67,  2,  2,  2, 42, 42, 42, 42,  2, 42,
-   42, 42, 41, 41, 41, 41, 41, 41, 41,  2,118,118,118,118,118,118,
-  118,  2, 53, 53, 53, 53, 53, 53,  2, 53, 59, 59, 59, 59, 59, 59,
-    2,  2, 40, 40, 40, 40, 51, 51, 51, 51, 50, 50, 50, 50, 50, 50,
-    2,  2,135,135,135,135,106,106,106,106,104,104,104,104,  2,  2,
-    2,104,161,161,161,161,161,161,161,  2,161,161,  2,161,161,  2,
-    2,  2,110,110,110,110,110,110,110,  2,110,110,  2,  2, 19,  2,
-   19, 19, 47, 47, 47, 47, 47, 47,  2,  2, 47,  2, 47, 47, 47, 47,
-    2, 47, 47,  2,  2,  2, 47,  2,  2, 47, 81, 81, 81, 81, 81, 81,
-    2, 81,120,120,120,120,116,116,116,116,116,116,116,  2,  2,  2,
-    2,116,128,128,128,128,128,128,128,  2,128,128,  2,  2,  2,  2,
-    2,128, 66, 66, 66, 66,  2,  2,  2, 66, 72, 72, 72, 72, 72, 72,
-    2,  2,  2,  2,  2, 72, 98, 98, 98, 98, 97, 97, 97, 97,  2,  2,
-   97, 97, 57, 57, 57, 57,  2, 57, 57,  2,  2, 57, 57, 57, 57, 57,
-    2,  2, 57, 57, 57,  2,  2,  2,  2, 57, 57,  2,  2,  2, 88, 88,
-   88, 88,117,117,117,117,112,112,112,112,112,112,112,  2,  2,  2,
-    2,112, 78, 78, 78, 78, 78, 78,  2,  2,  2, 78, 78, 78, 83, 83,
-   83, 83, 83, 83,  2,  2, 82, 82, 82, 82, 82, 82, 82,  2,122,122,
-  122,122,122,122,  2,  2,  2,122,122,122,122,  2,  2,  2, 89, 89,
-   89, 89, 89,  2,  2,  2,130,130,130,130,130,130,130,  2,  2,  2,
-  130,130,144,144,144,144,144,144,  2,  2,156,156,156,156,156,156,
-    2,156,156,156,  2,  2,  2,  3,  3,  3,147,147,147,147,148,148,
-  148,148,148,148,  2,  2,158,158,158,158,158,158,  2,  2,153,153,
-  153,153,149,149,149,149,149,149,149,  2, 94, 94, 94, 94, 94, 94,
-    2,  2,  2,  2, 94, 94,  2,  2,  2, 94, 85, 85, 85, 85, 85, 85,
-   85,  2,  2, 85,  2,  2,101,101,101,101,101,  2,  2,  2,101,101,
-    2,  2, 96, 96, 96, 96, 96,  2, 96, 96,111,111,111,111,111,111,
-  111,  2,100,100,100,100,108,108,108,108,108,108,  2,108,108,108,
-    2,  2,129,129,129,129,129,129,129,  2,129,  2,129,129,129,129,
-    2,129,129,129,  2,  2,109,109,109,109,109,109,109,  2,109,109,
-    2,  2,107,107,107,107,  2,107,107,107,107,  2,  2,107,107,  2,
-  107,107,107,107,  2,  1,107,107,  2,  2,107,  2,  2,  2,  2,  2,
-    2,107,  2,  2,107,107,137,137,137,137,  2,137,137,137,137,137,
-    2,  2,124,124,124,124,124,124,  2,  2,123,123,123,123,123,123,
-    2,  2,114,114,114,114,114,  2,  2,  2,114,114,  2,  2,102,102,
-  102,102,102,102,  2,  2,126,126,126,126,126,126,126,  2,  2,126,
-  126,126,142,142,142,142,125,125,125,125,125,125,125,  2,  2,  2,
-    2,125,154,154,154,154,154,154,154,  2,  2,154,  2,  2,  2,154,
-  154,  2,154,154,  2,154,154,  2,  2,154,154,154,  2,  2,150,150,
-  150,150,  2,  2,150,150,150,  2,  2,  2,141,141,141,141,140,140,
-  140,140,140,140,140,  2,121,121,121,121,121,  2,  2,  2,  7,  7,
-    2,  2,133,133,133,133,133,  2,133,133,133,133,133,  2,133,133,
-    2,  2,133,  2,  2,  2,134,134,134,134,  2,  2,134,134,  2,134,
-  134,134,134,134,134,  2,138,138,138,138,138,138,138,  2,138,138,
-    2,138,  2,  2,138,  2,138,138,  2,  2,143,143,143,143,143,143,
-    2,143,143,  2,143,143,143,143,143,  2,143,  2,  2,  2,143,143,
-    2,  2,145,145,145,145,145,  2,  2,  2,163,163,163,163,163,  2,
-  163,163,163,163,163,  2,  2,  2,163,163,163,163,  2,  2, 86,  2,
-    2,  2, 63, 63, 63, 63, 63, 63,  2,  2, 63, 63, 63,  2, 63,  2,
-    2,  2,157,157,157,157,157,157,157,  2, 80, 80, 80, 80, 80, 80,
-    2,  2,127,127,127,127,127,127,127,  2, 79,  2,  2,  2,115,115,
-  115,115,115,115,115,  2,115,115,  2,  2,  2,  2,115,115,159,159,
-  159,159,159,159,159,  2,159,159,  2,  2,103,103,103,103,103,103,
-    2,  2,119,119,119,119,119,119,  2,  2,119,119,  2,119,  2,119,
-  119,119,146,146,146,146,146,146,146,  2, 99, 99, 99, 99, 99, 99,
-   99,  2,  2,  2,  2, 99,136,139, 13, 13,155,  2,  2,  2,136,136,
-  136,136,155,155,155,155,155,155,  2,  2,136,  2,  2,  2,  2, 17,
-   17, 17,  2, 17, 17,  2, 17, 15, 15, 15, 17, 17, 17,  2,  2,  2,
-   15,  2,  2, 17,  2,  2,139,139,139,139,105,105,105,105,105,105,
-  105,  2,105,  2,  2,  2,105,105,  2,  2,  1,  1,  2,  2,  0,  0,
-    0,  1,  0,  1,  1,  1,  0,  0,  1,  1,  2,  2,  0,  2,  2,  0,
-    0,  2,  0,  2,  0,  2,131,131,131,131,  2,  2,  2,131,  2,131,
-  131,131, 56, 56, 56,  2, 56,  2,  2, 56, 56, 56,  2, 56, 56,  2,
-   56, 56,  6,  6,  2,  2,  2,  2,  2,  6,151,151,151,151,151,  2,
-    2,  2,151,151,  2,  2,  2,  2,151,151,160,160,160,160,160,160,
-  160,  2,152,152,152,152,152,152,  2,  2,  2,  2,  2,152,164,164,
-  164,164,164,164,  2,  2,  2, 30, 30,  2,113,113,113,113,113,  2,
-    2,113,113,113,113,  2,132,132,132,132,132,132,  2,  2,  2,  2,
-  132,132,  2,  3,  3,  2,  3,  2,  2,  3,  2,  3,  2,  3,  2,  2,
-    3,  2,  3,  2,  3,  2,  3,  3,  2,  3, 15,  0,  0,  2, 13,  2,
-    2,  2, 13, 13, 13,  2,  2,  0,  2,  2,  0,  1,  2,  3,  4,  5,
-    6,  7,  8,  9,  9,  9,  9, 10,  9, 11, 12, 13,  9,  9,  9, 14,
-    9,  9, 15,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
+   70, 70, 70,240, 70, 70, 70, 70, 70, 70, 70, 70, 70,241, 70, 70,
+   70, 70,242, 96, 96, 96, 70, 70, 70, 70,243, 96, 96, 96, 96, 96,
+   96, 96, 96, 96, 96, 96, 70, 70, 70, 70, 70, 70,244, 70, 70, 70,
+   70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,245, 96, 96,
+   96, 96, 96, 96, 96, 96,246, 96,247,248,  0,  1,  2,  2,  0,  1,
+    2,  2,  2,  3,  4,  5,  0,  0,  0,  0,  0, 19, 19, 19, 19, 19,
+   19, 19, 19, 19, 19,  0,  0,  0, 19,  0, 19,  0,  0,  0,  0,  0,
+   26, 26,  1,  1,  1,  1,  9,  9,  9,  9,  0,  9,  9,  9,  2,  2,
+    9,  9,  9,  9,  0,  9,  2,  2,  2,  2,  9,  0,  9,  0,  9,  9,
+    9,  2,  9,  2,  9,  9,  9,  9,  2,  9,  9,  9, 55, 55, 55, 55,
+   55, 55,  6,  6,  6,  6,  6,  1,  1,  6,  2,  4,  4,  4,  4,  4,
+    4,  4,  4,  4,  4,  2,  2, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+   14,  2,  2,  2,  2, 14, 14,  2,  2,  2,  3,  3,  3,  3,  3,  0,
+    3,  3,  0,  3,  3,  3,  3,  3,  3,  0,  3,  3,  3,  1,  1,  1,
+    3,  3,  1,  3,  3,  3, 37, 37, 37, 37, 37, 37,  2, 37, 37, 37,
+   37,  2,  2, 37, 37, 37, 38, 38, 38, 38, 38, 38,  2,  2, 64, 64,
+   64, 64, 64, 64, 64,  2,  2, 64, 64, 64, 90, 90, 90, 90, 90, 90,
+    2,  2, 90, 90, 90,  2, 95, 95, 95, 95,  2,  2, 95,  2,  3,  3,
+    3,  2,  3,  3,  2,  2,  3,  3,  0,  3,  7,  7,  7,  7,  7,  1,
+    1,  1,  1,  7,  7,  7,  0,  0,  7,  7,  5,  5,  5,  5,  2,  5,
+    5,  5,  5,  2,  2,  5,  5,  2,  5,  5,  5,  2,  5,  2,  2,  2,
+    5,  5,  5,  5,  2,  2,  5,  5,  5,  2,  2,  2,  2,  5,  5,  5,
+    2,  5,  2, 11, 11, 11, 11, 11, 11,  2,  2,  2,  2, 11, 11,  2,
+    2, 11, 11, 11, 11, 11, 11,  2, 11, 11,  2, 11, 11,  2, 11, 11,
+    2,  2,  2, 11,  2,  2, 11,  2, 11,  2,  2,  2, 11, 11,  2, 10,
+   10, 10, 10, 10, 10, 10, 10, 10,  2, 10, 10,  2, 10, 10, 10, 10,
+    2,  2, 10,  2,  2,  2,  2,  2, 10, 10,  2, 21, 21, 21, 21, 21,
+   21, 21, 21,  2,  2, 21, 21,  2, 21, 21, 21, 21,  2,  2, 21, 21,
+    2, 21,  2,  2, 21, 21,  2,  2, 22, 22,  2, 22, 22, 22, 22, 22,
+   22,  2, 22,  2, 22, 22, 22, 22,  2,  2,  2, 22, 22,  2,  2,  2,
+    2, 22, 22,  2,  2,  2, 22, 22, 22, 22, 23, 23, 23, 23, 23,  2,
+   23, 23, 23, 23,  2,  2,  2, 23, 23,  2, 23, 23, 23,  2,  2, 23,
+    2,  2,  2,  2, 23, 23,  2,  2,  2, 23, 16, 16, 16, 16, 16,  2,
+   16, 16,  2, 16, 16, 16, 16, 16,  2,  2,  2, 16, 16,  2,  2,  2,
+   16, 16, 20, 20, 20, 20, 20,  2, 20, 20,  2,  2, 20, 20,  2, 36,
+   36, 36, 36, 36, 36, 36, 36, 36, 36,  2,  2,  2, 36, 36, 36, 36,
+    2, 36,  2, 36,  2,  2,  2,  2, 36,  2,  2,  2,  2, 36, 36,  2,
+   36,  2, 36,  2,  2,  2,  2, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+   24,  2,  2,  2,  2,  0,  2, 18, 18,  2, 18,  2, 18, 18, 18, 18,
+   18,  2, 18, 18, 18, 18,  2, 18,  2, 18, 18, 18,  2,  2, 18,  2,
+   18,  2, 25, 25, 25, 25,  2, 25, 25, 25, 25,  2,  2,  2, 25,  2,
+   25, 25, 25,  0,  0,  0,  0, 25, 25,  2, 33, 33, 33, 33,  8,  8,
+    8,  8,  8,  8,  2,  8,  2,  8,  2,  2,  8,  8,  8,  0, 12, 12,
+   12, 12, 30, 30, 30, 30, 30,  2, 30, 30, 30, 30,  2,  2, 30, 30,
+   30,  2,  2, 30, 30, 30, 30,  2,  2,  2, 29, 29, 29, 29, 29, 29,
+    2,  2, 28, 28, 28, 28, 34, 34, 34, 34, 34,  2,  2,  2, 35, 35,
+   35, 35, 35, 35, 35,  0,  0,  0, 35, 35, 35,  2,  2,  2, 45, 45,
+   45, 45, 45, 45,  2,  2,  2,  2,  2, 45, 44, 44, 44, 44, 44,  0,
+    0,  2, 43, 43, 43, 43, 46, 46, 46, 46, 46,  2, 46, 46, 31, 31,
+   31, 31, 31, 31,  2,  2, 32, 32,  0,  0, 32,  0, 32, 32, 32, 32,
+   32, 32, 32, 32,  2,  2, 32,  2,  2,  2, 32, 32, 32,  2, 28, 28,
+    2,  2, 48, 48, 48, 48, 48, 48, 48,  2, 48,  2,  2,  2, 52, 52,
+   52, 52, 52, 52,  2,  2, 52,  2,  2,  2, 58, 58, 58, 58, 58, 58,
+    2,  2, 58, 58, 58,  2,  2,  2, 58, 58, 54, 54, 54, 54,  2,  2,
+   54, 54, 91, 91, 91, 91, 91, 91, 91,  2, 91,  2,  2, 91, 91, 91,
+    2,  2,  1,  1,  1,  2, 62, 62, 62, 62, 62,  2,  2,  2, 62, 62,
+   62,  2, 76, 76, 76, 76, 93, 93, 93, 93, 70, 70, 70, 70,  2,  2,
+    2, 70, 70, 70,  2,  2,  2, 70, 70, 70, 73, 73, 73, 73,  6,  2,
+    2,  2,  8,  8,  8,  2,  2,  8,  8,  8,  1,  1,  1,  0,  1,  0,
+    1,  1,  1,  0,  0,  0,  0,  1,  0,  0,  1,  1,  0,  2, 19, 19,
+    9,  9,  9,  9,  9,  6, 19,  9,  9,  9,  9,  9, 19, 19,  9,  9,
+    9, 19,  6, 19, 19, 19, 19, 19, 19,  9,  9,  9,  2,  2,  2,  9,
+    2,  9,  2,  9,  9,  9,  1,  1,  0,  0,  0,  2,  0,  0,  0, 19,
+    2,  2,  0,  0,  0, 19,  0,  0,  0,  2, 19,  2,  2,  2,  0,  2,
+    2,  2,  1,  2,  2,  2,  0,  0,  9,  0,  0,  0, 19, 19, 27, 27,
+   27, 27,  2,  2,  0,  0,  0,  0,  2,  0, 56, 56, 56, 56,  2, 55,
+   55, 55, 61, 61, 61, 61,  2,  2,  2, 61, 61,  2,  2,  2,  0,  0,
+    2,  2, 13, 13, 13, 13, 13, 13,  2, 13, 13, 13,  2,  2,  0, 13,
+    0, 13,  0, 13, 13, 13, 13, 13,  1,  1,  1,  1, 12, 12,  2, 15,
+   15, 15, 15, 15, 15, 15, 15, 15, 15,  2,  2,  1,  1,  0,  0, 15,
+   15, 15,  0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,  0,  2, 26,
+   26, 26, 26, 26, 26, 26,  2, 12, 12, 12, 12, 12, 12,  2, 12, 12,
+   12,  0, 39, 39, 39, 39, 39,  2,  2,  2, 39, 39, 39,  2, 86, 86,
+   86, 86, 77, 77, 77, 77, 79, 79, 79, 79, 19, 19, 19,  2, 19, 19,
+    2, 19,  2, 19, 19, 19, 19, 19,  2,  2,  2,  2, 19, 19, 60, 60,
+   60, 60, 60,  2,  2,  2, 65, 65, 65, 65, 75, 75, 75, 75, 75, 75,
+    2,  2,  2,  2, 75, 75, 69, 69, 69, 69, 69, 69,  0, 69, 74, 74,
+   74, 74,  2,  2,  2, 74, 12,  2,  2,  2, 84, 84, 84, 84, 84, 84,
+    2,  0, 84, 84,  2,  2,  2,  2, 84, 84, 33, 33, 33,  2, 68, 68,
+   68, 68, 68, 68, 68,  2, 68, 68,  2,  2, 92, 92, 92, 92, 92, 92,
+   92,  2,  2,  2,  2, 92, 87, 87, 87, 87, 87, 87, 87,  2, 19,  9,
+   19, 19, 19, 19,  0,  0, 87, 87,  2,  2,  2,  2,  2, 12,  2,  2,
+    2,  4, 14,  2, 14,  2, 14, 14,  2, 14, 14,  2, 14, 14,  2,  2,
+    2,  3,  3,  3,  0,  0,  2,  2,  3,  3,  1,  1,  6,  6,  3,  2,
+    3,  3,  3,  2,  2,  0,  2,  0,  0,  0,  0,  0, 17, 17, 17, 17,
+    0,  0,  2,  2, 12, 12, 49, 49, 49, 49,  2, 49, 49, 49, 49, 49,
+   49,  2, 49, 49,  2, 49, 49, 49,  2,  2,  9,  2,  2,  2,  0,  1,
+    2,  2, 71, 71, 71, 71, 71,  2,  2,  2, 67, 67, 67, 67, 67,  2,
+    2,  2, 42, 42, 42, 42,  2, 42, 42, 42, 41, 41, 41, 41, 41, 41,
+   41,  2,118,118,118,118,118,118,118,  2, 53, 53, 53, 53, 53, 53,
+    2, 53, 59, 59, 59, 59, 59, 59,  2,  2, 40, 40, 40, 40, 51, 51,
+   51, 51, 50, 50, 50, 50, 50, 50,  2,  2,135,135,135,135,106,106,
+  106,106,104,104,104,104,  2,  2,  2,104,161,161,161,161,161,161,
+  161,  2,161,161,  2,161,161,  2,  2,  2,110,110,110,110,110,110,
+  110,  2,110,110,  2,  2, 19,  2, 19, 19, 47, 47, 47, 47, 47, 47,
+    2,  2, 47,  2, 47, 47, 47, 47,  2, 47, 47,  2,  2,  2, 47,  2,
+    2, 47, 81, 81, 81, 81, 81, 81,  2, 81,120,120,120,120,116,116,
+  116,116,116,116,116,  2,  2,  2,  2,116,128,128,128,128,128,128,
+  128,  2,128,128,  2,  2,  2,  2,  2,128, 66, 66, 66, 66,  2,  2,
+    2, 66, 72, 72, 72, 72, 72, 72,  2,  2,  2,  2,  2, 72, 98, 98,
+   98, 98, 97, 97, 97, 97,  2,  2, 97, 97, 57, 57, 57, 57,  2, 57,
+   57,  2,  2, 57, 57, 57, 57, 57,  2,  2, 57, 57, 57,  2,  2,  2,
+    2, 57, 57,  2,  2,  2, 88, 88, 88, 88,117,117,117,117,112,112,
+  112,112,112,112,112,  2,  2,  2,  2,112, 78, 78, 78, 78, 78, 78,
+    2,  2,  2, 78, 78, 78, 83, 83, 83, 83, 83, 83,  2,  2, 82, 82,
+   82, 82, 82, 82, 82,  2,122,122,122,122,122,122,  2,  2,  2,122,
+  122,122,122,  2,  2,  2, 89, 89, 89, 89, 89,  2,  2,  2,130,130,
+  130,130,130,130,130,  2,  2,  2,130,130,144,144,144,144,144,144,
+    2,  2,156,156,156,156,156,156,  2,156,156,156,  2,  2,  2,  3,
+    3,  3,147,147,147,147,148,148,148,148,148,148,  2,  2,158,158,
+  158,158,158,158,  2,  2,153,153,153,153,149,149,149,149,149,149,
+  149,  2, 94, 94, 94, 94, 94, 94,  2,  2,  2,  2, 94, 94,  2,  2,
+    2, 94, 85, 85, 85, 85, 85, 85, 85,  2,  2, 85,  2,  2,101,101,
+  101,101,101,  2,  2,  2,101,101,  2,  2, 96, 96, 96, 96, 96,  2,
+   96, 96,111,111,111,111,111,111,111,  2,100,100,100,100,108,108,
+  108,108,108,108,  2,108,108,108,  2,  2,129,129,129,129,129,129,
+  129,  2,129,  2,129,129,129,129,  2,129,129,129,  2,  2,109,109,
+  109,109,109,109,109,  2,109,109,  2,  2,107,107,107,107,  2,107,
+  107,107,107,  2,  2,107,107,  2,107,107,107,107,  2,  1,107,107,
+    2,  2,107,  2,  2,  2,  2,  2,  2,107,  2,  2,107,107,137,137,
+  137,137,  2,137,137,137,137,137,  2,  2,124,124,124,124,124,124,
+    2,  2,123,123,123,123,123,123,  2,  2,114,114,114,114,114,  2,
+    2,  2,114,114,  2,  2,102,102,102,102,102,102,  2,  2,126,126,
+  126,126,126,126,126,  2,  2,126,126,126,142,142,142,142,125,125,
+  125,125,125,125,125,  2,  2,  2,  2,125,154,154,154,154,154,154,
+  154,  2,  2,154,  2,  2,  2,154,154,  2,154,154,  2,154,154,  2,
+    2,154,154,154,  2,  2,150,150,150,150,  2,  2,150,150,150,  2,
+    2,  2,141,141,141,141,140,140,140,140,140,140,140,  2,121,121,
+  121,121,121,  2,  2,  2,  7,  7,  2,  2,133,133,133,133,133,  2,
+  133,133,133,133,133,  2,133,133,  2,  2,133,  2,  2,  2,134,134,
+  134,134,  2,  2,134,134,  2,134,134,134,134,134,134,  2,138,138,
+  138,138,138,138,138,  2,138,138,  2,138,  2,  2,138,  2,138,138,
+    2,  2,143,143,143,143,143,143,  2,143,143,  2,143,143,143,143,
+  143,  2,143,  2,  2,  2,143,143,  2,  2,145,145,145,145,145,  2,
+    2,  2,163,163,163,163,163,  2,163,163,163,163,163,  2,  2,  2,
+  163,163,163,163,  2,  2, 86,  2,  2,  2, 63, 63, 63, 63, 63, 63,
+    2,  2, 63, 63, 63,  2, 63,  2,  2,  2,157,157,157,157,157,157,
+  157,  2, 80, 80, 80, 80, 80, 80,  2,  2,127,127,127,127,127,127,
+  127,  2, 79,  2,  2,  2,115,115,115,115,115,115,115,  2,115,115,
+    2,  2,  2,  2,115,115,159,159,159,159,159,159,159,  2,159,159,
+    2,  2,103,103,103,103,103,103,  2,  2,119,119,119,119,119,119,
+    2,  2,119,119,  2,119,  2,119,119,119,146,146,146,146,146,146,
+  146,  2, 99, 99, 99, 99, 99, 99, 99,  2,  2,  2,  2, 99,136,139,
+   13, 13,155,  2,  2,  2,136,136,136,136,155,155,155,155,155,155,
+    2,  2,136,  2,  2,  2,  2, 17, 17, 17,  2, 17, 17,  2, 17, 15,
+   15, 15, 17, 17, 17,  2,  2,  2, 15,  2,  2, 17,  2,  2,139,139,
+  139,139,105,105,105,105,105,105,105,  2,105,  2,  2,  2,105,105,
+    2,  2,  1,  1,  2,  2,  0,  0,  0,  1,  0,  1,  1,  1,  0,  0,
+    1,  1,  2,  2,  0,  2,  2,  0,  0,  2,  0,  2,  0,  2,131,131,
+  131,131,  2,  2,  2,131,  2,131,131,131, 56, 56, 56,  2, 56,  2,
+    2, 56, 56, 56,  2, 56, 56,  2, 56, 56,  6,  6,  2,  2,  2,  2,
+    2,  6,151,151,151,151,151,  2,  2,  2,151,151,  2,  2,  2,  2,
+  151,151,160,160,160,160,160,160,160,  2,152,152,152,152,152,152,
+    2,  2,  2,  2,  2,152,164,164,164,164,164,164,  2,  2,  2, 30,
+   30,  2,113,113,113,113,113,  2,  2,113,113,113,113,  2,132,132,
+  132,132,132,132,  2,  2,  2,  2,132,132,  2,  3,  3,  2,  3,  2,
+    2,  3,  2,  3,  2,  3,  2,  2,  3,  2,  3,  2,  3,  2,  3,  3,
+    2,  3, 15,  0,  0,  2, 13,  2,  2,  2, 13, 13, 13,  2,  2,  0,
+    2,  2,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  9,  9,  9, 10,
+    9, 11, 12, 13,  9,  9,  9, 14,  9,  9, 15,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
-    9,  9,  9,  9,  9,  9, 16, 17,  9,  9,  9,  9,  9,  9,  9,  9,
-    9,  9, 18, 19, 20,  9, 21,  9,  9,  9,  9,  9,  9,  9,  9,  9,
+    9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9, 16, 17,
+    9,  9,  9,  9,  9,  9,  9,  9,  9,  9, 18, 19, 20,  9, 21,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
-    9,  9, 22,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
+    9,  9,  9,  9,  9,  9,  9,  9,  9,  9, 22,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
@@ -3702,60 +3704,60 @@
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
     9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,
-    9,  9,  9,  9,  9,  9, 23, 24,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12,
-    0,  0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 23,  0,  0, 24,
-   25, 26, 27, 28, 29, 30,  0,  0, 31, 32,  0, 33,  0, 34,  0, 35,
-    0,  0,  0,  0, 36, 37, 38, 39,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 40,  0,  0,  0,  0,  0,
-    0,  0,  0,  0, 41, 42,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9, 23, 24,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  3,  4,
+    5,  6,  7,  8,  9, 10, 11, 12,  0,  0, 13, 14, 15, 16, 17, 18,
+   19, 20, 21, 22,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0, 23,  0,  0, 24, 25, 26, 27, 28, 29, 30,  0,  0,
+   31, 32,  0, 33,  0, 34,  0, 35,  0,  0,  0,  0, 36, 37, 38, 39,
     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, 43, 44,  0, 45,  0,  0,
-    0,  0,  0,  0, 46, 47,  0,  0,  0,  0,  0, 48,  0, 49,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 50, 51,  0,  0,
-    0, 52,  0,  0, 53,  0,  0,  0,  0,  0,  0,  0, 54,  0,  0,  0,
-    0,  0,  0,  0, 55,  0,  0,  0,  0,  0,  0,  0, 56,  0,  0,  0,
-    0,  0,  0,  0,  0, 57,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 58, 59, 60, 61,
-   62, 63, 64, 65,  0,  0,  0,  0,  0,  0, 66,  0,  0,  0,  0,  0,
+    0,  0, 40,  0,  0,  0,  0,  0,  0,  0,  0,  0, 41, 42,  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, 43, 44,  0, 45,  0,  0,  0,  0,  0,  0, 46, 47,  0,  0,
+    0,  0,  0, 48,  0, 49,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0, 50, 51,  0,  0,  0, 52,  0,  0, 53,  0,  0,  0,
+    0,  0,  0,  0, 54,  0,  0,  0,  0,  0,  0,  0, 55,  0,  0,  0,
+    0,  0,  0,  0, 56,  0,  0,  0,  0,  0,  0,  0,  0, 57,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0, 58, 59, 60, 61, 62, 63, 64, 65,  0,  0,  0,  0,
+    0,  0, 66,  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, 67, 68,  0, 69, 70,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0, 71, 72, 73, 74, 75, 76, 77, 78,
-   79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
-   95, 96, 97, 98, 99,100,101,102,103,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,104,  0,  0,  0,  0,  0,
-    0,105,106,  0,107,  0,  0,  0,108,  0,109,  0,110,  0,111,112,
-  113,  0,114,  0,  0,  0,115,  0,  0,  0,116,  0,  0,  0,  0,  0,
+   67, 68,  0, 69, 70,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+   71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
+   87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,
+  103,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,104,  0,  0,  0,  0,  0,  0,105,106,  0,107,  0,  0,  0,
+  108,  0,109,  0,110,  0,111,112,113,  0,114,  0,  0,  0,115,  0,
+    0,  0,116,  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,117,  0,  0,
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,117,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,118,119,120,121,
-    0,122,123,124,125,126,  0,127,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,118,119,120,121,  0,122,123,124,125,126,  0,127,
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,128,129,130,131,132,133,134,135,
-  136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,
-  152,153,154,155,156,157,  0,  0,  0,158,159,160,161,  0,  0,  0,
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,162,163,  0,  0,  0,  0,  0,  0,  0,164,  0,  0,  0,  0,  0,
+  128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
+  144,145,146,147,148,149,150,151,152,153,154,155,156,157,  0,  0,
+    0,158,159,160,161,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,162,163,  0,  0,  0,  0,  0,
+    0,  0,164,  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,165,  0,  0,  0,
+    0,  0,  0,  0,165,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,166,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,167,  0,  0,  0,  0,
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,166,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,167,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
-    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,168,  0,  0,  0,  0,
+    0,  0,  0,168,  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,169,170,  0,
-    0,  0,  0,171,172,  0,  0,  0,173,174,175,176,177,178,179,180,
-  181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,
-  197,198,199,200,201,202,203,204,205,206,  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,  2,  3,  4,
+    0,  0,  0,  0,  0,169,170,  0,  0,  0,  0,171,172,  0,  0,  0,
+  173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,
+  189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,
+  205,206,  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,  2,  3,  4,
 };
 static const uint16_t
-_hb_ucd_u16[10040] =
+_hb_ucd_u16[10060] =
 {
      0,   0,   1,   2,   3,   4,   5,   6,   0,   0,   7,   8,   9,  10,  11,  12,
     13,  13,  13,  14,  15,  13,  13,  16,  17,  18,  19,  20,  21,  22,  13,  23,
@@ -3798,9 +3800,9 @@
    209, 306, 209, 209, 209, 209, 209, 209,   9,   9,   9,  11,  11,  11, 307, 308,
     13,  13,  13,  13,  13,  13, 309, 310,  11,  11, 311,  48,  48,  48, 312, 313,
     48, 314, 315, 315, 315, 315,  32,  32, 316, 317, 318, 319, 320, 321, 140, 140,
-   209, 322, 209, 209, 209, 209, 209, 323, 209, 209, 209, 209, 209, 324, 140, 325,
-   326, 327, 328, 329, 136,  48,  48,  48,  48, 330, 178,  48,  48,  48,  48, 331,
-   332,  48,  48, 136,  48,  48,  48,  48, 200, 333,  48,  48, 209, 209, 323,  48,
+   209, 322, 209, 209, 209, 209, 209, 323, 209, 209, 209, 209, 209, 324, 140, 209,
+   325, 326, 327, 328, 136,  48,  48,  48,  48, 329, 178,  48,  48,  48,  48, 330,
+   331,  48,  48, 136,  48,  48,  48,  48, 200, 332,  48,  48, 209, 209, 333,  48,
    209, 334, 335, 209, 336, 337, 209, 209, 335, 209, 209, 337, 209, 209, 209, 209,
     48,  48,  48,  48, 209, 209, 209, 209,  48, 338,  48,  48,  48,  48,  48,  48,
    151, 209, 209, 209, 287,  48,  48, 229, 339,  48, 340, 140,  13,  13, 341, 342,
@@ -3871,143 +3873,144 @@
      9,   9, 607,  11, 654, 370, 140, 140, 140, 140, 140, 140, 140, 140, 140, 499,
    271, 271, 655, 656, 140, 140, 140, 140, 499, 271, 657, 658, 140, 140, 140, 140,
    659,  48, 660, 661, 662, 663, 664, 665, 666, 206, 667, 206, 140, 140, 140, 668,
-   209, 209, 325, 209, 209, 209, 209, 209, 209, 323, 334, 669, 669, 669, 209, 324,
-   670, 209, 209, 209, 209, 209, 209, 209, 209, 209, 671, 140, 140, 140, 672, 209,
-   673, 209, 209, 325, 674, 675, 324, 140, 209, 209, 209, 209, 209, 209, 209, 676,
-   209, 209, 209, 209, 209, 677, 426, 426, 209, 209, 209, 209, 209, 209, 209, 678,
-   209, 209, 209, 209, 209, 176, 325, 427, 325, 209, 209, 209, 679, 176, 209, 209,
-   679, 209, 671, 675, 140, 140, 140, 140, 209, 209, 209, 209, 209, 323, 671, 426,
-   674, 209, 209, 680, 681, 325, 674, 674, 209, 682, 209, 209, 288, 140, 140, 192,
+   209, 209, 669, 209, 209, 209, 209, 209, 209, 323, 334, 670, 670, 670, 209, 324,
+   671, 209, 209, 209, 209, 209, 209, 209, 209, 209, 672, 140, 140, 140, 673, 209,
+   674, 209, 209, 669, 675, 676, 324, 140, 209, 209, 209, 209, 209, 209, 209, 677,
+   209, 209, 209, 209, 209, 678, 426, 426, 209, 209, 209, 209, 209, 209, 209, 679,
+   209, 209, 209, 209, 209, 176, 669, 427, 669, 209, 209, 209, 680, 176, 209, 209,
+   680, 209, 672, 676, 140, 140, 140, 140, 209, 209, 209, 209, 209, 323, 672, 426,
+   675, 209, 209, 681, 682, 669, 675, 675, 209, 683, 209, 209, 288, 140, 140, 192,
     48,  48,  48,  48,  48,  48, 140, 140,  48,  48,  48, 207,  48,  48,  48,  48,
     48, 204,  48,  48,  48,  48,  48,  48,  48,  48, 478,  48,  48,  48,  48,  48,
-    48,  48,  48,  48,  48,  48, 100, 140,  48, 204, 140, 140, 140, 140, 140, 140,
-    48,  48,  48,  48,  71,  48,  48,  48,  48,  48,  48, 140, 140, 140, 140, 140,
-   683, 140, 570, 570, 570, 570, 570, 570,  32,  32,  32,  32,  32,  32,  32,  32,
-    32,  32,  32,  32,  32,  32,  32, 140, 391, 391, 391, 391, 391, 391, 391, 684,
-   391, 391, 391, 391, 391, 391, 391, 685,   0,   0,   0,   0,   1,   2,   1,   2,
-     0,   0,   3,   3,   4,   5,   4,   5,   4,   4,   4,   4,   4,   4,   4,   4,
-     4,   4,   4,   6,   0,   0,   7,   0,   8,   8,   8,   8,   8,   8,   8,   9,
-    10,  11,  12,  11,  11,  11,  13,  11,  14,  14,  14,  14,  14,  14,  14,  14,
-    15,  14,  14,  14,  14,  14,  14,  14,  14,  14,  14,  16,  17,  18,  17,  17,
-    19,  20,  21,  21,  22,  21,  23,  24,  25,  26,  27,  27,  28,  29,  27,  30,
-    27,  27,  27,  27,  27,  31,  27,  27,  32,  33,  33,  33,  34,  27,  27,  27,
-    35,  35,  35,  36,  37,  37,  37,  38,  39,  39,  40,  41,  42,  43,  44,  27,
-    45,  46,  27,  27,  27,  27,  47,  27,  48,  48,  48,  48,  48,  49,  50,  48,
-    51,  52,  53,  54,  55,  56,  57,  58,  59,  60,  61,  62,  63,  64,  65,  66,
-    67,  68,  69,  70,  71,  72,  73,  74,  75,  76,  77,  78,  79,  80,  81,  82,
-    83,  84,  85,  86,  87,  88,  89,  90,  91,  92,  93,  94,  95,  96,  97,  98,
-    99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 109, 110, 111, 112, 109,
-   113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 122, 123, 122, 124, 125, 125,
-   126, 127, 128, 129, 130, 131, 125, 125, 132, 132, 132, 132, 133, 132, 134, 135,
-   132, 133, 132, 136, 136, 137, 125, 125, 138, 138, 138, 138, 138, 138, 138, 138,
-   138, 138, 139, 139, 140, 139, 139, 141, 142, 142, 142, 142, 142, 142, 142, 142,
-   143, 143, 143, 143, 144, 145, 143, 143, 144, 143, 143, 146, 147, 148, 143, 143,
-   143, 147, 143, 143, 143, 149, 143, 150, 143, 151, 152, 152, 152, 152, 152, 153,
-   154, 154, 154, 154, 154, 154, 154, 154, 155, 156, 157, 157, 157, 157, 158, 159,
-   160, 161, 162, 163, 164, 165, 166, 167, 168, 168, 168, 168, 168, 169, 170, 170,
-   171, 172, 173, 173, 173, 173, 173, 174, 173, 173, 175, 154, 154, 154, 154, 176,
-   177, 178, 179, 179, 180, 181, 182, 183, 184, 184, 185, 184, 186, 187, 168, 168,
-   188, 189, 190, 190, 190, 191, 190, 192, 193, 193, 194,   8, 195, 125, 125, 125,
-   196, 196, 196, 196, 197, 196, 196, 198, 199, 199, 199, 199, 200, 200, 200, 201,
-   202, 202, 202, 203, 204, 205, 205, 205, 206, 139, 139, 207, 208, 209, 210, 211,
-     4,   4, 212,   4,   4, 213, 214, 215,   4,   4,   4, 216,   8,   8,   8,   8,
-    11, 217,  11,  11, 217, 218,  11, 219,  11,  11,  11, 220, 220, 221,  11, 222,
-   223,   0,   0,   0,   0,   0, 224, 225, 226, 227,   0,   0, 228,   8,   8, 229,
-     0,   0, 230, 231, 232,   0,   4,   4, 233,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 234, 125, 235, 125,   0,   0,
-   236, 236, 236, 236, 236, 236, 236, 236,   0,   0,   0,   0,   0,   0,   0, 237,
-     0, 238,   0,   0,   0,   0,   0,   0, 239, 239, 239, 239, 239, 239,   4,   4,
-   240, 240, 240, 240, 240, 240, 240, 241, 139, 139, 140, 242, 242, 242, 243, 244,
-   143, 245, 246, 246, 246, 246,  14,  14,   0,   0,   0,   0,   0, 247, 125, 125,
-   248, 249, 248, 248, 248, 248, 248, 250, 248, 248, 248, 248, 248, 248, 248, 248,
-   248, 248, 248, 248, 248, 251, 125, 252, 253,   0, 254, 255, 256, 257, 257, 257,
-   257, 258, 259, 260, 260, 260, 260, 261, 262, 263, 263, 264, 142, 142, 142, 142,
-   265,   0, 263, 263,   0,   0, 266, 260, 142, 265,   0,   0,   0,   0, 142, 267,
-     0,   0,   0,   0,   0, 260, 260, 268, 260, 260, 260, 260, 260, 269,   0,   0,
-   248, 248, 248, 248,   0,   0,   0,   0, 270, 270, 270, 270, 270, 270, 270, 270,
-   271, 270, 270, 270, 272, 273, 273, 273, 274, 274, 274, 274, 274, 274, 274, 274,
-   274, 274, 275, 125,  14,  14,  14,  14,  14,  14, 276, 276, 276, 276, 276, 277,
-     0,   0, 278,   4,   4,   4,   4,   4, 279,   4,   4,   4, 280, 281, 125, 282,
-   283, 283, 284, 285, 286, 286, 286, 287, 288, 288, 288, 288, 289, 290,  48,  48,
-   291, 291, 292, 293, 293, 294, 142, 295, 296, 296, 296, 296, 297, 298, 138, 299,
-   300, 300, 300, 301, 302, 303, 138, 138, 304, 304, 304, 304, 305, 306, 307, 308,
-   309, 310, 246,   4,   4, 311, 312, 152, 152, 152, 152, 152, 307, 307, 313, 314,
-   142, 142, 315, 142, 316, 142, 142, 317, 125, 125, 125, 125, 125, 125, 125, 125,
-   248, 248, 248, 248, 248, 248, 318, 248, 248, 248, 248, 248, 248, 319, 125, 125,
-   320, 321,  21, 322, 323,  27,  27,  27,  27,  27,  27,  27, 324, 325,  27,  27,
-    27,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27, 326,  27,  27,  27,  27,
-    27, 327,  27,  27, 328, 125, 125,  27,   8, 285, 329,   0,   0, 330, 331, 332,
-    27,  27,  27,  27,  27,  27,  27, 333, 334,   0,   1,   2,   1,   2, 335, 259,
-   260, 336, 142, 265, 337, 338, 339, 340, 341, 342, 343, 344, 345, 345, 125, 125,
-   342, 342, 342, 342, 342, 342, 342, 346, 347,   0,   0, 348,  11,  11,  11,  11,
-   349, 350, 351, 125, 125,   0,   0, 352, 353, 354, 355, 355, 355, 356, 357, 252,
-   358, 358, 359, 360, 361, 362, 362, 363, 364, 365, 366, 366, 367, 368, 125, 125,
-   369, 369, 369, 369, 369, 370, 370, 370, 371, 372, 373, 374, 374, 375, 374, 376,
-   377, 377, 378, 379, 379, 379, 380, 381, 381, 382, 383, 384, 125, 125, 125, 125,
-   385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 386, 385, 387, 388, 125,
-   389,   4,   4, 390, 125, 125, 125, 125, 391, 392, 392, 393, 394, 395, 396, 396,
-   397, 398, 399, 125, 125, 125, 400, 401, 402, 403, 404, 405, 125, 125, 125, 125,
-   406, 406, 407, 408, 407, 409, 407, 407, 410, 411, 412, 413, 414, 414, 415, 415,
-   416, 416, 125, 125, 417, 417, 418, 419, 420, 420, 420, 421, 422, 423, 424, 425,
-   426, 427, 428, 125, 125, 125, 125, 125, 429, 429, 429, 429, 430, 125, 125, 125,
-   431, 431, 431, 432, 431, 431, 431, 433, 434, 434, 435, 436, 125, 125, 125, 125,
-   125, 125, 125, 125, 125, 125,  27,  45, 437, 437, 438, 439, 125, 125, 125, 440,
-   441, 441, 442, 443, 443, 444, 125, 445, 446, 125, 125, 447, 448, 125, 449, 450,
-   451, 451, 451, 451, 452, 453, 451, 454, 455, 455, 455, 455, 456, 457, 458, 459,
-   460, 460, 460, 461, 462, 463, 463, 464, 465, 465, 465, 465, 465, 465, 466, 467,
-   468, 469, 468, 468, 470, 125, 125, 125, 471, 472, 473, 474, 474, 474, 475, 476,
-   477, 478, 479, 480, 481, 482, 483, 484, 485, 485, 485, 485, 485, 486, 487, 125,
-   488, 488, 488, 488, 489, 490, 125, 125, 491, 491, 491, 492, 491, 493, 125, 125,
-   494, 494, 494, 494, 495, 496, 497, 125, 498, 498, 498, 499, 499, 125, 125, 125,
-   500, 501, 502, 500, 503, 125, 125, 125, 504, 504, 504, 505, 125, 125, 125, 125,
-   125, 125, 506, 506, 506, 506, 506, 507, 508, 509, 510, 511, 512, 513, 125, 125,
-   125, 125, 514, 515, 515, 514, 516, 125, 517, 517, 517, 517, 518, 519, 519, 519,
-   519, 519, 520, 154, 521, 521, 521, 522, 523, 125, 125, 125, 125, 125, 125, 125,
-   524, 525, 525, 526, 527, 525, 528, 529, 529, 530, 531, 532, 125, 125, 125, 125,
-   533, 534, 534, 535, 536, 537, 538, 539, 540, 541, 542, 125, 125, 125, 125, 125,
-   125, 125, 125, 125, 125, 125, 543, 544, 545, 546, 545, 547, 545, 548, 125, 125,
-   125, 125, 125, 549, 550, 550, 550, 551, 552, 552, 552, 552, 552, 552, 552, 552,
-   552, 553, 125, 125, 125, 125, 125, 125, 552, 552, 552, 552, 552, 552, 554, 555,
-   552, 552, 552, 552, 556, 125, 125, 125, 125, 557, 557, 557, 557, 557, 557, 558,
-   559, 559, 559, 559, 559, 559, 559, 559, 559, 559, 559, 559, 559, 560, 125, 125,
-   561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 562, 125, 125, 125,
-   276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 563, 564, 565, 566, 567,
-   567, 567, 567, 568, 569, 570, 571, 572, 573, 573, 573, 573, 574, 575, 576, 577,
-   573, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 578, 578, 578, 578,
-   578, 579, 125, 125, 125, 125, 125, 125, 580, 580, 580, 580, 581, 580, 580, 580,
-   582, 580, 125, 125, 125, 125, 583, 584, 585, 585, 585, 585, 585, 585, 585, 585,
-   585, 585, 585, 585, 585, 585, 585, 586, 587, 587, 587, 587, 587, 587, 587, 587,
-   587, 587, 587, 587, 587, 588, 125, 125, 589, 125, 125, 125, 125, 125, 125, 125,
-   125, 125, 125, 125, 125, 125, 125, 590, 591, 257, 257, 257, 257, 257, 257, 257,
-   257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 592, 593, 125, 594, 595, 596,
-   596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 597,
-   598, 598, 598, 598, 598, 598, 599, 600, 601, 602, 266, 125, 125, 125, 125, 125,
-     8,   8, 603,   8, 604,   0,   0,   0,   0,   0,   0,   0, 266, 125, 125, 125,
-     0,   0,   0,   0,   0,   0,   0, 605,   0,   0, 606,   0,   0,   0, 607, 608,
-   609,   0, 610,   0,   0,   0, 235, 125,  11,  11,  11,  11, 611, 125, 125, 125,
-   125, 125, 125, 125,   0, 266,   0, 266,   0,   0,   0,   0,   0, 234,   0, 612,
-     0,   0,   0,   0,   0, 224,   0,   0,   0, 613, 614, 615, 616,   0,   0,   0,
-   617, 618,   0, 619, 620, 621,   0,   0,   0,   0, 622,   0,   0,   0,   0,   0,
-     0,   0,   0,   0, 623,   0,   0,   0, 624, 624, 624, 624, 624, 624, 624, 624,
-   625, 626, 627, 125, 125, 125, 125, 125,   4, 628, 629, 125, 125, 125, 125, 125,
-   630, 631, 632,  14,  14,  14, 633, 125, 634, 125, 125, 125, 125, 125, 125, 125,
-   635, 635, 636, 637, 638, 125, 125, 125, 125, 639, 640, 125, 641, 641, 641, 642,
-   125, 125, 125, 125, 125, 643, 643, 644, 125, 125, 125, 125, 125, 125, 645, 646,
-   647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 648, 649, 125, 125,
-   650, 650, 650, 650, 651, 652, 125, 125, 125, 125, 125, 125, 125, 125, 125, 334,
-     0,   0,   0, 653, 125, 125, 125, 125, 334,   0,   0, 247, 125, 125, 125, 125,
-   654,  27, 655, 656, 657, 658, 659, 660, 661, 662, 663, 662, 125, 125, 125, 664,
-     0,   0, 252,   0,   0,   0,   0,   0,   0, 266, 226, 334, 334, 334,   0, 605,
-     0,   0, 247, 125, 125, 125, 665,   0, 666,   0,   0, 252, 612, 667, 605, 125,
-     0,   0,   0,   0,   0, 668, 350, 350,   0,   0,   0,   0,   0,   0,   0, 669,
-     0,   0,   0,   0,   0, 285, 252, 228, 252,   0,   0,   0, 670, 285,   0,   0,
-   670,   0, 247, 667, 125, 125, 125, 125,   0,   0,   0,   0,   0, 266, 247, 350,
-   612,   0,   0, 671, 672, 252, 612, 612,   0, 330,   0,   0, 235, 125, 125, 285,
-   248, 248, 248, 248, 248, 248, 125, 125, 248, 248, 248, 319, 248, 248, 248, 248,
-   248, 318, 248, 248, 248, 248, 248, 248, 248, 248, 584, 248, 248, 248, 248, 248,
-   248, 248, 248, 248, 248, 248, 673, 125, 248, 318, 125, 125, 125, 125, 125, 125,
-   248, 248, 248, 248, 674, 248, 248, 248, 248, 248, 248, 125, 125, 125, 125, 125,
-   675, 125,   0,   0,   0,   0,   0,   0,   8,   8,   8,   8,   8,   8,   8,   8,
+    48,  48,  48,  48,  48,  48, 100,  48,  48,  48,  48,  48,  48, 204, 140, 140,
+    48, 204, 140, 140, 140, 140, 140, 140,  48,  48,  48,  48,  71,  48,  48,  48,
+    48,  48,  48, 140, 140, 140, 140, 140, 684, 140, 570, 570, 570, 570, 570, 570,
+    32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32,  32, 140,
+   391, 391, 391, 391, 391, 391, 391, 685, 391, 391, 391, 391, 391, 391, 391, 686,
+     0,   0,   0,   0,   1,   2,   1,   2,   0,   0,   3,   3,   4,   5,   4,   5,
+     4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   4,   6,   0,   0,   7,   0,
+     8,   8,   8,   8,   8,   8,   8,   9,  10,  11,  12,  11,  11,  11,  13,  11,
+    14,  14,  14,  14,  14,  14,  14,  14,  15,  14,  14,  14,  14,  14,  14,  14,
+    14,  14,  14,  16,  17,  18,  17,  17,  19,  20,  21,  21,  22,  21,  23,  24,
+    25,  26,  27,  27,  28,  29,  27,  30,  27,  27,  27,  27,  27,  31,  27,  27,
+    32,  33,  33,  33,  34,  27,  27,  27,  35,  35,  35,  36,  37,  37,  37,  38,
+    39,  39,  40,  41,  42,  43,  44,  27,  45,  46,  27,  27,  27,  27,  47,  27,
+    48,  48,  48,  48,  48,  49,  50,  48,  51,  52,  53,  54,  55,  56,  57,  58,
+    59,  60,  61,  62,  63,  64,  65,  66,  67,  68,  69,  70,  71,  72,  73,  74,
+    75,  76,  77,  78,  79,  80,  81,  82,  83,  84,  85,  86,  87,  88,  89,  90,
+    91,  92,  93,  94,  95,  96,  97,  98,  99, 100, 101, 102, 103, 104, 105, 106,
+   107, 108, 109, 109, 110, 111, 112, 109, 113, 114, 115, 116, 117, 118, 119, 120,
+   121, 122, 122, 123, 122, 124, 125, 125, 126, 127, 128, 129, 130, 131, 125, 125,
+   132, 132, 132, 132, 133, 132, 134, 135, 132, 133, 132, 136, 136, 137, 125, 125,
+   138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 139, 139, 140, 139, 139, 141,
+   142, 142, 142, 142, 142, 142, 142, 142, 143, 143, 143, 143, 144, 145, 143, 143,
+   144, 143, 143, 146, 147, 148, 143, 143, 143, 147, 143, 143, 143, 149, 143, 150,
+   143, 151, 152, 152, 152, 152, 152, 153, 154, 154, 154, 154, 154, 154, 154, 154,
+   155, 156, 157, 157, 157, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167,
+   168, 168, 168, 168, 168, 169, 170, 170, 171, 172, 173, 173, 173, 173, 173, 174,
+   173, 173, 175, 154, 154, 154, 154, 176, 177, 178, 179, 179, 180, 181, 182, 183,
+   184, 184, 185, 184, 186, 187, 168, 168, 188, 189, 190, 190, 190, 191, 190, 192,
+   193, 193, 194,   8, 195, 125, 125, 125, 196, 196, 196, 196, 197, 196, 196, 198,
+   199, 199, 199, 199, 200, 200, 200, 201, 202, 202, 202, 203, 204, 205, 205, 205,
+   206, 139, 139, 207, 208, 209, 210, 211,   4,   4, 212,   4,   4, 213, 214, 215,
+     4,   4,   4, 216,   8,   8,   8,   8,  11, 217,  11,  11, 217, 218,  11, 219,
+    11,  11,  11, 220, 220, 221,  11, 222, 223,   0,   0,   0,   0,   0, 224, 225,
+   226, 227,   0,   0, 228,   8,   8, 229,   0,   0, 230, 231, 232,   0,   4,   4,
+   233,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0, 234, 125, 235, 125,   0,   0, 236, 236, 236, 236, 236, 236, 236, 236,
+     0,   0,   0,   0,   0,   0,   0, 237,   0, 238,   0,   0,   0,   0,   0,   0,
+   239, 239, 239, 239, 239, 239,   4,   4, 240, 240, 240, 240, 240, 240, 240, 241,
+   139, 139, 140, 242, 242, 242, 243, 244, 143, 245, 246, 246, 246, 246,  14,  14,
+     0,   0,   0,   0,   0, 247, 125, 125, 248, 249, 248, 248, 248, 248, 248, 250,
+   248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 251, 125,   0,
+   252,   0, 253, 254, 255, 256, 256, 256, 256, 257, 258, 259, 259, 259, 259, 260,
+   261, 262, 262, 263, 142, 142, 142, 142, 264,   0, 262, 262,   0,   0, 265, 259,
+   142, 264,   0,   0,   0,   0, 142, 266,   0,   0,   0,   0,   0, 259, 259, 267,
+   259, 259, 259, 259, 259, 268,   0,   0, 248, 248, 248, 248,   0,   0,   0,   0,
+   269, 269, 269, 269, 269, 269, 269, 269, 270, 269, 269, 269, 271, 272, 272, 272,
+   273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 274, 125,  14,  14,  14,  14,
+    14,  14, 275, 275, 275, 275, 275, 276,   0,   0, 277,   4,   4,   4,   4,   4,
+   278,   4,   4,   4, 279, 280, 125, 281, 282, 282, 283, 284, 285, 285, 285, 286,
+   287, 287, 287, 287, 288, 289,  48,  48, 290, 290, 291, 292, 292, 293, 142, 294,
+   295, 295, 295, 295, 296, 297, 138, 298, 299, 299, 299, 300, 301, 302, 138, 138,
+   303, 303, 303, 303, 304, 305, 306, 307, 308, 309, 246,   4,   4, 310, 311, 152,
+   152, 152, 152, 152, 306, 306, 312, 313, 142, 142, 314, 142, 315, 142, 142, 316,
+   125, 125, 125, 125, 125, 125, 125, 125, 248, 248, 248, 248, 248, 248, 317, 248,
+   248, 248, 248, 248, 248, 318, 125, 125, 319, 320,  21, 321, 322,  27,  27,  27,
+    27,  27,  27,  27, 323, 324,  27,  27,  27,  27,  27,  27,  27,  27,  27,  27,
+    27,  27,  27, 325,  27,  27,  27,  27,  27, 326,  27,  27, 327, 125, 125,  27,
+     8, 284, 328,   0,   0, 329, 330, 331,  27,  27,  27,  27,  27,  27,  27, 332,
+   333,   0,   1,   2,   1,   2, 334, 258, 259, 335, 142, 264, 336, 337, 338, 339,
+   340, 341, 342, 343, 344, 344, 125, 125, 341, 341, 341, 341, 341, 341, 341, 345,
+   346,   0,   0, 347,  11,  11,  11,  11, 348, 349, 350, 125, 125,   0,   0, 351,
+   352, 353, 354, 354, 354, 355, 356, 357, 358, 358, 359, 360, 361, 362, 362, 363,
+   364, 365, 366, 366, 367, 368, 125, 125, 369, 369, 369, 369, 369, 370, 370, 370,
+   371, 372, 373, 374, 374, 375, 374, 376, 377, 377, 378, 379, 379, 379, 380, 381,
+   381, 382, 383, 384, 125, 125, 125, 125, 385, 385, 385, 385, 385, 385, 385, 385,
+   385, 385, 385, 386, 385, 387, 388, 125, 389,   4,   4, 390, 125, 125, 125, 125,
+   391, 392, 392, 393, 394, 395, 396, 396, 397, 398, 399, 125, 125, 125, 400, 401,
+   402, 403, 404, 405, 125, 125, 125, 125, 406, 406, 407, 408, 407, 409, 407, 407,
+   410, 411, 412, 413, 414, 414, 415, 415, 416, 416, 125, 125, 417, 417, 418, 419,
+   420, 420, 420, 421, 422, 423, 424, 425, 426, 427, 428, 125, 125, 125, 125, 125,
+   429, 429, 429, 429, 430, 125, 125, 125, 431, 431, 431, 432, 431, 431, 431, 433,
+   434, 434, 435, 436, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,  27,  45,
+   437, 437, 438, 439, 125, 125, 125, 440, 441, 441, 442, 443, 443, 444, 125, 445,
+   446, 125, 125, 447, 448, 125, 449, 450, 451, 451, 451, 451, 452, 453, 451, 454,
+   455, 455, 455, 455, 456, 457, 458, 459, 460, 460, 460, 461, 462, 463, 463, 464,
+   465, 465, 465, 465, 465, 465, 466, 467, 468, 469, 468, 468, 470, 125, 125, 125,
+   471, 472, 473, 474, 474, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484,
+   485, 485, 485, 485, 485, 486, 487, 125, 488, 488, 488, 488, 489, 490, 125, 125,
+   491, 491, 491, 492, 491, 493, 125, 125, 494, 494, 494, 494, 495, 496, 497, 125,
+   498, 498, 498, 499, 499, 125, 125, 125, 500, 501, 502, 500, 503, 125, 125, 125,
+   504, 504, 504, 505, 125, 125, 125, 125, 125, 125, 506, 506, 506, 506, 506, 507,
+   508, 509, 510, 511, 512, 513, 125, 125, 125, 125, 514, 515, 515, 514, 516, 125,
+   517, 517, 517, 517, 518, 519, 519, 519, 519, 519, 520, 154, 521, 521, 521, 522,
+   523, 125, 125, 125, 125, 125, 125, 125, 524, 525, 525, 526, 527, 525, 528, 529,
+   529, 530, 531, 532, 125, 125, 125, 125, 533, 534, 534, 535, 536, 537, 538, 539,
+   540, 541, 542, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 543, 544,
+   545, 546, 545, 547, 545, 548, 125, 125, 125, 125, 125, 549, 550, 550, 550, 551,
+   552, 552, 552, 552, 552, 552, 552, 552, 552, 553, 125, 125, 125, 125, 125, 125,
+   552, 552, 552, 552, 552, 552, 554, 555, 552, 552, 552, 552, 556, 125, 125, 125,
+   125, 557, 557, 557, 557, 557, 557, 558, 559, 559, 559, 559, 559, 559, 559, 559,
+   559, 559, 559, 559, 559, 560, 125, 125, 561, 561, 561, 561, 561, 561, 561, 561,
+   561, 561, 561, 561, 562, 125, 125, 125, 275, 275, 275, 275, 275, 275, 275, 275,
+   275, 275, 275, 563, 564, 565, 566, 567, 567, 567, 567, 568, 569, 570, 571, 572,
+   573, 573, 573, 573, 574, 575, 576, 577, 573, 125, 125, 125, 125, 125, 125, 125,
+   125, 125, 125, 125, 578, 578, 578, 578, 578, 579, 125, 125, 125, 125, 125, 125,
+   580, 580, 580, 580, 581, 580, 580, 580, 582, 580, 125, 125, 125, 125, 583, 584,
+   585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 586,
+   587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 588, 125, 125,
+   589, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 590,
+   591, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
+   256, 256, 592, 593, 125, 594, 595, 596, 596, 596, 596, 596, 596, 596, 596, 596,
+   596, 596, 596, 596, 596, 596, 596, 597, 598, 598, 598, 598, 598, 598, 599, 600,
+   601, 602, 603, 125, 125, 125, 125, 125,   8,   8, 604,   8, 605,   0,   0,   0,
+     0,   0,   0,   0, 603, 125, 125, 125,   0,   0,   0,   0,   0,   0,   0, 606,
+     0,   0, 607,   0,   0,   0, 608, 609, 610,   0, 611,   0,   0,   0, 235, 125,
+    11,  11,  11,  11, 612, 125, 125, 125, 125, 125, 125, 125,   0, 603,   0, 603,
+     0,   0,   0,   0,   0, 234,   0, 613,   0,   0,   0,   0,   0, 224,   0,   0,
+     0, 614, 615, 616, 617,   0,   0,   0, 618, 619,   0, 620, 621, 622,   0,   0,
+     0,   0, 623,   0,   0,   0,   0,   0,   0,   0,   0,   0, 624,   0,   0,   0,
+   625, 625, 625, 625, 625, 625, 625, 625, 626, 627, 628, 125, 125, 125, 125, 125,
+     4, 629, 630, 125, 125, 125, 125, 125, 631, 632, 633,  14,  14,  14, 634, 125,
+   635, 125, 125, 125, 125, 125, 125, 125, 636, 636, 637, 638, 639, 125, 125, 125,
+   125, 640, 641, 125, 642, 642, 642, 643, 125, 125, 125, 125, 125, 644, 644, 645,
+   125, 125, 125, 125, 125, 125, 646, 647, 648, 648, 648, 648, 648, 648, 648, 648,
+   648, 648, 648, 648, 649, 650, 125, 125, 651, 651, 651, 651, 652, 653, 125, 125,
+   125, 125, 125, 125, 125, 125, 125, 333,   0,   0,   0, 654, 125, 125, 125, 125,
+   333,   0,   0, 247, 125, 125, 125, 125, 655,  27, 656, 657, 658, 659, 660, 661,
+   662, 663, 664, 663, 125, 125, 125, 665,   0,   0, 357,   0,   0,   0,   0,   0,
+     0, 603, 226, 333, 333, 333,   0, 606,   0,   0, 247, 125, 125, 125, 666,   0,
+   667,   0,   0, 357, 613, 668, 606, 125,   0,   0,   0,   0,   0, 669, 349, 349,
+     0,   0,   0,   0,   0,   0,   0, 670,   0,   0,   0,   0,   0, 284, 357, 228,
+   357,   0,   0,   0, 671, 284,   0,   0, 671,   0, 247, 668, 125, 125, 125, 125,
+     0,   0,   0,   0,   0, 603, 247, 349, 613,   0,   0, 672, 673, 357, 613, 613,
+     0, 329,   0,   0, 235, 125, 125, 284, 248, 248, 248, 248, 248, 248, 125, 125,
+   248, 248, 248, 318, 248, 248, 248, 248, 248, 317, 248, 248, 248, 248, 248, 248,
+   248, 248, 584, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 674, 248,
+   248, 248, 248, 248, 248, 317, 125, 125, 248, 317, 125, 125, 125, 125, 125, 125,
+   248, 248, 248, 248, 675, 248, 248, 248, 248, 248, 248, 125, 125, 125, 125, 125,
+   676, 125,   0,   0,   0,   0,   0,   0,   8,   8,   8,   8,   8,   8,   8,   8,
      8,   8,   8,   8,   8,   8,   8,   0,   0,   0,   0,   0,   1,   2,   2,   2,
      2,   2,   3,   0,   0,   0,   4,   0,   2,   2,   2,   2,   2,   3,   2,   2,
      2,   2,   5,   0,   2,   5,   6,   0,   7,   7,   7,   7,   8,   9,  10,  11,
@@ -4071,33 +4074,33 @@
      0, 240,   0,   0, 241, 241, 241, 241,  18,  18,  18,  18,  18,  12, 242,  18,
    243, 243, 243, 243, 243, 243,  12, 244, 245,  12,  12, 244, 151, 154,  12,  12,
    151, 154, 151, 154,   0,   0,   0, 246, 247, 247, 247, 247, 247, 247, 248, 247,
-   247,  12,  12,  12, 247, 249,  12,  12,   0,   0,   0,  12,   0, 250,   0,   0,
-   251, 247, 252, 253,   0,   0, 247,   0, 254, 255, 255, 255, 255, 255, 255, 255,
-   255, 256, 257, 258, 259, 260, 260, 260, 260, 260, 260, 260, 260, 260, 261, 259,
-    12, 262, 263, 263, 263, 263, 263, 263, 264, 150, 150, 150, 150, 150, 150, 265,
-     0,  12,  12,  12, 150, 150, 150, 266, 260, 260, 260, 261, 260, 260,   0,   0,
-   267, 267, 267, 267, 267, 267, 267, 268, 267, 269,  12,  12, 270, 270, 270, 270,
-   271, 271, 271, 271, 271, 271, 271,  12, 272, 272, 272, 272, 272, 272,  12,  12,
-   237,   2,   2,   2,   2,   2, 231,   2,   2,   2, 273,  12, 274, 275, 276,  12,
-   277,   2,   2,   2, 278, 278, 278, 278, 278, 278, 278, 279,   0,   0, 246,  12,
-   280, 280, 280, 280, 280, 280,  12,  12, 281, 281, 281, 281, 281, 282,  12, 283,
-   281, 281, 282,  12, 284, 284, 284, 284, 284, 284, 284, 285, 286, 286, 286, 286,
-   286,  12,  12, 287, 150, 150, 150, 288, 289, 289, 289, 289, 289, 289, 289, 290,
-   289, 289, 291, 292, 145, 145, 145, 293, 294, 294, 294, 294, 294, 295,  12,  12,
-   294, 294, 294, 296, 294, 294, 296, 294, 297, 297, 297, 297, 298,  12,  12,  12,
-    12,  12, 299, 297, 300, 300, 300, 300, 300, 301,  12,  12, 155, 154, 155, 154,
-   155, 154,  12,  12,   2,   2,   3,   2,   2, 302, 303,  12, 300, 300, 300, 304,
-   300, 300, 304,  12, 150,  12,  12,  12, 150, 265, 305, 150, 150, 150, 150,  12,
-   247, 247, 247, 249, 247, 247, 249,  12,   2, 273,  12,  12, 306,  22,  12,  24,
-    25,  26,  25, 307, 308, 309,  25,  25,  50,  12,  12,  12, 310,  29,  29,  29,
-    29,  29,  29, 311, 312,  29,  29,  29,  29,  29,  12, 310,   7,   7,   7, 313,
-   232,   0,   0,   0,   0, 232,   0,  12,  29, 314,  29,  29,  29,  29,  29, 315,
-   316,   0,   0,   0,   0, 317, 260, 260, 260, 260, 260, 318, 319, 150, 319, 150,
-   319, 150, 319, 288,   0, 232,   0, 232,  12,  12, 316, 246, 320, 320, 320, 321,
-   320, 320, 320, 320, 320, 322, 320, 320, 320, 320, 322, 323, 320, 320, 320, 324,
-   320, 320, 322,  12, 232, 131,   0,   0,   0, 131,   0,   0,   8,   8,   8,  14,
-     0,   0,   0, 234, 325,  12,  12,  12,   0,   0,   0, 326, 327, 327, 327, 327,
-   327, 327, 327, 328, 329, 329, 329, 329, 330,  12,  12,  12, 215,   0,   0,   0,
+   247,  12,  12,  12, 247, 249,  12,  12,   0, 250,   0,   0, 251, 247, 252, 253,
+     0,   0, 247,   0, 254, 255, 255, 255, 255, 255, 255, 255, 255, 256, 257, 258,
+   259, 260, 260, 260, 260, 260, 260, 260, 260, 260, 261, 259,  12, 262, 263, 263,
+   263, 263, 263, 263, 264, 150, 150, 150, 150, 150, 150, 265,   0,  12,  12, 131,
+   150, 150, 150, 266, 260, 260, 260, 261, 260, 260,   0,   0, 267, 267, 267, 267,
+   267, 267, 267, 268, 267, 269,  12,  12, 270, 270, 270, 270, 271, 271, 271, 271,
+   271, 271, 271,  12, 272, 272, 272, 272, 272, 272,  12,  12, 237,   2,   2,   2,
+     2,   2, 231,   2,   2,   2, 273,  12, 274, 275, 276,  12, 277,   2,   2,   2,
+   278, 278, 278, 278, 278, 278, 278, 279,   0,   0, 246,  12, 280, 280, 280, 280,
+   280, 280,  12,  12, 281, 281, 281, 281, 281, 282,  12, 283, 281, 281, 282,  12,
+   284, 284, 284, 284, 284, 284, 284, 285, 286, 286, 286, 286, 286,  12,  12, 287,
+   150, 150, 150, 288, 289, 289, 289, 289, 289, 289, 289, 290, 289, 289, 291, 292,
+   145, 145, 145, 293, 294, 294, 294, 294, 294, 295,  12,  12, 294, 294, 294, 296,
+   294, 294, 296, 294, 297, 297, 297, 297, 298,  12,  12,  12,  12,  12, 299, 297,
+   300, 300, 300, 300, 300, 301,  12,  12, 155, 154, 155, 154, 155, 154,  12,  12,
+     2,   2,   3,   2,   2, 302, 303,  12, 300, 300, 300, 304, 300, 300, 304,  12,
+   150,  12,  12,  12, 150, 265, 305, 150, 150, 150, 150,  12, 247, 247, 247, 249,
+   247, 247, 249,  12,   2, 273,  12,  12, 306,  22,  12,  24,  25,  26,  25, 307,
+   308, 309,  25,  25,  50,  12,  12,  12, 310,  29,  29,  29,  29,  29,  29, 311,
+   312,  29,  29,  29,  29,  29,  12, 310,   7,   7,   7, 313, 232,   0,   0,   0,
+     0, 232,   0,  12,  29, 314,  29,  29,  29,  29,  29, 315, 316,   0,   0,   0,
+     0, 317, 260, 260, 260, 260, 260, 318, 319, 150, 319, 150, 319, 150, 319, 288,
+     0, 232,   0, 232,  12,  12, 316, 246, 320, 320, 320, 321, 320, 320, 320, 320,
+   320, 322, 320, 320, 320, 320, 322, 323, 320, 320, 320, 324, 320, 320, 322,  12,
+   232, 131,   0,   0,   0, 131,   0,   0,   8,   8,   8,  14,   0,   0,   0, 234,
+   325,  12,  12,  12,   0,   0,   0, 326, 327, 327, 327, 327, 327, 327, 327, 328,
+   329, 329, 329, 329, 330,  12,  12,  12, 215,   0,   0,   0,   0,   0,   0,  12,
    331, 331, 331, 331, 331,  12,  12, 332, 333, 333, 333, 333, 333, 333, 334,  12,
    335, 335, 335, 335, 335, 335, 336,  12, 337, 337, 337, 337, 337, 337, 337, 338,
    339, 339, 339, 339, 339,  12, 339, 339, 339, 340,  12,  12, 341, 341, 341, 341,
@@ -4159,232 +4162,232 @@
    260, 556, 260, 557, 558, 255, 255, 255, 559,  12,  12,  12, 560,  12,  12,  12,
    256, 561,  12,  12,  12, 260,  12,  12, 562, 562, 562, 562, 562, 562, 562,  12,
    563, 563, 563, 563, 563, 563, 564,  12, 563, 563, 563, 565, 563, 563, 565,  12,
-   563, 563, 566, 563,   7,   7,   7, 567,   7, 199,  12,  12,   0, 246,  12,  12,
-     0, 232, 316,   0,   0, 568, 228,   0,   0,   0, 568,   7, 213, 569,   7,   0,
-     0,   0, 570, 228,   8, 225,  12,  12,   0,   0, 234,  12,   0,   0,   0, 229,
-   571, 572, 316, 229,   0,   0, 240, 316,   0, 316,   0,   0,   0, 240, 232, 316,
-     0, 229,   0, 229,   0,   0, 240, 232,   0, 573, 239,   0, 229,   0,   0,   0,
-     0, 246,   0,   0,   0,   0,   0, 239, 574, 574, 574, 574, 574, 574, 574,  12,
-    12,  12, 575, 574, 576, 574, 574, 574,   2,   2,   2, 273,  12, 275, 273,  12,
-   241, 577, 241, 241, 241, 241, 578, 241, 579, 580, 577,  12,  19,  19,  19, 581,
-    12,  12,  12, 582, 583, 583, 583, 583, 583, 583, 583, 584, 583, 583, 583, 585,
-   583, 583, 585, 586, 587, 587, 587, 587, 587, 587, 587, 588, 589, 589, 589, 589,
-   589, 589, 590, 591, 592, 592, 592, 592, 592, 592, 593,  12, 151, 154, 151, 594,
-   151, 151, 151, 154, 595, 595, 595, 595, 595, 596, 595, 595, 595, 597,  12,  12,
-   598, 598, 598, 598, 598, 598, 598,  12, 598, 598, 599, 600,   0, 234,  12,  12,
-    29, 414,  29,  29, 601, 602, 414,  29,  50,  29, 603,  12, 604, 310, 603, 414,
-   601, 602, 603, 603, 601, 602,  50,  29,  50,  29, 414, 605,  29,  29, 606,  29,
-    29,  29,  29,  12, 414, 414, 606,  29,  51,  12,  12,  12,  12, 239,   0,   0,
-   607,  12,  12,  12, 246,  12,  12,  12,   0,   0,  12,   0,   0, 232, 131,   0,
-     0,   0,  12,  12,   0,   0,   0, 240,   0, 246,  12, 239, 608,  12,  12,  12,
-   247, 247, 609,  12, 610,  12,  12,  12,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0, 939, 940, 941, 942, 946, 948,   0, 962,
-   969, 970, 971, 976,1001,1002,1003,1008,   0,1033,1040,1041,1042,1043,1047,   0,
-     0,1080,1081,1082,1086,1110,   0,   0,1124,1125,1126,1127,1131,1133,   0,1147,
-  1154,1155,1156,1161,1187,1188,1189,1193,   0,1219,1226,1227,1228,1229,1233,   0,
-     0,1267,1268,1269,1273,1298,   0,1303, 943,1128, 944,1129, 954,1139, 958,1143,
-   959,1144, 960,1145, 961,1146, 964,1149,   0,   0, 973,1158, 974,1159, 975,1160,
-   983,1168, 978,1163, 988,1173, 990,1175, 991,1176, 993,1178, 994,1179,   0,   0,
-  1004,1190,1005,1191,1006,1192,1014,1199,1007,   0,   0,   0,1016,1201,1020,1206,
-     0,1022,1208,1025,1211,1023,1209,   0,   0,   0,   0,1032,1218,1037,1223,1035,
-  1221,   0,   0,   0,1044,1230,1045,1231,1049,1235,   0,   0,1058,1244,1064,1250,
-  1060,1246,1066,1252,1067,1253,1072,1258,1069,1255,1077,1264,1074,1261,   0,   0,
-  1083,1270,1084,1271,1085,1272,1088,1275,1089,1276,1096,1283,1103,1290,1111,1299,
-  1115,1118,1307,1120,1309,1121,1310,   0,1053,1239,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,1093,1280,   0,   0,   0,   0,   0,   0,   0,
+   563, 563, 566, 563,   0,  12,  12,  12,   7,   7,   7, 567,   7, 199,  12,  12,
+     0, 246,  12,  12,   0, 232, 316,   0,   0, 568, 228,   0,   0,   0, 568,   7,
+   213, 569,   7,   0,   0,   0, 570, 228,   8, 225,  12,  12,   0,   0, 234,  12,
+     0,   0,   0, 229, 571, 572, 316, 229,   0,   0, 240, 316,   0, 316,   0,   0,
+     0, 240, 232, 316,   0, 229,   0, 229,   0,   0, 240, 232,   0, 573, 239,   0,
+   229,   0,   0,   0,   0, 246,   0,   0,   0,   0,   0, 239, 574, 574, 574, 574,
+   574, 574, 574,  12,  12,  12, 575, 574, 576, 574, 574, 574,   2,   2,   2, 273,
+    12, 275, 273,  12, 241, 577, 241, 241, 241, 241, 578, 241, 579, 580, 577,  12,
+    19,  19,  19, 581,  12,  12,  12, 582, 583, 583, 583, 583, 583, 583, 583, 584,
+   583, 583, 583, 585, 583, 583, 585, 586, 587, 587, 587, 587, 587, 587, 587, 588,
+   589, 589, 589, 589, 589, 589, 590, 591, 592, 592, 592, 592, 592, 592, 593,  12,
+   151, 154, 151, 594, 151, 151, 151, 154, 595, 595, 595, 595, 595, 596, 595, 595,
+   595, 597,  12,  12, 598, 598, 598, 598, 598, 598, 598,  12, 598, 598, 599, 600,
+     0, 234,  12,  12,  29, 414,  29,  29, 601, 602, 414,  29,  50,  29, 603,  12,
+   604, 310, 603, 414, 601, 602, 603, 603, 601, 602,  50,  29,  50,  29, 414, 605,
+    29,  29, 606,  29,  29,  29,  29,  12, 414, 414, 606,  29,  51,  12,  12,  12,
+    12, 239,   0,   0, 607,  12,  12,  12, 246,  12,  12,  12,   0,   0,  12,   0,
+     0, 232, 131,   0,   0,   0,  12,  12,   0,   0,   0, 240,   0, 246,  12, 239,
+   608,  12,  12,  12, 247, 247, 609,  12, 610,  12,  12,  12,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 939, 940, 941, 942,
+   946, 948,   0, 962, 969, 970, 971, 976,1001,1002,1003,1008,   0,1033,1040,1041,
+  1042,1043,1047,   0,   0,1080,1081,1082,1086,1110,   0,   0,1124,1125,1126,1127,
+  1131,1133,   0,1147,1154,1155,1156,1161,1187,1188,1189,1193,   0,1219,1226,1227,
+  1228,1229,1233,   0,   0,1267,1268,1269,1273,1298,   0,1303, 943,1128, 944,1129,
+   954,1139, 958,1143, 959,1144, 960,1145, 961,1146, 964,1149,   0,   0, 973,1158,
+   974,1159, 975,1160, 983,1168, 978,1163, 988,1173, 990,1175, 991,1176, 993,1178,
+   994,1179,   0,   0,1004,1190,1005,1191,1006,1192,1014,1199,1007,   0,   0,   0,
+  1016,1201,1020,1206,   0,1022,1208,1025,1211,1023,1209,   0,   0,   0,   0,1032,
+  1218,1037,1223,1035,1221,   0,   0,   0,1044,1230,1045,1231,1049,1235,   0,   0,
+  1058,1244,1064,1250,1060,1246,1066,1252,1067,1253,1072,1258,1069,1255,1077,1264,
+  1074,1261,   0,   0,1083,1270,1084,1271,1085,1272,1088,1275,1089,1276,1096,1283,
+  1103,1290,1111,1299,1115,1118,1307,1120,1309,1121,1310,   0,1053,1239,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1093,1280,   0,   0,   0,
      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0, 949,1134,1010,1195,1050,1236,1090,1277,1341,1368,1340,
-  1367,1342,1369,1339,1366,   0,1320,1347,1418,1419,1323,1350,   0,   0, 992,1177,
-  1018,1204,1055,1241,1416,1417,1415,1424,1202,   0,   0,   0, 987,1172,   0,   0,
-  1031,1217,1321,1348,1322,1349,1338,1365, 950,1135, 951,1136, 979,1164, 980,1165,
-  1011,1196,1012,1197,1051,1237,1052,1238,1061,1247,1062,1248,1091,1278,1092,1279,
-  1071,1257,1076,1263,   0,   0, 997,1182,   0,   0,   0,   0,   0,   0, 945,1130,
-   982,1167,1337,1364,1335,1362,1046,1232,1422,1423,1113,1301,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   8,   9,   0,  10,1425,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   7,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,   0,1314,1427,   5,
-  1434,1438,1443,   0,1450,   0,1455,1461,1514,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0, 949,1134,1010,1195,1050,1236,1090,
+  1277,1341,1368,1340,1367,1342,1369,1339,1366,   0,1320,1347,1418,1419,1323,1350,
+     0,   0, 992,1177,1018,1204,1055,1241,1416,1417,1415,1424,1202,   0,   0,   0,
+   987,1172,   0,   0,1031,1217,1321,1348,1322,1349,1338,1365, 950,1135, 951,1136,
+   979,1164, 980,1165,1011,1196,1012,1197,1051,1237,1052,1238,1061,1247,1062,1248,
+  1091,1278,1092,1279,1071,1257,1076,1263,   0,   0, 997,1182,   0,   0,   0,   0,
+     0,   0, 945,1130, 982,1167,1337,1364,1335,1362,1046,1232,1422,1423,1113,1301,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   8,   9,   0,  10,
+  1425,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     7,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   0,   0,   0,   0,   0,
+     0,1314,1427,   5,1434,1438,1443,   0,1450,   0,1455,1461,1514,   0,   0,   0,
      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,1446,1458,1468,1476,1480,1486,1517,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,1446,1458,1468,1476,1480,1486,1517,   0,   0,   0,
      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,1489,1503,1494,1500,1508,   0,   0,   0,   0,1520,1521,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,1526,1528,   0,1525,   0,   0,   0,1522,
-     0,   0,   0,   0,1536,1532,1539,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,1534,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,1556,   0,   0,   0,   0,   0,   0,1548,1550,   0,1547,   0,   0,   0,1567,
-     0,   0,   0,   0,1558,1554,1561,   0,   0,   0,   0,   0,   0,   0,1568,1569,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,1529,1551,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,1523,1545,1524,1546,   0,   0,1527,1549,
-     0,   0,1570,1571,1530,1552,1531,1553,   0,   0,1533,1555,1535,1557,1537,1559,
-     0,   0,1572,1573,1544,1566,1538,1560,1540,1562,1541,1563,1542,1564,   0,   0,
-  1543,1565,   0,   0,   0,   0,   0,   0,   0,   0,1606,1607,1609,1608,1610,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,1613,   0,1611,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1612,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,1489,1503,1494,1500,1508,   0,   0,   0,   0,1520,
+  1521,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1526,1528,   0,1525,
+     0,   0,   0,1522,   0,   0,   0,   0,1536,1532,1539,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,1534,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,1556,   0,   0,   0,   0,   0,   0,1548,1550,   0,1547,
+     0,   0,   0,1567,   0,   0,   0,   0,1558,1554,1561,   0,   0,   0,   0,   0,
+     0,   0,1568,1569,   0,   0,   0,   0,   0,   0,   0,   0,   0,1529,1551,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1523,1545,1524,1546,
+     0,   0,1527,1549,   0,   0,1570,1571,1530,1552,1531,1553,   0,   0,1533,1555,
+  1535,1557,1537,1559,   0,   0,1572,1573,1544,1566,1538,1560,1540,1562,1541,1563,
+  1542,1564,   0,   0,1543,1565,   0,   0,   0,   0,   0,   0,   0,   0,1606,1607,
+  1609,1608,1610,   0,   0,   0,   0,   0,   0,   0,   0,   0,1613,   0,1611,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1612,
      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,1620,   0,   0,   0,   0,   0,   0,   0,1623,   0,   0,1624,   0,   0,   0,
+     0,   0,   0,   0,   0,1620,   0,   0,   0,   0,   0,   0,   0,1623,   0,   0,
+  1624,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,1614,1615,1616,1617,1618,1619,1621,1622,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,1628,1629,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,1625,1626,   0,1627,   0,   0,   0,1634,
+     0,   0,1635,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,1630,1631,1632,   0,   0,1633,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,1639,   0,   0,1638,1640,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,1636,1637,   0,   0,   0,   0,   0,   0,
+  1641,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,1642,1644,1643,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,1645,   0,   0,   0,   0,   0,   0,   0,1646,   0,   0,   0,
+     0,   0,   0,1648,1649,   0,1647,1650,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,1651,1653,1652,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,1654,   0,1655,1657,1656,   0,   0,   0,   0,1659,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,1660,   0,   0,   0,   0,1661,   0,
+     0,   0,   0,1662,   0,   0,   0,   0,1663,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,1658,   0,   0,   0,   0,   0,   0,   0,   0,   0,1664,
+     0,1665,1673,   0,1674,   0,   0,   0,   0,   0,   0,   0,   0,1666,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1668,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,1669,   0,   0,   0,   0,1670,   0,
+     0,   0,   0,1671,   0,   0,   0,   0,1672,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,1667,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,1675,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,1676,   0,1677,   0,1678,   0,1679,   0,1680,   0,   0,   0,1681,   0,
      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-  1614,1615,1616,1617,1618,1619,1621,1622,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,1628,1629,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,1625,1626,   0,1627,   0,   0,   0,1634,   0,   0,1635,   0,
+     0,   0,   0,   0,   0,   0,   0,1682,   0,1683,   0,   0,1684,1685,   0,1686,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 953,1138, 955,1140,
+   956,1141, 957,1142,1324,1351, 963,1148, 965,1150, 968,1153, 966,1151, 967,1152,
+  1378,1380,1379,1381, 984,1169, 985,1170,1420,1421, 986,1171, 989,1174, 995,1180,
+   998,1183, 996,1181, 999,1184,1000,1185,1015,1200,1329,1356,1017,1203,1019,1205,
+  1021,1207,1024,1210,1687,1688,1027,1213,1026,1212,1028,1214,1029,1215,1030,1216,
+  1034,1220,1036,1222,1039,1225,1038,1224,1334,1361,1336,1363,1382,1384,1383,1385,
+  1056,1242,1057,1243,1059,1245,1063,1249,1689,1690,1065,1251,1068,1254,1070,1256,
+  1386,1387,1388,1389,1691,1692,1073,1259,1075,1262,1079,1266,1078,1265,1095,1282,
+  1098,1285,1097,1284,1390,1391,1392,1393,1099,1286,1100,1287,1101,1288,1102,1289,
+  1105,1292,1104,1291,1106,1294,1107,1295,1108,1296,1114,1302,1119,1308,1122,1311,
+  1123,1312,1186,1260,1293,1305,   0,1394,   0,   0,   0,   0, 952,1137, 947,1132,
+  1317,1344,1316,1343,1319,1346,1318,1345,1693,1695,1371,1375,1370,1374,1373,1377,
+  1372,1376,1694,1696, 981,1166, 977,1162, 972,1157,1326,1353,1325,1352,1328,1355,
+  1327,1354,1697,1698,1009,1194,1013,1198,1054,1240,1048,1234,1331,1358,1330,1357,
+  1333,1360,1332,1359,1699,1700,1396,1401,1395,1400,1398,1403,1397,1402,1399,1404,
+  1094,1281,1087,1274,1406,1411,1405,1410,1408,1413,1407,1412,1409,1414,1109,1297,
+  1117,1306,1116,1304,1112,1300,   0,   0,   0,   0,   0,   0,1471,1472,1701,1705,
+  1702,1706,1703,1707,1430,1431,1715,1719,1716,1720,1717,1721,1477,1478,1729,1731,
+  1730,1732,   0,   0,1435,1436,1733,1735,1734,1736,   0,   0,1481,1482,1737,1741,
+  1738,1742,1739,1743,1439,1440,1751,1755,1752,1756,1753,1757,1490,1491,1765,1768,
+  1766,1769,1767,1770,1447,1448,1771,1774,1772,1775,1773,1776,1495,1496,1777,1779,
+  1778,1780,   0,   0,1451,1452,1781,1783,1782,1784,   0,   0,1504,1505,1785,1788,
+  1786,1789,1787,1790,   0,1459,   0,1791,   0,1792,   0,1793,1509,1510,1794,1798,
+  1795,1799,1796,1800,1462,1463,1808,1812,1809,1813,1810,1814,1467,  21,1475,  22,
+  1479,  23,1485,  24,1493,  27,1499,  28,1507,  29,   0,   0,1704,1708,1709,1710,
+  1711,1712,1713,1714,1718,1722,1723,1724,1725,1726,1727,1728,1740,1744,1745,1746,
+  1747,1748,1749,1750,1754,1758,1759,1760,1761,1762,1763,1764,1797,1801,1802,1803,
+  1804,1805,1806,1807,1811,1815,1816,1817,1818,1819,1820,1821,1470,1469,1822,1474,
+  1465,   0,1473,1825,1429,1428,1426,  12,1432,   0,  26,   0,   0,1315,1823,1484,
+  1466,   0,1483,1829,1433,  13,1437,  14,1441,1826,1827,1828,1488,1487,1513,  19,
+     0,   0,1492,1515,1445,1444,1442,  15,   0,1831,1832,1833,1502,1501,1516,  25,
+  1497,1498,1506,1518,1457,1456,1454,  17,1453,1313,  11,   3,   0,   0,1824,1512,
+  1519,   0,1511,1830,1449,  16,1460,  18,1464,   4,   0,   0,  30,  31,   0,   0,
      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,1630,1631,1632,   0,   0,1633,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-  1639,   0,   0,1638,1640,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,1636,1637,   0,   0,   0,   0,   0,   0,1641,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,1642,1644,1643,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-  1645,   0,   0,   0,   0,   0,   0,   0,1646,   0,   0,   0,   0,   0,   0,1648,
-  1649,   0,1647,1650,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,1651,1653,1652,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,1654,   0,1655,1657,1656,   0,   0,   0,   0,1659,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,1660,   0,   0,   0,   0,1661,   0,   0,   0,   0,1662,
-     0,   0,   0,   0,1663,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,1658,   0,   0,   0,   0,   0,   0,   0,   0,   0,1664,   0,1665,1673,   0,
-  1674,   0,   0,   0,   0,   0,   0,   0,   0,1666,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1668,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,1669,   0,   0,   0,   0,1670,   0,   0,   0,   0,1671,
-     0,   0,   0,   0,1672,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,1667,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1675,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1676,   0,
-  1677,   0,1678,   0,1679,   0,1680,   0,   0,   0,1681,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,1682,   0,1683,   0,   0,1684,1685,   0,1686,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0, 953,1138, 955,1140, 956,1141, 957,1142,
-  1324,1351, 963,1148, 965,1150, 968,1153, 966,1151, 967,1152,1378,1380,1379,1381,
-   984,1169, 985,1170,1420,1421, 986,1171, 989,1174, 995,1180, 998,1183, 996,1181,
-   999,1184,1000,1185,1015,1200,1329,1356,1017,1203,1019,1205,1021,1207,1024,1210,
-  1687,1688,1027,1213,1026,1212,1028,1214,1029,1215,1030,1216,1034,1220,1036,1222,
-  1039,1225,1038,1224,1334,1361,1336,1363,1382,1384,1383,1385,1056,1242,1057,1243,
-  1059,1245,1063,1249,1689,1690,1065,1251,1068,1254,1070,1256,1386,1387,1388,1389,
-  1691,1692,1073,1259,1075,1262,1079,1266,1078,1265,1095,1282,1098,1285,1097,1284,
-  1390,1391,1392,1393,1099,1286,1100,1287,1101,1288,1102,1289,1105,1292,1104,1291,
-  1106,1294,1107,1295,1108,1296,1114,1302,1119,1308,1122,1311,1123,1312,1186,1260,
-  1293,1305,   0,1394,   0,   0,   0,   0, 952,1137, 947,1132,1317,1344,1316,1343,
-  1319,1346,1318,1345,1693,1695,1371,1375,1370,1374,1373,1377,1372,1376,1694,1696,
-   981,1166, 977,1162, 972,1157,1326,1353,1325,1352,1328,1355,1327,1354,1697,1698,
-  1009,1194,1013,1198,1054,1240,1048,1234,1331,1358,1330,1357,1333,1360,1332,1359,
-  1699,1700,1396,1401,1395,1400,1398,1403,1397,1402,1399,1404,1094,1281,1087,1274,
-  1406,1411,1405,1410,1408,1413,1407,1412,1409,1414,1109,1297,1117,1306,1116,1304,
-  1112,1300,   0,   0,   0,   0,   0,   0,1471,1472,1701,1705,1702,1706,1703,1707,
-  1430,1431,1715,1719,1716,1720,1717,1721,1477,1478,1729,1731,1730,1732,   0,   0,
-  1435,1436,1733,1735,1734,1736,   0,   0,1481,1482,1737,1741,1738,1742,1739,1743,
-  1439,1440,1751,1755,1752,1756,1753,1757,1490,1491,1765,1768,1766,1769,1767,1770,
-  1447,1448,1771,1774,1772,1775,1773,1776,1495,1496,1777,1779,1778,1780,   0,   0,
-  1451,1452,1781,1783,1782,1784,   0,   0,1504,1505,1785,1788,1786,1789,1787,1790,
-     0,1459,   0,1791,   0,1792,   0,1793,1509,1510,1794,1798,1795,1799,1796,1800,
-  1462,1463,1808,1812,1809,1813,1810,1814,1467,  21,1475,  22,1479,  23,1485,  24,
-  1493,  27,1499,  28,1507,  29,   0,   0,1704,1708,1709,1710,1711,1712,1713,1714,
-  1718,1722,1723,1724,1725,1726,1727,1728,1740,1744,1745,1746,1747,1748,1749,1750,
-  1754,1758,1759,1760,1761,1762,1763,1764,1797,1801,1802,1803,1804,1805,1806,1807,
-  1811,1815,1816,1817,1818,1819,1820,1821,1470,1469,1822,1474,1465,   0,1473,1825,
-  1429,1428,1426,  12,1432,   0,  26,   0,   0,1315,1823,1484,1466,   0,1483,1829,
-  1433,  13,1437,  14,1441,1826,1827,1828,1488,1487,1513,  19,   0,   0,1492,1515,
-  1445,1444,1442,  15,   0,1831,1832,1833,1502,1501,1516,  25,1497,1498,1506,1518,
-  1457,1456,1454,  17,1453,1313,  11,   3,   0,   0,1824,1512,1519,   0,1511,1830,
-  1449,  16,1460,  18,1464,   4,   0,   0,  30,  31,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,  20,   0,
-     0,   0,   2,   6,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,1834,1835,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,1836,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,1837,1839,1838,   0,   0,   0,   0,1840,   0,   0,   0,
-     0,1841,   0,   0,1842,   0,   0,   0,   0,   0,   0,   0,1843,   0,1844,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,1845,   0,   0,1846,   0,   0,1847,
-     0,1848,   0,   0,   0,   0,   0,   0, 937,   0,1850,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,1849, 936, 938,1851,1852,   0,   0,1853,1854,   0,   0,
-  1855,1856,   0,   0,   0,   0,   0,   0,1857,1858,   0,   0,1861,1862,   0,   0,
-  1863,1864,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,1867,1868,1869,1870,1859,1860,1865,1866,   0,   0,   0,   0,
-     0,   0,1871,1872,1873,1874,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,  32,  33,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,1875,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,1877,   0,1878,   0,1879,   0,1880,   0,1881,   0,1882,   0,
-  1883,   0,1884,   0,1885,   0,1886,   0,1887,   0,1888,   0,   0,1889,   0,1890,
-     0,1891,   0,   0,   0,   0,   0,   0,1892,1893,   0,1894,1895,   0,1896,1897,
-     0,1898,1899,   0,1900,1901,   0,   0,   0,   0,   0,   0,1876,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,1902,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,1904,   0,1905,   0,1906,   0,1907,   0,1908,   0,1909,   0,
-  1910,   0,1911,   0,1912,   0,1913,   0,1914,   0,1915,   0,   0,1916,   0,1917,
-     0,1918,   0,   0,   0,   0,   0,   0,1919,1920,   0,1921,1922,   0,1923,1924,
-     0,1925,1926,   0,1927,1928,   0,   0,   0,   0,   0,   0,1903,   0,   0,1929,
-  1930,1931,1932,   0,   0,   0,1933,   0, 710, 385, 724, 715, 455, 103, 186, 825,
-   825, 242, 751, 205, 241, 336, 524, 601, 663, 676, 688, 738, 411, 434, 474, 500,
-   649, 746, 799, 108, 180, 416, 482, 662, 810, 275, 462, 658, 692, 344, 618, 679,
-   293, 388, 440, 492, 740, 116, 146, 168, 368, 414, 481, 527, 606, 660, 665, 722,
-   781, 803, 809, 538, 553, 588, 642, 758, 811, 701, 233, 299, 573, 612, 487, 540,
-   714, 779, 232, 267, 412, 445, 457, 585, 594, 766, 167, 613, 149, 148, 560, 589,
-   648, 768, 708, 345, 411, 704, 105, 259, 313, 496, 518, 174, 542, 120, 307, 101,
-   430, 372, 584, 183, 228, 529, 650, 697, 424, 732, 428, 349, 632, 355, 517, 110,
-   135, 147, 403, 580, 624, 700, 750, 170, 193, 245, 297, 374, 463, 543, 763, 801,
-   812, 815, 162, 384, 420, 730, 287, 330, 337, 366, 459, 476, 509, 558, 591, 610,
-   726, 652, 734, 759, 154, 163, 198, 473, 683, 697, 292, 311, 353, 423, 572, 494,
-   113, 217, 259, 280, 314, 499, 506, 603, 608, 752, 778, 782, 788, 117, 557, 748,
-   774, 320, 109, 126, 260, 265, 373, 411, 479, 523, 655, 737, 823, 380, 765, 161,
-   395, 398, 438, 451, 502, 516, 537, 583, 791, 136, 340, 769, 122, 273, 446, 727,
-   305, 322, 400, 496, 771, 155, 190, 269, 377, 391, 406, 432, 501, 519, 599, 684,
-   687, 749, 776, 175, 452, 191, 480, 510, 659, 772, 805, 813, 397, 444, 619, 566,
-   568, 575, 491, 471, 707, 111, 636, 156, 153, 288, 346, 578, 256, 435, 383, 729,
-   680, 767, 694, 295, 128, 210,   0,   0, 227,   0, 379,   0,   0, 150, 493, 525,
-   544, 551, 552, 556, 783, 576, 604,   0, 661,   0, 703,   0,   0, 735, 743,   0,
-     0,   0, 793, 794, 795, 808, 741, 773, 118, 127, 130, 166, 169, 177, 207, 213,
-   215, 226, 229, 268, 270, 317, 327, 329, 335, 369, 375, 381, 404, 441, 448, 458,
-   477, 484, 503, 539, 545, 547, 546, 548, 549, 550, 554, 555, 561, 564, 569, 591,
-   593, 595, 598, 607, 620, 625, 625, 651, 690, 695, 705, 706, 716, 717, 733, 735,
-   777, 786, 790, 315, 869, 623,   0,   0, 102, 145, 134, 115, 129, 138, 165, 171,
-   207, 202, 206, 212, 227, 231, 240, 243, 250, 254, 294, 296, 303, 308, 319, 325,
-   321, 329, 326, 335, 341, 357, 360, 362, 370, 379, 388, 389, 393, 421, 424, 438,
-   456, 454, 458, 465, 477, 535, 485, 490, 493, 507, 512, 514, 521, 522, 525, 526,
-   528, 533, 532, 541, 565, 569, 574, 586, 591, 597, 607, 637, 647, 674, 691, 693,
-   695, 698, 703, 699, 705, 704, 702, 706, 709, 717, 728, 736, 747, 754, 770, 777,
-   783, 784, 786, 787, 790, 802, 825, 848, 847, 857,  55,  65,  66, 883, 892, 916,
-   822, 824,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,1586,   0,1605,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,1602,1603,1934,1935,1574,1575,1576,1577,1579,1580,1581,1583,1584,   0,
-  1585,1587,1588,1589,1591,   0,1592,   0,1593,1594,   0,1595,1596,   0,1598,1599,
-  1600,1601,1604,1582,1578,1590,1597,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,1936,   0,1937,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,1938,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,1939,1940,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,1941,1942,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,1944,1943,   0,1945,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,1946,1947,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-  1948,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,1949,1950,1951,1952,1953,1954,1955,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,1956,1957,1958,1960,1959,1961,   0,   0,   0,   0,   0,   0,   0,
-     0,   0,   0,   0,   0,   0,   0,   0, 106, 104, 107, 826, 114, 118, 119, 121,
-   123, 124, 127, 125,  34, 830, 130, 131, 132, 137, 827,  35, 133, 139, 829, 142,
-   143, 112, 144, 145, 924, 151, 152,  37, 157, 158, 159, 160,  38, 165, 166, 169,
-   171, 172, 173, 174, 176, 177, 178, 179, 181, 182, 182, 182, 833, 468, 184, 185,
-   834, 187, 188, 189, 196, 192, 194, 195, 197, 199, 200, 201, 203, 204, 204, 206,
-   208, 209, 211, 218, 213, 219, 214, 216, 153, 234, 221, 222, 223, 220, 225, 224,
-   230, 835, 235, 236, 237, 238, 239, 244, 836, 837, 247, 248, 249, 246, 251,  39,
-    40, 253, 255, 255, 838, 257, 258, 259, 261, 839, 262, 263, 301, 264,  41, 266,
-   270, 272, 271, 841, 274, 842, 277, 276, 278, 281, 282,  42, 283, 284, 285, 286,
-    43, 843,  44, 289, 290, 291, 293, 934, 298, 845, 845, 621, 300, 300,  45, 852,
-   894, 302, 304,  46, 306, 309, 310, 312, 316,  48,  47, 317, 846, 318, 323, 324,
-   325, 324, 328, 329, 333, 331, 332, 334, 335, 336, 338, 339, 342, 343, 347, 351,
-   849, 350, 348, 352, 354, 359, 850, 361, 358, 356,  49, 363, 365, 367, 364,  50,
-   369, 371, 851, 376, 386, 378,  53, 381,  52,  51, 140, 141, 387, 382, 614,  78,
-   388, 389, 390, 394, 392, 856,  54, 399, 396, 402, 404, 858, 405, 401, 407,  55,
-   408, 409, 410, 413, 859, 415,  56, 417, 860, 418,  57, 419, 422, 424, 425, 861,
-   840, 862, 426, 863, 429, 431, 427, 433, 437, 441, 438, 439, 442, 443, 864, 436,
-   449, 450,  58, 454, 453, 865, 447, 460, 866, 867, 461, 466, 465, 464,  59, 467,
-   470, 469, 472, 828, 475, 868, 478, 870, 483, 485, 486, 871, 488, 489, 872, 873,
-   495, 497,  60, 498,  61,  61, 504, 505, 507, 508, 511,  62, 513, 874, 515, 875,
-   518, 844, 520, 876, 877, 878,  63,  64, 528, 880, 879, 881, 882, 530, 531, 531,
-   533,  66, 534,  67,  68, 884, 536, 538, 541,  69, 885, 549, 886, 887, 556, 559,
-    70, 561, 562, 563, 888, 889, 889, 567,  71, 890, 570, 571,  72, 891, 577,  73,
-   581, 579, 582, 893, 587,  74, 590, 592, 596,  75, 895, 896,  76, 897, 600, 898,
-   602, 605, 607, 899, 900, 609, 901, 611, 853,  77, 615, 616,  79, 617, 252, 902,
-   903, 854, 855, 621, 622, 731,  80, 627, 626, 628, 164, 629, 630, 631, 633, 904,
-   632, 634, 639, 640, 635, 641, 646, 651, 638, 643, 644, 645, 905, 907, 906,  81,
-   653, 654, 656, 911, 657, 908,  82,  83, 909, 910,  84, 664, 665, 666, 667, 669,
-   668, 671, 670, 674, 672, 673, 675,  85, 677, 678,  86, 681, 682, 912, 685, 686,
-    87, 689,  36, 913, 914,  88,  89, 696, 702, 709, 711, 915, 712, 713, 718, 719,
-   917, 831, 721, 720, 723, 832, 725, 728, 918, 919, 739, 742, 744, 920, 745, 753,
-   756, 757, 755, 760, 761, 921, 762,  90, 764, 922,  91, 775, 279, 780, 923, 925,
-    92,  93, 785, 926,  94, 927, 787, 787, 789, 928, 792,  95, 796, 797, 798, 800,
-    96, 929, 802, 804, 806,  97,  98, 807, 930,  99, 931, 932, 933, 814, 100, 816,
-   817, 818, 819, 820, 821, 935,   0,   0,
+     0,   0,  20,   0,   0,   0,   2,   6,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,1834,1835,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1836,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,1837,1839,1838,   0,   0,   0,   0,
+  1840,   0,   0,   0,   0,1841,   0,   0,1842,   0,   0,   0,   0,   0,   0,   0,
+  1843,   0,1844,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1845,   0,   0,
+  1846,   0,   0,1847,   0,1848,   0,   0,   0,   0,   0,   0, 937,   0,1850,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,1849, 936, 938,1851,1852,   0,   0,
+  1853,1854,   0,   0,1855,1856,   0,   0,   0,   0,   0,   0,1857,1858,   0,   0,
+  1861,1862,   0,   0,1863,1864,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,1867,1868,1869,1870,1859,1860,1865,1866,
+     0,   0,   0,   0,   0,   0,1871,1872,1873,1874,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,  32,  33,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,1875,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,1877,   0,1878,   0,1879,   0,1880,   0,
+  1881,   0,1882,   0,1883,   0,1884,   0,1885,   0,1886,   0,1887,   0,1888,   0,
+     0,1889,   0,1890,   0,1891,   0,   0,   0,   0,   0,   0,1892,1893,   0,1894,
+  1895,   0,1896,1897,   0,1898,1899,   0,1900,1901,   0,   0,   0,   0,   0,   0,
+  1876,   0,   0,   0,   0,   0,   0,   0,   0,   0,1902,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,1904,   0,1905,   0,1906,   0,1907,   0,
+  1908,   0,1909,   0,1910,   0,1911,   0,1912,   0,1913,   0,1914,   0,1915,   0,
+     0,1916,   0,1917,   0,1918,   0,   0,   0,   0,   0,   0,1919,1920,   0,1921,
+  1922,   0,1923,1924,   0,1925,1926,   0,1927,1928,   0,   0,   0,   0,   0,   0,
+  1903,   0,   0,1929,1930,1931,1932,   0,   0,   0,1933,   0, 710, 385, 724, 715,
+   455, 103, 186, 825, 825, 242, 751, 205, 241, 336, 524, 601, 663, 676, 688, 738,
+   411, 434, 474, 500, 649, 746, 799, 108, 180, 416, 482, 662, 810, 275, 462, 658,
+   692, 344, 618, 679, 293, 388, 440, 492, 740, 116, 146, 168, 368, 414, 481, 527,
+   606, 660, 665, 722, 781, 803, 809, 538, 553, 588, 642, 758, 811, 701, 233, 299,
+   573, 612, 487, 540, 714, 779, 232, 267, 412, 445, 457, 585, 594, 766, 167, 613,
+   149, 148, 560, 589, 648, 768, 708, 345, 411, 704, 105, 259, 313, 496, 518, 174,
+   542, 120, 307, 101, 430, 372, 584, 183, 228, 529, 650, 697, 424, 732, 428, 349,
+   632, 355, 517, 110, 135, 147, 403, 580, 624, 700, 750, 170, 193, 245, 297, 374,
+   463, 543, 763, 801, 812, 815, 162, 384, 420, 730, 287, 330, 337, 366, 459, 476,
+   509, 558, 591, 610, 726, 652, 734, 759, 154, 163, 198, 473, 683, 697, 292, 311,
+   353, 423, 572, 494, 113, 217, 259, 280, 314, 499, 506, 603, 608, 752, 778, 782,
+   788, 117, 557, 748, 774, 320, 109, 126, 260, 265, 373, 411, 479, 523, 655, 737,
+   823, 380, 765, 161, 395, 398, 438, 451, 502, 516, 537, 583, 791, 136, 340, 769,
+   122, 273, 446, 727, 305, 322, 400, 496, 771, 155, 190, 269, 377, 391, 406, 432,
+   501, 519, 599, 684, 687, 749, 776, 175, 452, 191, 480, 510, 659, 772, 805, 813,
+   397, 444, 619, 566, 568, 575, 491, 471, 707, 111, 636, 156, 153, 288, 346, 578,
+   256, 435, 383, 729, 680, 767, 694, 295, 128, 210,   0,   0, 227,   0, 379,   0,
+     0, 150, 493, 525, 544, 551, 552, 556, 783, 576, 604,   0, 661,   0, 703,   0,
+     0, 735, 743,   0,   0,   0, 793, 794, 795, 808, 741, 773, 118, 127, 130, 166,
+   169, 177, 207, 213, 215, 226, 229, 268, 270, 317, 327, 329, 335, 369, 375, 381,
+   404, 441, 448, 458, 477, 484, 503, 539, 545, 547, 546, 548, 549, 550, 554, 555,
+   561, 564, 569, 591, 593, 595, 598, 607, 620, 625, 625, 651, 690, 695, 705, 706,
+   716, 717, 733, 735, 777, 786, 790, 315, 869, 623,   0,   0, 102, 145, 134, 115,
+   129, 138, 165, 171, 207, 202, 206, 212, 227, 231, 240, 243, 250, 254, 294, 296,
+   303, 308, 319, 325, 321, 329, 326, 335, 341, 357, 360, 362, 370, 379, 388, 389,
+   393, 421, 424, 438, 456, 454, 458, 465, 477, 535, 485, 490, 493, 507, 512, 514,
+   521, 522, 525, 526, 528, 533, 532, 541, 565, 569, 574, 586, 591, 597, 607, 637,
+   647, 674, 691, 693, 695, 698, 703, 699, 705, 704, 702, 706, 709, 717, 728, 736,
+   747, 754, 770, 777, 783, 784, 786, 787, 790, 802, 825, 848, 847, 857,  55,  65,
+    66, 883, 892, 916, 822, 824,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,1586,   0,1605,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,1602,1603,1934,1935,1574,1575,1576,1577,1579,1580,
+  1581,1583,1584,   0,1585,1587,1588,1589,1591,   0,1592,   0,1593,1594,   0,1595,
+  1596,   0,1598,1599,1600,1601,1604,1582,1578,1590,1597,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,1936,   0,1937,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,1938,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1939,1940,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,1941,1942,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,1944,1943,   0,1945,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,1946,1947,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,1948,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,1949,1950,1951,1952,1953,1954,
+  1955,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,1956,1957,1958,1960,1959,1961,   0,   0,   0,
+     0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, 106, 104, 107, 826,
+   114, 118, 119, 121, 123, 124, 127, 125,  34, 830, 130, 131, 132, 137, 827,  35,
+   133, 139, 829, 142, 143, 112, 144, 145, 924, 151, 152,  37, 157, 158, 159, 160,
+    38, 165, 166, 169, 171, 172, 173, 174, 176, 177, 178, 179, 181, 182, 182, 182,
+   833, 468, 184, 185, 834, 187, 188, 189, 196, 192, 194, 195, 197, 199, 200, 201,
+   203, 204, 204, 206, 208, 209, 211, 218, 213, 219, 214, 216, 153, 234, 221, 222,
+   223, 220, 225, 224, 230, 835, 235, 236, 237, 238, 239, 244, 836, 837, 247, 248,
+   249, 246, 251,  39,  40, 253, 255, 255, 838, 257, 258, 259, 261, 839, 262, 263,
+   301, 264,  41, 266, 270, 272, 271, 841, 274, 842, 277, 276, 278, 281, 282,  42,
+   283, 284, 285, 286,  43, 843,  44, 289, 290, 291, 293, 934, 298, 845, 845, 621,
+   300, 300,  45, 852, 894, 302, 304,  46, 306, 309, 310, 312, 316,  48,  47, 317,
+   846, 318, 323, 324, 325, 324, 328, 329, 333, 331, 332, 334, 335, 336, 338, 339,
+   342, 343, 347, 351, 849, 350, 348, 352, 354, 359, 850, 361, 358, 356,  49, 363,
+   365, 367, 364,  50, 369, 371, 851, 376, 386, 378,  53, 381,  52,  51, 140, 141,
+   387, 382, 614,  78, 388, 389, 390, 394, 392, 856,  54, 399, 396, 402, 404, 858,
+   405, 401, 407,  55, 408, 409, 410, 413, 859, 415,  56, 417, 860, 418,  57, 419,
+   422, 424, 425, 861, 840, 862, 426, 863, 429, 431, 427, 433, 437, 441, 438, 439,
+   442, 443, 864, 436, 449, 450,  58, 454, 453, 865, 447, 460, 866, 867, 461, 466,
+   465, 464,  59, 467, 470, 469, 472, 828, 475, 868, 478, 870, 483, 485, 486, 871,
+   488, 489, 872, 873, 495, 497,  60, 498,  61,  61, 504, 505, 507, 508, 511,  62,
+   513, 874, 515, 875, 518, 844, 520, 876, 877, 878,  63,  64, 528, 880, 879, 881,
+   882, 530, 531, 531, 533,  66, 534,  67,  68, 884, 536, 538, 541,  69, 885, 549,
+   886, 887, 556, 559,  70, 561, 562, 563, 888, 889, 889, 567,  71, 890, 570, 571,
+    72, 891, 577,  73, 581, 579, 582, 893, 587,  74, 590, 592, 596,  75, 895, 896,
+    76, 897, 600, 898, 602, 605, 607, 899, 900, 609, 901, 611, 853,  77, 615, 616,
+    79, 617, 252, 902, 903, 854, 855, 621, 622, 731,  80, 627, 626, 628, 164, 629,
+   630, 631, 633, 904, 632, 634, 639, 640, 635, 641, 646, 651, 638, 643, 644, 645,
+   905, 907, 906,  81, 653, 654, 656, 911, 657, 908,  82,  83, 909, 910,  84, 664,
+   665, 666, 667, 669, 668, 671, 670, 674, 672, 673, 675,  85, 677, 678,  86, 681,
+   682, 912, 685, 686,  87, 689,  36, 913, 914,  88,  89, 696, 702, 709, 711, 915,
+   712, 713, 718, 719, 917, 831, 721, 720, 723, 832, 725, 728, 918, 919, 739, 742,
+   744, 920, 745, 753, 756, 757, 755, 760, 761, 921, 762,  90, 764, 922,  91, 775,
+   279, 780, 923, 925,  92,  93, 785, 926,  94, 927, 787, 787, 789, 928, 792,  95,
+   796, 797, 798, 800,  96, 929, 802, 804, 806,  97,  98, 807, 930,  99, 931, 932,
+   933, 814, 100, 816, 817, 818, 819, 820, 821, 935,   0,   0,
 };
 static const int16_t
 _hb_ucd_i16[92] =
@@ -4400,12 +4403,12 @@
 static inline uint_fast8_t
 _hb_ucd_gc (unsigned u)
 {
-  return u<1114110u?_hb_ucd_u8[6800+(((_hb_ucd_u8[1312+(((_hb_ucd_u16[((_hb_ucd_u8[544+(((_hb_ucd_u8[u>>1>>3>>3>>4])<<4)+((u>>1>>3>>3)&15u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2;
+  return u<1114110u?_hb_ucd_u8[6808+(((_hb_ucd_u8[1312+(((_hb_ucd_u16[((_hb_ucd_u8[544+(((_hb_ucd_u8[u>>1>>3>>3>>4])<<4)+((u>>1>>3>>3)&15u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2;
 }
 static inline uint_fast8_t
 _hb_ucd_ccc (unsigned u)
 {
-  return u<125259u?_hb_ucd_u8[8792+(((_hb_ucd_u8[8236+(((_hb_ucd_u8[7776+(((_hb_ucd_u8[7424+(((_hb_ucd_u8[7178+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0;
+  return u<125259u?_hb_ucd_u8[8800+(((_hb_ucd_u8[8244+(((_hb_ucd_u8[7784+(((_hb_ucd_u8[7432+(((_hb_ucd_u8[7186+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0;
 }
 static inline unsigned
 _hb_ucd_b4 (const uint8_t* a, unsigned i)
@@ -4415,24 +4418,24 @@
 static inline int_fast16_t
 _hb_ucd_bmg (unsigned u)
 {
-  return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[9684+(((_hb_ucd_u8[9452+(((_hb_ucd_u8[9356+(((_hb_ucd_b4(9292+_hb_ucd_u8,u>>1>>2>>3>>3))<<3)+((u>>1>>2>>3)&7u))])<<3)+((u>>1>>2)&7u))])<<2)+((u>>1)&3u))])<<1)+((u)&1u)]:0;
+  return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[9692+(((_hb_ucd_u8[9460+(((_hb_ucd_u8[9364+(((_hb_ucd_b4(9300+_hb_ucd_u8,u>>1>>2>>3>>3))<<3)+((u>>1>>2>>3)&7u))])<<3)+((u>>1>>2)&7u))])<<2)+((u>>1)&3u))])<<1)+((u)&1u)]:0;
 }
 static inline uint_fast8_t
 _hb_ucd_sc (unsigned u)
 {
-  return u<918000u?_hb_ucd_u8[11118+(((_hb_ucd_u16[4024+(((_hb_ucd_u16[2040+(((_hb_ucd_u8[10382+(((_hb_ucd_u8[9932+(u>>2>>2>>3>>4)])<<4)+((u>>2>>2>>3)&15u))])<<3)+((u>>2>>2)&7u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:2;
+  return u<918000u?_hb_ucd_u8[11126+(((_hb_ucd_u16[4040+(((_hb_ucd_u16[2048+(((_hb_ucd_u8[10390+(((_hb_ucd_u8[9940+(u>>2>>2>>3>>4)])<<4)+((u>>2>>2>>3)&15u))])<<3)+((u>>2>>2)&7u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:2;
 }
 static inline uint_fast16_t
 _hb_ucd_dm (unsigned u)
 {
-  return u<195102u?_hb_ucd_u16[6728+(((_hb_ucd_u8[13944+(((_hb_ucd_u8[13562+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0;
+  return u<195102u?_hb_ucd_u16[6748+(((_hb_ucd_u8[13952+(((_hb_ucd_u8[13570+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0;
 }
 
 
 #else
 
 static const uint8_t
-_hb_ucd_u8[13370] =
+_hb_ucd_u8[13386] =
 {
     0,  1,  2,  3,  4,  5,  6,  7,  7,  8,  7,  7,  7,  7,  7,  7,
     7,  7,  7,  7,  9, 10,  7,  7,  7,  7,  7, 11, 12, 12, 12, 13,
@@ -4440,7 +4443,7 @@
     7, 24, 21, 21, 21, 25, 26, 27, 21, 28, 29, 30, 31, 32, 33, 34,
     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, 35, 21, 36,
-    7,  7,  7,  7, 35, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+    7,  7,  7,  7, 37, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
@@ -4462,7 +4465,7 @@
    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
-   37, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+   38, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
    12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
    12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
@@ -4503,8 +4506,9 @@
    34,192,193,111,111,111,111,111,130,194,195,111, 34,196,111,111,
    67, 67,197, 67, 67,111, 67,198, 67, 67, 67, 67, 67, 67, 67, 67,
    67, 67, 67, 67, 67, 67, 67,199,111,111,111,111,111,111,111,111,
-   34, 34, 34, 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111,
+   34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,111,111,111,
    34, 34, 34, 34, 34,111,111,111,111,111,111,111,111,111,111,111,
+   34, 34, 34, 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111,
   200,111,188,188,111,111,111,111,111,111,111,111,111,111,111,111,
     0,  0,  0,  0,  0,  0,  0,  0,  1,  2,  3,  2,  4,  5,  6,  2,
     7,  7,  7,  7,  7,  2,  8,  9, 10, 11, 11, 11, 11, 11, 11, 11,
@@ -4967,7 +4971,7 @@
    31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 65, 66, 67, 31, 31,
    31, 31, 68, 31, 31, 31, 31, 31, 31, 31, 31, 69, 70, 71, 17, 17,
    72, 73, 31, 74, 75, 76, 77, 78, 79, 31, 80, 81, 17, 82, 17, 17,
-   17, 17, 31, 31, 23, 23, 23, 23, 23, 23, 31, 31, 31, 31, 31, 31,
+   17, 17, 31, 31, 23, 23, 23, 23, 23, 23, 23, 83, 31, 31, 31, 31,
    23, 83, 31, 31, 23, 23, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
    31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
    31, 31, 31, 31, 84,  0,  0,  1,  0,  1,  2,  3,  0,  1,  2,  3,
@@ -5597,12 +5601,12 @@
 static inline uint_fast8_t
 _hb_ucd_gc (unsigned u)
 {
-  return u<1114112u?_hb_ucd_u8[5080+(((_hb_ucd_u8[1152+(((_hb_ucd_u16[((_hb_ucd_u8[544+(((_hb_ucd_u8[u>>1>>3>>3>>4])<<4)+((u>>1>>3>>3)&15u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2;
+  return u<1114112u?_hb_ucd_u8[5096+(((_hb_ucd_u8[1168+(((_hb_ucd_u16[((_hb_ucd_u8[544+(((_hb_ucd_u8[u>>1>>3>>3>>4])<<4)+((u>>1>>3>>3)&15u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2;
 }
 static inline uint_fast8_t
 _hb_ucd_ccc (unsigned u)
 {
-  return u<125259u?_hb_ucd_u8[7038+(((_hb_ucd_u8[6482+(((_hb_ucd_u8[6022+(((_hb_ucd_u8[5670+(((_hb_ucd_u8[5424+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0;
+  return u<125259u?_hb_ucd_u8[7054+(((_hb_ucd_u8[6498+(((_hb_ucd_u8[6038+(((_hb_ucd_u8[5686+(((_hb_ucd_u8[5440+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0;
 }
 static inline unsigned
 _hb_ucd_b4 (const uint8_t* a, unsigned i)
@@ -5612,17 +5616,17 @@
 static inline int_fast16_t
 _hb_ucd_bmg (unsigned u)
 {
-  return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[7930+(((_hb_ucd_u8[7698+(((_hb_ucd_u8[7602+(((_hb_ucd_b4(7538+_hb_ucd_u8,u>>1>>2>>3>>3))<<3)+((u>>1>>2>>3)&7u))])<<3)+((u>>1>>2)&7u))])<<2)+((u>>1)&3u))])<<1)+((u)&1u)]:0;
+  return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[7946+(((_hb_ucd_u8[7714+(((_hb_ucd_u8[7618+(((_hb_ucd_b4(7554+_hb_ucd_u8,u>>1>>2>>3>>3))<<3)+((u>>1>>2>>3)&7u))])<<3)+((u>>1>>2)&7u))])<<2)+((u>>1)&3u))])<<1)+((u)&1u)]:0;
 }
 static inline uint_fast8_t
 _hb_ucd_sc (unsigned u)
 {
-  return u<918016u?_hb_ucd_u8[11228+(((_hb_ucd_u8[10264+(((_hb_ucd_u8[9276+(((_hb_ucd_u8[8596+(((_hb_ucd_u8[8292+(((_hb_ucd_u8[8178+(u>>2>>2>>2>>3>>4)])<<4)+((u>>2>>2>>2>>3)&15u))])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:2;
+  return u<918016u?_hb_ucd_u8[11244+(((_hb_ucd_u8[10280+(((_hb_ucd_u8[9292+(((_hb_ucd_u8[8612+(((_hb_ucd_u8[8308+(((_hb_ucd_u8[8194+(u>>2>>2>>2>>3>>4)])<<4)+((u>>2>>2>>2>>3)&15u))])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:2;
 }
 static inline uint_fast16_t
 _hb_ucd_dm (unsigned u)
 {
-  return u<195102u?_hb_ucd_u16[1608+(((_hb_ucd_u8[12570+(((_hb_ucd_u8[12188+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0;
+  return u<195102u?_hb_ucd_u16[1608+(((_hb_ucd_u8[12586+(((_hb_ucd_u8[12204+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0;
 }
 
 #endif
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-unicode-emoji-table.hh b/src/java.desktop/share/native/libharfbuzz/hb-unicode-emoji-table.hh
index 13b1c4b..e607e8c 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-unicode-emoji-table.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-unicode-emoji-table.hh
@@ -7,13 +7,13 @@
  * on file with this header:
  *
  * # emoji-data.txt
- * # Date: 2022-08-02, 00:26:10 GMT
- * # © 2022 Unicode®, Inc.
+ * # Date: 2023-02-01, 02:22:54 GMT
+ * # © 2023 Unicode®, Inc.
  * # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries.
  * # For terms of use, see https://www.unicode.org/terms_of_use.html
  * #
  * # Emoji Data for UTS #51
- * # Used with Emoji Version 15.0 and subsequent minor revisions (if any)
+ * # Used with Emoji Version 15.1 and subsequent minor revisions (if any)
  * #
  * # For documentation and usage, see https://www.unicode.org/reports/tr51
  */
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-vector.hh b/src/java.desktop/share/native/libharfbuzz/hb-vector.hh
index c461f0e..001789a 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-vector.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb-vector.hh
@@ -54,7 +54,7 @@
   hb_vector_t (const Iterable &o) : hb_vector_t ()
   {
     auto iter = hb_iter (o);
-    if (iter.is_random_access_iterator)
+    if (iter.is_random_access_iterator || iter.has_fast_len)
       alloc (hb_len (iter), true);
     hb_copy (iter, *this);
   }
@@ -62,7 +62,19 @@
   {
     alloc (o.length, true);
     if (unlikely (in_error ())) return;
-    copy_vector (o);
+    copy_array (o.as_array ());
+  }
+  hb_vector_t (array_t o) : hb_vector_t ()
+  {
+    alloc (o.length, true);
+    if (unlikely (in_error ())) return;
+    copy_array (o);
+  }
+  hb_vector_t (c_array_t o) : hb_vector_t ()
+  {
+    alloc (o.length, true);
+    if (unlikely (in_error ())) return;
+    copy_array (o);
   }
   hb_vector_t (hb_vector_t &&o)
   {
@@ -74,7 +86,7 @@
   ~hb_vector_t () { fini (); }
 
   public:
-  int allocated = 0; /* == -1 means allocation failed. */
+  int allocated = 0; /* < 0 means allocation failed. */
   unsigned int length = 0;
   public:
   Type *arrayZ = nullptr;
@@ -90,19 +102,21 @@
 
   void fini ()
   {
-    shrink_vector (0);
-    hb_free (arrayZ);
+    /* We allow a hack to make the vector point to a foreign array
+     * by the user. In that case length/arrayZ are non-zero but
+     * allocated is zero. Don't free anything. */
+    if (allocated)
+    {
+      shrink_vector (0);
+      hb_free (arrayZ);
+    }
     init ();
   }
 
   void reset ()
   {
     if (unlikely (in_error ()))
-      /* Big Hack! We don't know the true allocated size before
-       * an allocation failure happened. But we know it was at
-       * least as big as length. Restore it to that and continue
-       * as if error did not happen. */
-      allocated = length;
+      reset_error ();
     resize (0);
   }
 
@@ -119,7 +133,7 @@
     alloc (o.length, true);
     if (unlikely (in_error ())) return *this;
 
-    copy_vector (o);
+    copy_array (o.as_array ());
 
     return *this;
   }
@@ -191,47 +205,38 @@
   Type *push ()
   {
     if (unlikely (!resize (length + 1)))
-      return &Crap (Type);
+      return std::addressof (Crap (Type));
     return std::addressof (arrayZ[length - 1]);
   }
-  template <typename T,
-            typename T2 = Type,
-            hb_enable_if (!std::is_copy_constructible<T2>::value &&
-                          std::is_copy_assignable<T>::value)>
-  Type *push (T&& v)
+  template <typename... Args> Type *push (Args&&... args)
   {
-    Type *p = push ();
-    if (p == &Crap (Type))
+    if (unlikely ((int) length >= allocated && !alloc (length + 1)))
       // If push failed to allocate then don't copy v, since this may cause
       // the created copy to leak memory since we won't have stored a
       // reference to it.
-      return p;
-    *p = std::forward<T> (v);
-    return p;
-  }
-  template <typename T,
-            typename T2 = Type,
-            hb_enable_if (std::is_copy_constructible<T2>::value)>
-  Type *push (T&& v)
-  {
-    if (unlikely (!alloc (length + 1)))
-      // If push failed to allocate then don't copy v, since this may cause
-      // the created copy to leak memory since we won't have stored a
-      // reference to it.
-      return &Crap (Type);
+      return std::addressof (Crap (Type));
 
     /* Emplace. */
-    length++;
-    Type *p = std::addressof (arrayZ[length - 1]);
-    return new (p) Type (std::forward<T> (v));
+    Type *p = std::addressof (arrayZ[length++]);
+    return new (p) Type (std::forward<Args> (args)...);
   }
 
   bool in_error () const { return allocated < 0; }
+  void set_error ()
+  {
+    assert (allocated >= 0);
+    allocated = -allocated - 1;
+  }
+  void reset_error ()
+  {
+    assert (allocated < 0);
+    allocated = -(allocated + 1);
+  }
 
   template <typename T = Type,
             hb_enable_if (hb_is_trivially_copy_assignable(T))>
   Type *
-  realloc_vector (unsigned new_allocated)
+  realloc_vector (unsigned new_allocated, hb_priority<0>)
   {
     if (!new_allocated)
     {
@@ -243,7 +248,7 @@
   template <typename T = Type,
             hb_enable_if (!hb_is_trivially_copy_assignable(T))>
   Type *
-  realloc_vector (unsigned new_allocated)
+  realloc_vector (unsigned new_allocated, hb_priority<0>)
   {
     if (!new_allocated)
     {
@@ -263,47 +268,66 @@
     }
     return new_array;
   }
+  /* Specialization for hb_vector_t<hb_{vector,array}_t<U>> to speed up. */
+  template <typename T = Type,
+            hb_enable_if (hb_is_same (T, hb_vector_t<typename T::item_t>) ||
+                          hb_is_same (T, hb_array_t <typename T::item_t>))>
+  Type *
+  realloc_vector (unsigned new_allocated, hb_priority<1>)
+  {
+    if (!new_allocated)
+    {
+      hb_free (arrayZ);
+      return nullptr;
+    }
+    return (Type *) hb_realloc (arrayZ, new_allocated * sizeof (Type));
+  }
 
   template <typename T = Type,
             hb_enable_if (hb_is_trivially_constructible(T))>
   void
-  grow_vector (unsigned size)
+  grow_vector (unsigned size, hb_priority<0>)
   {
-    memset (arrayZ + length, 0, (size - length) * sizeof (*arrayZ));
+    hb_memset (arrayZ + length, 0, (size - length) * sizeof (*arrayZ));
     length = size;
   }
   template <typename T = Type,
             hb_enable_if (!hb_is_trivially_constructible(T))>
   void
-  grow_vector (unsigned size)
+  grow_vector (unsigned size, hb_priority<0>)
   {
-    while (length < size)
-    {
-      length++;
-      new (std::addressof (arrayZ[length - 1])) Type ();
-    }
+    for (; length < size; length++)
+      new (std::addressof (arrayZ[length])) Type ();
+  }
+  /* Specialization for hb_vector_t<hb_{vector,array}_t<U>> to speed up. */
+  template <typename T = Type,
+            hb_enable_if (hb_is_same (T, hb_vector_t<typename T::item_t>) ||
+                          hb_is_same (T, hb_array_t <typename T::item_t>))>
+  void
+  grow_vector (unsigned size, hb_priority<1>)
+  {
+    hb_memset (arrayZ + length, 0, (size - length) * sizeof (*arrayZ));
+    length = size;
   }
 
   template <typename T = Type,
             hb_enable_if (hb_is_trivially_copyable (T))>
   void
-  copy_vector (const hb_vector_t &other)
+  copy_array (hb_array_t<const Type> other)
   {
     length = other.length;
-#ifndef HB_OPTIMIZE_SIZE
-    if (sizeof (T) >= sizeof (long long))
+    if (!HB_OPTIMIZE_SIZE_VAL && sizeof (T) >= sizeof (long long))
       /* This runs faster because of alignment. */
       for (unsigned i = 0; i < length; i++)
         arrayZ[i] = other.arrayZ[i];
     else
-#endif
        hb_memcpy ((void *) arrayZ, (const void *) other.arrayZ, length * item_size);
   }
   template <typename T = Type,
             hb_enable_if (!hb_is_trivially_copyable (T) &&
                            std::is_copy_constructible<T>::value)>
   void
-  copy_vector (const hb_vector_t &other)
+  copy_array (hb_array_t<const Type> other)
   {
     length = 0;
     while (length < other.length)
@@ -318,7 +342,7 @@
                           std::is_default_constructible<T>::value &&
                           std::is_copy_assignable<T>::value)>
   void
-  copy_vector (const hb_vector_t &other)
+  copy_array (hb_array_t<const Type> other)
   {
     length = 0;
     while (length < other.length)
@@ -332,11 +356,15 @@
   void
   shrink_vector (unsigned size)
   {
-    while ((unsigned) length > size)
+    assert (size <= length);
+    if (!std::is_trivially_destructible<Type>::value)
     {
-      arrayZ[(unsigned) length - 1].~Type ();
-      length--;
+      unsigned count = length - size;
+      Type *p = arrayZ + length - 1;
+      while (count--)
+        p--->~Type ();
     }
+    length = size;
   }
 
   void
@@ -383,18 +411,18 @@
 
     if (unlikely (overflows))
     {
-      allocated = -1;
+      set_error ();
       return false;
     }
 
-    Type *new_array = realloc_vector (new_allocated);
+    Type *new_array = realloc_vector (new_allocated, hb_prioritize);
 
     if (unlikely (new_allocated && !new_array))
     {
       if (new_allocated <= (unsigned) allocated)
         return true; // shrinking failed; it's okay; happens in our fuzzer
 
-      allocated = -1;
+      set_error ();
       return false;
     }
 
@@ -413,7 +441,7 @@
     if (size > length)
     {
       if (initialize)
-        grow_vector (size);
+        grow_vector (size, hb_prioritize);
     }
     else if (size < length)
     {
@@ -432,7 +460,7 @@
   Type pop ()
   {
     if (!length) return Null (Type);
-    Type v {std::move (arrayZ[length - 1])};
+    Type v (std::move (arrayZ[length - 1]));
     arrayZ[length - 1].~Type ();
     length--;
     return v;
diff --git a/src/java.desktop/share/native/libharfbuzz/hb-version.h b/src/java.desktop/share/native/libharfbuzz/hb-version.h
index 1dc7a6b..3627da3 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb-version.h
+++ b/src/java.desktop/share/native/libharfbuzz/hb-version.h
@@ -41,7 +41,7 @@
  *
  * The major component of the library version available at compile-time.
  */
-#define HB_VERSION_MAJOR 7
+#define HB_VERSION_MAJOR 8
 /**
  * HB_VERSION_MINOR:
  *
@@ -53,14 +53,14 @@
  *
  * The micro component of the library version available at compile-time.
  */
-#define HB_VERSION_MICRO 0
+#define HB_VERSION_MICRO 2
 
 /**
  * HB_VERSION_STRING:
  *
  * A string literal containing the library version available at compile-time.
  */
-#define HB_VERSION_STRING "7.2.0"
+#define HB_VERSION_STRING "8.2.2"
 
 /**
  * HB_VERSION_ATLEAST:
diff --git a/src/java.desktop/share/native/libharfbuzz/hb.hh b/src/java.desktop/share/native/libharfbuzz/hb.hh
index 4a6d99e..65d2dd5 100644
--- a/src/java.desktop/share/native/libharfbuzz/hb.hh
+++ b/src/java.desktop/share/native/libharfbuzz/hb.hh
@@ -64,6 +64,7 @@
 #pragma GCC diagnostic error   "-Wbitwise-instead-of-logical"
 #pragma GCC diagnostic error   "-Wcast-align"
 #pragma GCC diagnostic error   "-Wcast-function-type"
+#pragma GCC diagnostic error   "-Wconstant-conversion"
 #pragma GCC diagnostic error   "-Wcomma"
 #pragma GCC diagnostic error   "-Wdelete-non-virtual-dtor"
 #pragma GCC diagnostic error   "-Wembedded-directive"
@@ -255,8 +256,8 @@
 #endif
 
 #if defined(__OPTIMIZE__) && hb_has_builtin(__builtin_expect)
-#define likely(expr) (__builtin_expect (!!(expr), 1))
-#define unlikely(expr) (__builtin_expect (!!(expr), 0))
+#define likely(expr) __builtin_expect (bool(expr), 1)
+#define unlikely(expr) __builtin_expect (bool(expr), 0)
 #else
 #define likely(expr) (expr)
 #define unlikely(expr) (expr)
@@ -315,6 +316,14 @@
 #define __restrict
 #endif
 
+#ifndef HB_ALWAYS_INLINE
+#if defined(_MSC_VER)
+#define HB_ALWAYS_INLINE __forceinline
+#else
+#define HB_ALWAYS_INLINE __attribute__((always_inline)) inline
+#endif
+#endif
+
 /*
  * Borrowed from https://bugzilla.mozilla.org/show_bug.cgi?id=1215411
  * HB_FALLTHROUGH is an annotation to suppress compiler warnings about switch
diff --git a/src/java.desktop/share/native/libjavajpeg/imageioJPEG.c b/src/java.desktop/share/native/libjavajpeg/imageioJPEG.c
index 4ebd565..8a74a6d 100644
--- a/src/java.desktop/share/native/libjavajpeg/imageioJPEG.c
+++ b/src/java.desktop/share/native/libjavajpeg/imageioJPEG.c
@@ -1132,6 +1132,10 @@
         return;
     }
     num_bytes += sb->remaining_skip;
+    // Check for overflow if remaining_skip value is too large
+    if (num_bytes < 0) {
+        return;
+    }
     sb->remaining_skip = 0;
 
     /* First the easy case where we are skipping <= the current contents. */
diff --git a/src/java.desktop/share/native/libjavajpeg/jpegdecoder.c b/src/java.desktop/share/native/libjavajpeg/jpegdecoder.c
index 9181493..a01a6bb 100644
--- a/src/java.desktop/share/native/libjavajpeg/jpegdecoder.c
+++ b/src/java.desktop/share/native/libjavajpeg/jpegdecoder.c
@@ -406,6 +406,10 @@
         return;
     }
     num_bytes += src->remaining_skip;
+    // Check for overflow if remaining_skip value is too large
+    if (num_bytes < 0) {
+        return;
+    }
     src->remaining_skip = 0;
     ret = (int)src->pub.bytes_in_buffer; /* this conversion is safe, because capacity of the buffer is limited by jnit */
     if (ret >= num_bytes) {
diff --git a/src/java.desktop/share/native/libjsound/MidiOutDevice.c b/src/java.desktop/share/native/libjsound/MidiOutDevice.c
index 3738eba..29ef140 100644
--- a/src/java.desktop/share/native/libjsound/MidiOutDevice.c
+++ b/src/java.desktop/share/native/libjsound/MidiOutDevice.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -121,6 +121,7 @@
                                                         jbyteArray jData, jint size, jlong timeStamp) {
 #if USE_PLATFORM_MIDI_OUT == TRUE
     UBYTE* data;
+    UBYTE* msg;
 #endif
 
     TRACE0("Java_com_sun_media_sound_MidiOutDevice_nSendLongMessage.\n");
@@ -133,11 +134,12 @@
     }
     /* "continuation" sysex messages start with F7 (instead of F0), but
        are sent without the F7. */
+    msg = data;
     if (data[0] == 0xF7 && size > 1) {
-        data++;
+        msg++;
         size--;
     }
-    MIDI_OUT_SendLongMessage((MidiDeviceHandle*) (UINT_PTR) deviceHandle, data,
+    MIDI_OUT_SendLongMessage((MidiDeviceHandle*) (UINT_PTR) deviceHandle, msg,
                              (UINT32) size, (UINT32)timeStamp);
     // release the byte array
     (*e)->ReleaseByteArrayElements(e, jData, (jbyte*) data, JNI_ABORT);
diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/CHANGES b/src/java.desktop/share/native/libsplashscreen/libpng/CHANGES
index 468e111..2d8c585 100644
--- a/src/java.desktop/share/native/libsplashscreen/libpng/CHANGES
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/CHANGES
@@ -204,7 +204,7 @@
   Added simple sRGB support (Glenn R-P)
   Easier conditional compiling, e.g.,
     define PNG_READ/WRITE_NOT_FULLY_SUPPORTED;
-    all configurable options can be selected from command-line instead
+    all configurable options can be selected from command line instead
     of having to edit pngconf.h (Glenn R-P)
   Fixed memory leak in pngwrite.c (free info_ptr->text) (Glenn R-P)
   Added more conditions for png_do_background, to avoid changing
@@ -942,7 +942,7 @@
 Version 1.0.9beta1 [November 10, 2000]
   Fixed typo in scripts/makefile.hpux
   Updated makevms.com in scripts and contrib/* and contrib/* (Martin Zinser)
-  Fixed seqence-point bug in contrib/pngminus/png2pnm (Martin Zinser)
+  Fixed sequence-point bug in contrib/pngminus/png2pnm (Martin Zinser)
   Changed "cdrom.com" in documentation to "libpng.org"
   Revised pnggccrd.c to get it all working, and updated makefile.gcmmx (Greg).
   Changed type of "params" from voidp to png_voidp in png_read|write_png().
@@ -2295,7 +2295,7 @@
   Clarified usage of sig_bit versus sig_bit_p in example.c (Vincent Torri)
 
 Version 1.4.0beta59 [May 15, 2009]
-  Reformated sources in libpng style (3-space indentation, comment format)
+  Reformatted sources in libpng style (3-space indentation, comment format)
   Fixed typo in libpng docs (PNG_FILTER_AVE should be PNG_FILTER_AVG)
   Added sections about the git repository and our coding style to the
     documentation
@@ -2661,7 +2661,7 @@
 
 Version 1.4.1beta07 [February 6, 2010]
   Folded some long lines in the source files.
-  Added defineable PNG_USER_CHUNK_CACHE_MAX, PNG_USER_CHUNK_MALLOC_MAX,
+  Added definable PNG_USER_CHUNK_CACHE_MAX, PNG_USER_CHUNK_MALLOC_MAX,
     and a PNG_USER_LIMITS_SUPPORTED flag.
   Eliminated use of png_ptr->irowbytes and reused the slot in png_ptr as
     png_ptr->png_user_chunk_malloc_max.
@@ -3919,7 +3919,7 @@
     version checking to configure.ac
   Improved pngstest speed by not doing redundant tests and add const to
     the background parameter of png_image_finish_read. The --background
-    option is now done automagically only when required, so that commandline
+    option is now done automagically only when required, so that command-line
     option no longer exists.
   Cleaned up pngpriv.h to consistently declare all functions and data.
     Also eliminated PNG_CONST_DATA, which is apparently not needed but we
@@ -4052,7 +4052,7 @@
     (in fact this is harmless, but the PNG data produced may be sub-optimal).
 
 Version 1.6.0beta17 [March 10, 2012]
-  Fixed PNG_LIBPNG_BUILD_BASE_TYPE definition. 
+  Fixed PNG_LIBPNG_BUILD_BASE_TYPE definition.
   Reject all iCCP chunks after the first, even if the first one is invalid.
   Deflate/inflate was reworked to move common zlib calls into single
     functions [rw]util.c.  A new shared keyword check routine was also added
@@ -4962,7 +4962,7 @@
   Changed "if defined(__ARM_NEON__)" to
     "if (defined(__ARM_NEON__) || defined(__ARM_NEON))" (James Wu).
   Fixed clang no-warning builds: png_digit was defined but never used.
-    
+
 Version 1.6.13beta02 [July 21, 2014]
   Fixed an incorrect separator ("/" should be "\") in scripts/makefile.vcwin32
     (bug report from Wolfgang S. Kechel).  Bug was introduced in libpng-1.6.11.
@@ -5453,7 +5453,7 @@
 Version 1.6.21beta02 [December 14, 2015]
   Moved png_check_keyword() from pngwutil.c to pngset.c
   Removed LE/BE dependencies in pngvalid, to 'fix' the current problem
-    in the BigEndian tests by not testing it, making the BE code the same 
+    in the BigEndian tests by not testing it, making the BE code the same
     as the LE version.
   Fixes to pngvalid for various reduced build configurations (eliminate unused
     statics) and a fix for the case in rgb_to_gray when the digitize option
@@ -5517,7 +5517,7 @@
   Added a common-law trademark notice and export control information
     to the LICENSE file, png.h, and the man page.
   Restored "& 0xff" in png_save_uint_16() and png_save_uint_32() that
-    were accidentally removed from libpng-1.6.17. 
+    were accidentally removed from libpng-1.6.17.
   Changed PNG_INFO_cHNK and PNG_FREE_cHNK from 0xnnnn to 0xnnnnU in png.h
     (Robert C. Seacord).
   Removed dubious "#if INT_MAX" test from png.h that was added to
@@ -5927,7 +5927,7 @@
     (Bug report from the OSS-fuzz project).
 
 Version 1.6.32beta04 [August 2, 2017]
-  Replaced local eXIf_buf with info_ptr-eXIf_buf in png_handle_eXIf().
+  Replaced local eXIf_buf with info_ptr->eXIf_buf in png_handle_eXIf().
   Update libpng.3 and libpng-manual.txt about eXIf functions.
 
 Version 1.6.32beta05 [August 2, 2017]
@@ -5950,7 +5950,7 @@
   Require cmake-2.8.8 in CMakeLists.txt. Revised symlink creation,
     no longer using deprecated cmake LOCATION feature (Clifford Yapp).
   Fixed five-byte error in the calculation of IDAT maximum possible size.
-  
+
 Version 1.6.32beta10 [August 5, 2017]
   Moved chunk-length check into a png_check_chunk_length() private
     function (Suggested by Max Stepin).
@@ -6121,6 +6121,14 @@
     removed the obsolete makefile.cegcc.
   Cleaned up the code and updated the internal documentation.
 
+Version 1.6.40 [June 21, 2023]
+  Fixed the eXIf chunk multiplicity checks.
+  Fixed a memory leak in pCAL processing.
+  Corrected the validity report about tRNS inside png_get_valid().
+  Fixed various build issues on *BSD, Mac and Windows.
+  Updated the configurations and the scripts for continuous integration.
+  Cleaned up the code, the build scripts, and the documentation.
+
 Send comments/corrections/commendations to png-mng-implement at lists.sf.net.
 Subscription is required; visit
 https://lists.sourceforge.net/lists/listinfo/png-mng-implement
diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/LICENSE b/src/java.desktop/share/native/libsplashscreen/libpng/LICENSE
index 7ac9016..086d1c2 100644
--- a/src/java.desktop/share/native/libsplashscreen/libpng/LICENSE
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/LICENSE
@@ -4,8 +4,8 @@
 PNG Reference Library License version 2
 ---------------------------------------
 
- * Copyright (c) 1995-2022 The PNG Reference Library Authors.
- * Copyright (c) 2018-2022 Cosmin Truta.
+ * Copyright (c) 1995-2023 The PNG Reference Library Authors.
+ * Copyright (c) 2018-2023 Cosmin Truta.
  * Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson.
  * Copyright (c) 1996-1997 Andreas Dilger.
  * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@@ -131,4 +131,4 @@
 without fee, and encourage the use of this source code as a component
 to supporting the PNG file format in commercial products.  If you use
 this source code in a product, acknowledgment is not required but would
-be appreciated.
\ No newline at end of file
+be appreciated.
diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/README b/src/java.desktop/share/native/libsplashscreen/libpng/README
index 097a3c2..dedd2c1 100644
--- a/src/java.desktop/share/native/libsplashscreen/libpng/README
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/README
@@ -1,57 +1,88 @@
-README for libpng version 1.6.39
+README for libpng version 1.6.40
 ================================
 
-See the note about version numbers near the top of png.h.
-See INSTALL for instructions on how to install libpng.
+See the note about version numbers near the top of `png.h`.
+See `INSTALL` for instructions on how to install libpng.
 
-Libpng comes in several distribution formats.  Get libpng-*.tar.gz or
-libpng-*.tar.xz if you want UNIX-style line endings in the text files,
-or lpng*.7z or lpng*.zip if you want DOS-style line endings.
+Libpng comes in several distribution formats.  Get `libpng-*.tar.gz`
+or `libpng-*.tar.xz` if you want UNIX-style line endings in the text
+files, or `lpng*.7z` or `lpng*.zip` if you want DOS-style line endings.
 
-Version 0.89 was the first official release of libpng.  Don't let the
-fact that it's the first release fool you.  The libpng library has been
-in extensive use and testing since mid-1995.  By late 1997 it had
-finally gotten to the stage where there hadn't been significant
-changes to the API in some time, and people have a bad feeling about
-libraries with versions < 1.0.  Version 1.0.0 was released in
-March 1998.
+For a detailed description on using libpng, read `libpng-manual.txt`.
+For examples of libpng in a program, see `example.c` and `pngtest.c`.
+For usage information and restrictions (what little they are) on libpng,
+see `png.h`.  For a description on using zlib (the compression library
+used by libpng) and zlib's restrictions, see `zlib.h`.
 
-****
-Note that some of the changes to the png_info structure render this
+You should use zlib 1.0.4 or later to run this, but it _may_ work with
+versions as old as zlib 0.95.  Even so, there are bugs in older zlib
+versions which can cause the output of invalid compression streams for
+some images.
+
+You should also note that zlib is a compression library that is useful
+for more things than just PNG files.  You can use zlib as a drop-in
+replacement for `fread()` and `fwrite()`, if you are so inclined.
+
+zlib should be available at the same place that libpng is, or at
+https://zlib.net .
+
+You may also want a copy of the PNG specification.  It is available
+as an RFC, a W3C Recommendation, and an ISO/IEC Standard.  You can find
+these at http://www.libpng.org/pub/png/pngdocs.html .
+
+This code is currently being archived at https://libpng.sourceforge.io
+in the download area, and at http://libpng.download/src .
+
+This release, based in a large way on Glenn's, Guy's and Andreas'
+earlier work, was created and will be supported by myself and the PNG
+development group.
+
+Send comments, corrections and commendations to `png-mng-implement`
+at `lists.sourceforge.net`.  (Subscription is required; visit
+https://lists.sourceforge.net/lists/listinfo/png-mng-implement
+to subscribe.)
+
+Send general questions about the PNG specification to `png-mng-misc`
+at `lists.sourceforge.net`.  (Subscription is required; visit
+https://lists.sourceforge.net/lists/listinfo/png-mng-misc
+to subscribe.)
+
+Historical notes
+----------------
+
+The libpng library has been in extensive use and testing since mid-1995.
+Version 0.89, published a year later, was the first official release.
+By late 1997, it had finally gotten to the stage where there hadn't
+been significant changes to the API in some time, and people have a bad
+feeling about libraries with versions below 1.0.  Version 1.0.0 was
+released in March 1998.
+
+Note that some of the changes to the `png_info` structure render this
 version of the library binary incompatible with libpng-0.89 or
 earlier versions if you are using a shared library.  The type of the
-"filler" parameter for png_set_filler() has changed from png_byte to
-png_uint_32, which will affect shared-library applications that use
-this function.
+`filler` parameter for `png_set_filler()` has changed from `png_byte`
+to `png_uint_32`, which will affect shared-library applications that
+use this function.
 
-To avoid problems with changes to the internals of the png info_struct,
+To avoid problems with changes to the internals of the `info_struct`,
 new APIs have been made available in 0.95 to avoid direct application
-access to info_ptr.  These functions are the png_set_<chunk> and
-png_get_<chunk> functions.  These functions should be used when
-accessing/storing the info_struct data, rather than manipulating it
+access to `info_ptr`.  These functions are the `png_set_<chunk>` and
+`png_get_<chunk>` functions.  These functions should be used when
+accessing/storing the `info_struct` data, rather than manipulating it
 directly, to avoid such problems in the future.
 
 It is important to note that the APIs did not make current programs
 that access the info struct directly incompatible with the new
 library, through libpng-1.2.x.  In libpng-1.4.x, which was meant to
-be a transitional release, members of the png_struct and the
-info_struct can still be accessed, but the compiler will issue a
+be a transitional release, members of the `png_struct` and the
+`info_struct` can still be accessed, but the compiler will issue a
 warning about deprecated usage.  Since libpng-1.5.0, direct access
 to these structs is not allowed, and the definitions of the structs
-reside in private pngstruct.h and pnginfo.h header files that are not
-accessible to applications.  It is strongly suggested that new
-programs use the new APIs (as shown in example.c and pngtest.c), and
-older programs be converted to the new format, to facilitate upgrades
-in the future.
-****
-
-Additions since 0.90 include the ability to compile libpng as a
-Windows DLL, and new APIs for accessing data in the info struct.
-Experimental functions include the ability to set weighting and cost
-factors for row filter selection, direct reads of integers from buffers
-on big-endian processors that support misaligned data access, faster
-methods of doing alpha composition, and more accurate 16->8 bit color
-conversion.
+reside in private `pngstruct.h` and `pnginfo.h` header files that are
+not accessible to applications.  It is strongly suggested that new
+programs use the new APIs (as shown in `example.c` and `pngtest.c`),
+and older programs be converted to the new format, to facilitate
+upgrades in the future.
 
 The additions since 0.89 include the ability to read from a PNG stream
 which has had some (or all) of the signature bytes read by the calling
@@ -61,50 +92,17 @@
 to set different actions based on whether the CRC error occurred in a
 critical or an ancillary chunk.
 
-For a detailed description on using libpng, read libpng-manual.txt.
-For examples of libpng in a program, see example.c and pngtest.c.  For
-usage information and restrictions (what little they are) on libpng,
-see png.h.  For a description on using zlib (the compression library
-used by libpng) and zlib's restrictions, see zlib.h
+The additions since 0.90 include the ability to compile libpng as a
+Windows DLL, and new APIs for accessing data in the `info_struct`.
+Experimental functions included the ability to set weighting and cost
+factors for row filter selection, direct reads of integers from buffers
+on big-endian processors that support misaligned data access, faster
+methods of doing alpha composition, and more accurate 16-to-8 bit color
+conversion.  Some of these experimental functions, such as the weighted
+filter heuristics, have since been removed.
 
-I have included a general makefile, as well as several machine and
-compiler specific ones, but you may have to modify one for your own
-needs.
-
-You should use zlib 1.0.4 or later to run this, but it MAY work with
-versions as old as zlib 0.95.  Even so, there are bugs in older zlib
-versions which can cause the output of invalid compression streams for
-some images.
-
-You should also note that zlib is a compression library that is useful
-for more things than just PNG files.  You can use zlib as a drop-in
-replacement for fread() and fwrite(), if you are so inclined.
-
-zlib should be available at the same place that libpng is, or at
-https://zlib.net.
-
-You may also want a copy of the PNG specification.  It is available
-as an RFC, a W3C Recommendation, and an ISO/IEC Standard.  You can find
-these at http://www.libpng.org/pub/png/pngdocs.html .
-
-This code is currently being archived at libpng.sourceforge.io in the
-[DOWNLOAD] area, and at http://libpng.download/src .
-
-This release, based in a large way on Glenn's, Guy's and Andreas'
-earlier work, was created and will be supported by myself and the PNG
-development group.
-
-Send comments/corrections/commendations to png-mng-implement at
-lists.sourceforge.net (subscription required; visit
-https://lists.sourceforge.net/lists/listinfo/png-mng-implement
-to subscribe).
-
-Send general questions about the PNG specification to png-mng-misc
-at lists.sourceforge.net (subscription required; visit
-https://lists.sourceforge.net/lists/listinfo/png-mng-misc to
-subscribe).
-
-Files in this distribution:
+Files included in this distribution
+-----------------------------------
 
     ANNOUNCE      =>  Announcement of this version, with recent changes
     AUTHORS       =>  List of contributing authors
@@ -153,7 +151,7 @@
         arm-neon/     =>  Optimized code for the ARM-NEON platform
         mips-msa/     =>  Optimized code for the MIPS-MSA platform
         powerpc-vsx/  =>  Optimized code for the POWERPC-VSX platform
-        examples/     =>  Example programs
+        examples/     =>  Examples of libpng usage
         gregbook/     =>  Source code for PNG reading and writing, from
                           "PNG: The Definitive Guide" by Greg Roelofs,
                           O'Reilly, 1999
diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/png.c b/src/java.desktop/share/native/libsplashscreen/libpng/png.c
index 30181b6..91a92e5 100644
--- a/src/java.desktop/share/native/libsplashscreen/libpng/png.c
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/png.c
@@ -29,7 +29,7 @@
  * However, the following notice accompanied the original version of this
  * file and, per its terms, should not be removed:
  *
- * Copyright (c) 2018-2022 Cosmin Truta
+ * Copyright (c) 2018-2023 Cosmin Truta
  * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
  * Copyright (c) 1996-1997 Andreas Dilger
  * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@@ -42,7 +42,7 @@
 #include "pngpriv.h"
 
 /* Generate a compiler error if there is an old png.h in the search path. */
-typedef png_libpng_version_1_6_39 Your_png_h_is_not_version_1_6_39;
+typedef png_libpng_version_1_6_40 Your_png_h_is_not_version_1_6_40;
 
 #ifdef __GNUC__
 /* The version tests may need to be added to, but the problem warning has
@@ -843,8 +843,8 @@
    return PNG_STRING_COPYRIGHT
 #else
    return PNG_STRING_NEWLINE \
-      "libpng version 1.6.39" PNG_STRING_NEWLINE \
-      "Copyright (c) 2018-2022 Cosmin Truta" PNG_STRING_NEWLINE \
+      "libpng version 1.6.40" PNG_STRING_NEWLINE \
+      "Copyright (c) 2018-2023 Cosmin Truta" PNG_STRING_NEWLINE \
       "Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson" \
       PNG_STRING_NEWLINE \
       "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/png.h b/src/java.desktop/share/native/libsplashscreen/libpng/png.h
index 3d9fa03..578841c 100644
--- a/src/java.desktop/share/native/libsplashscreen/libpng/png.h
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/png.h
@@ -29,9 +29,9 @@
  * However, the following notice accompanied the original version of this
  * file and, per its terms, should not be removed:
  *
- * libpng version 1.6.39 - November 20, 2022
+ * libpng version 1.6.40
  *
- * Copyright (c) 2018-2022 Cosmin Truta
+ * Copyright (c) 2018-2023 Cosmin Truta
  * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
  * Copyright (c) 1996-1997 Andreas Dilger
  * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@@ -43,7 +43,7 @@
  *   libpng versions 0.89, June 1996, through 0.96, May 1997: Andreas Dilger
  *   libpng versions 0.97, January 1998, through 1.6.35, July 2018:
  *     Glenn Randers-Pehrson
- *   libpng versions 1.6.36, December 2018, through 1.6.39, November 2022:
+ *   libpng versions 1.6.36, December 2018, through 1.6.40, June 2023:
  *     Cosmin Truta
  *   See also "Contributing Authors", below.
  */
@@ -55,8 +55,8 @@
  * PNG Reference Library License version 2
  * ---------------------------------------
  *
- *  * Copyright (c) 1995-2022 The PNG Reference Library Authors.
- *  * Copyright (c) 2018-2022 Cosmin Truta.
+ *  * Copyright (c) 1995-2023 The PNG Reference Library Authors.
+ *  * Copyright (c) 2018-2023 Cosmin Truta.
  *  * Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson.
  *  * Copyright (c) 1996-1997 Andreas Dilger.
  *  * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@@ -267,7 +267,7 @@
  *    ...
  *    1.5.30                  15    10530  15.so.15.30[.0]
  *    ...
- *    1.6.39                  16    10639  16.so.16.39[.0]
+ *    1.6.40                  16    10640  16.so.16.40[.0]
  *
  *    Henceforth the source version will match the shared-library major and
  *    minor numbers; the shared-library major version number will be used for
@@ -306,8 +306,8 @@
  */
 
 /* Version information for png.h - this should match the version in png.c */
-#define PNG_LIBPNG_VER_STRING "1.6.39"
-#define PNG_HEADER_VERSION_STRING " libpng version 1.6.39 - November 20, 2022\n"
+#define PNG_LIBPNG_VER_STRING "1.6.40"
+#define PNG_HEADER_VERSION_STRING " libpng version 1.6.40 - June 21, 2023\n"
 
 #define PNG_LIBPNG_VER_SONUM   16
 #define PNG_LIBPNG_VER_DLLNUM  16
@@ -315,7 +315,7 @@
 /* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */
 #define PNG_LIBPNG_VER_MAJOR   1
 #define PNG_LIBPNG_VER_MINOR   6
-#define PNG_LIBPNG_VER_RELEASE 39
+#define PNG_LIBPNG_VER_RELEASE 40
 
 /* This should be zero for a public release, or non-zero for a
  * development version.  [Deprecated]
@@ -346,7 +346,7 @@
  * From version 1.0.1 it is:
  * XXYYZZ, where XX=major, YY=minor, ZZ=release
  */
-#define PNG_LIBPNG_VER 10639 /* 1.6.39 */
+#define PNG_LIBPNG_VER 10640 /* 1.6.40 */
 
 /* Library configuration: these options cannot be changed after
  * the library has been built.
@@ -456,7 +456,7 @@
 /* This triggers a compiler error in png.c, if png.c and png.h
  * do not agree upon the version number.
  */
-typedef char* png_libpng_version_1_6_39;
+typedef char* png_libpng_version_1_6_40;
 
 /* Basic control structions.  Read libpng-manual.txt or libpng.3 for more info.
  *
diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/pngconf.h b/src/java.desktop/share/native/libsplashscreen/libpng/pngconf.h
index d11e9ac..41cbc91 100644
--- a/src/java.desktop/share/native/libsplashscreen/libpng/pngconf.h
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/pngconf.h
@@ -29,7 +29,7 @@
  * However, the following notice accompanied the original version of this
  * file and, per its terms, should not be removed:
  *
- * libpng version 1.6.39
+ * libpng version 1.6.40
  *
  * Copyright (c) 2018-2022 Cosmin Truta
  * Copyright (c) 1998-2002,2004,2006-2016,2018 Glenn Randers-Pehrson
diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/pngget.c b/src/java.desktop/share/native/libsplashscreen/libpng/pngget.c
index 454d4e8..6e510b2 100644
--- a/src/java.desktop/share/native/libsplashscreen/libpng/pngget.c
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/pngget.c
@@ -29,7 +29,7 @@
  * However, the following notice accompanied the original version of this
  * file and, per its terms, should not be removed:
  *
- * Copyright (c) 2018 Cosmin Truta
+ * Copyright (c) 2018-2023 Cosmin Truta
  * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
  * Copyright (c) 1996-1997 Andreas Dilger
  * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@@ -49,7 +49,18 @@
     png_uint_32 flag)
 {
    if (png_ptr != NULL && info_ptr != NULL)
+   {
+#ifdef PNG_READ_tRNS_SUPPORTED
+      /* png_handle_PLTE() may have canceled a valid tRNS chunk but left the
+       * 'valid' flag for the detection of duplicate chunks. Do not report a
+       * valid tRNS chunk in this case.
+       */
+      if (flag == PNG_INFO_tRNS && png_ptr->num_trans == 0)
+         return(0);
+#endif
+
       return(info_ptr->valid & flag);
+   }
 
    return(0);
 }
diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/pnglibconf.h b/src/java.desktop/share/native/libsplashscreen/libpng/pnglibconf.h
index 18b435d..e98d49c 100644
--- a/src/java.desktop/share/native/libsplashscreen/libpng/pnglibconf.h
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/pnglibconf.h
@@ -31,9 +31,9 @@
  * However, the following notice accompanied the original version of this
  * file and, per its terms, should not be removed:
  */
-/* libpng version 1.6.39 */
+/* libpng version 1.6.40 */
 
-/* Copyright (c) 2018-2022 Cosmin Truta */
+/* Copyright (c) 2018-2023 Cosmin Truta */
 /* Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson */
 
 /* This code is released under the libpng license. */
diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/pngpriv.h b/src/java.desktop/share/native/libsplashscreen/libpng/pngpriv.h
index ec47329..914d0b9 100644
--- a/src/java.desktop/share/native/libsplashscreen/libpng/pngpriv.h
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/pngpriv.h
@@ -29,7 +29,7 @@
  * However, the following notice accompanied the original version of this
  * file and, per its terms, should not be removed:
  *
- * Copyright (c) 2018-2022 Cosmin Truta
+ * Copyright (c) 2018-2023 Cosmin Truta
  * Copyright (c) 1998-2002,2004,2006-2018 Glenn Randers-Pehrson
  * Copyright (c) 1996-1997 Andreas Dilger
  * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@@ -654,7 +654,7 @@
 #define PNG_BACKGROUND_IS_GRAY     0x800U
 #define PNG_HAVE_PNG_SIGNATURE    0x1000U
 #define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000U /* Have another chunk after IDAT */
-                   /*             0x4000U (unused) */
+#define PNG_WROTE_eXIf            0x4000U
 #define PNG_IS_READ_STRUCT        0x8000U /* Else is a write struct */
 
 /* Flags for the transformations the PNG library does on the image data */
@@ -1938,7 +1938,7 @@
  */
 #define PNG_FP_INVALID  512  /* Available for callers as a distinct value */
 
-/* Result codes for the parser (boolean - true meants ok, false means
+/* Result codes for the parser (boolean - true means ok, false means
  * not ok yet.)
  */
 #define PNG_FP_MAYBE      0  /* The number may be valid in the future */
diff --git a/src/java.desktop/share/native/libsplashscreen/libpng/pngset.c b/src/java.desktop/share/native/libsplashscreen/libpng/pngset.c
index ea7deca..62612a0 100644
--- a/src/java.desktop/share/native/libsplashscreen/libpng/pngset.c
+++ b/src/java.desktop/share/native/libsplashscreen/libpng/pngset.c
@@ -29,7 +29,7 @@
  * However, the following notice accompanied the original version of this
  * file and, per its terms, should not be removed:
  *
- * Copyright (c) 2018-2022 Cosmin Truta
+ * Copyright (c) 2018-2023 Cosmin Truta
  * Copyright (c) 1998-2018 Glenn Randers-Pehrson
  * Copyright (c) 1996-1997 Andreas Dilger
  * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
@@ -165,46 +165,40 @@
 #ifdef PNG_eXIf_SUPPORTED
 void PNGAPI
 png_set_eXIf(png_const_structrp png_ptr, png_inforp info_ptr,
-    png_bytep eXIf_buf)
+    png_bytep exif)
 {
   png_warning(png_ptr, "png_set_eXIf does not work; use png_set_eXIf_1");
   PNG_UNUSED(info_ptr)
-  PNG_UNUSED(eXIf_buf)
+  PNG_UNUSED(exif)
 }
 
 void PNGAPI
 png_set_eXIf_1(png_const_structrp png_ptr, png_inforp info_ptr,
-    png_uint_32 num_exif, png_bytep eXIf_buf)
+    png_uint_32 num_exif, png_bytep exif)
 {
-   int i;
+   png_bytep new_exif;
 
    png_debug1(1, "in %s storage function", "eXIf");
 
-   if (png_ptr == NULL || info_ptr == NULL)
+   if (png_ptr == NULL || info_ptr == NULL ||
+       (png_ptr->mode & PNG_WROTE_eXIf) != 0)
       return;
 
-   if (info_ptr->exif)
-   {
-      png_free(png_ptr, info_ptr->exif);
-      info_ptr->exif = NULL;
-   }
+   new_exif = png_voidcast(png_bytep, png_malloc_warn(png_ptr, num_exif));
 
-   info_ptr->num_exif = num_exif;
-
-   info_ptr->exif = png_voidcast(png_bytep, png_malloc_warn(png_ptr,
-       info_ptr->num_exif));
-
-   if (info_ptr->exif == NULL)
+   if (new_exif == NULL)
    {
       png_warning(png_ptr, "Insufficient memory for eXIf chunk data");
       return;
    }
 
+   memcpy(new_exif, exif, (size_t)num_exif);
+
+   png_free_data(png_ptr, info_ptr, PNG_FREE_EXIF, 0);
+
+   info_ptr->num_exif = num_exif;
+   info_ptr->exif = new_exif;
    info_ptr->free_me |= PNG_FREE_EXIF;
-
-   for (i = 0; i < (int) info_ptr->num_exif; i++)
-      info_ptr->exif[i] = eXIf_buf[i];
-
    info_ptr->valid |= PNG_INFO_eXIf;
 }
 #endif /* eXIf */
@@ -265,15 +259,13 @@
    if (info_ptr->hist == NULL)
    {
       png_warning(png_ptr, "Insufficient memory for hIST chunk data");
-
       return;
    }
 
-   info_ptr->free_me |= PNG_FREE_HIST;
-
    for (i = 0; i < info_ptr->num_palette; i++)
       info_ptr->hist[i] = hist[i];
 
+   info_ptr->free_me |= PNG_FREE_HIST;
    info_ptr->valid |= PNG_INFO_hIST;
 }
 #endif
@@ -395,6 +387,8 @@
 
    memcpy(info_ptr->pcal_purpose, purpose, length);
 
+   info_ptr->free_me |= PNG_FREE_PCAL;
+
    png_debug(3, "storing X0, X1, type, and nparams in info");
    info_ptr->pcal_X0 = X0;
    info_ptr->pcal_X1 = X1;
@@ -411,7 +405,6 @@
    if (info_ptr->pcal_units == NULL)
    {
       png_warning(png_ptr, "Insufficient memory for pCAL units");
-
       return;
    }
 
@@ -423,7 +416,6 @@
    if (info_ptr->pcal_params == NULL)
    {
       png_warning(png_ptr, "Insufficient memory for pCAL params");
-
       return;
    }
 
@@ -441,7 +433,6 @@
       if (info_ptr->pcal_params[i] == NULL)
       {
          png_warning(png_ptr, "Insufficient memory for pCAL parameter");
-
          return;
       }
 
@@ -449,7 +440,6 @@
    }
 
    info_ptr->valid |= PNG_INFO_pCAL;
-   info_ptr->free_me |= PNG_FREE_PCAL;
 }
 #endif
 
@@ -506,18 +496,17 @@
 
    if (info_ptr->scal_s_height == NULL)
    {
-      png_free (png_ptr, info_ptr->scal_s_width);
+      png_free(png_ptr, info_ptr->scal_s_width);
       info_ptr->scal_s_width = NULL;
 
       png_warning(png_ptr, "Memory allocation failed while processing sCAL");
-
       return;
    }
 
    memcpy(info_ptr->scal_s_height, sheight, lengthh);
 
-   info_ptr->valid |= PNG_INFO_sCAL;
    info_ptr->free_me |= PNG_FREE_SCAL;
+   info_ptr->valid |= PNG_INFO_sCAL;
 }
 
 #  ifdef PNG_FLOATING_POINT_SUPPORTED
@@ -653,11 +642,10 @@
    if (num_palette > 0)
       memcpy(png_ptr->palette, palette, (unsigned int)num_palette *
           (sizeof (png_color)));
+
    info_ptr->palette = png_ptr->palette;
    info_ptr->num_palette = png_ptr->num_palette = (png_uint_16)num_palette;
-
    info_ptr->free_me |= PNG_FREE_PLTE;
-
    info_ptr->valid |= PNG_INFO_PLTE;
 }
 
@@ -1048,8 +1036,8 @@
               png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH));
           memcpy(info_ptr->trans_alpha, trans_alpha, (size_t)num_trans);
 
-          info_ptr->valid |= PNG_INFO_tRNS;
           info_ptr->free_me |= PNG_FREE_TRNS;
+          info_ptr->valid |= PNG_INFO_tRNS;
        }
        png_ptr->trans_alpha = info_ptr->trans_alpha;
    }
@@ -1082,8 +1070,8 @@
 
    if (num_trans != 0)
    {
-      info_ptr->valid |= PNG_INFO_tRNS;
       info_ptr->free_me |= PNG_FREE_TRNS;
+      info_ptr->valid |= PNG_INFO_tRNS;
    }
 }
 #endif
@@ -1117,11 +1105,11 @@
    {
       /* Out of memory or too many chunks */
       png_chunk_report(png_ptr, "too many sPLT chunks", PNG_CHUNK_WRITE_ERROR);
-
       return;
    }
 
    png_free(png_ptr, info_ptr->splt_palettes);
+
    info_ptr->splt_palettes = np;
    info_ptr->free_me |= PNG_FREE_SPLT;
 
@@ -1275,11 +1263,11 @@
    {
       png_chunk_report(png_ptr, "too many unknown chunks",
           PNG_CHUNK_WRITE_ERROR);
-
       return;
    }
 
    png_free(png_ptr, info_ptr->unknown_chunks);
+
    info_ptr->unknown_chunks = np; /* safe because it is initialized */
    info_ptr->free_me |= PNG_FREE_UNKN;
 
diff --git a/src/java.desktop/unix/classes/sun/awt/UNIXToolkit.java b/src/java.desktop/unix/classes/sun/awt/UNIXToolkit.java
index 31764c7..d785823 100644
--- a/src/java.desktop/unix/classes/sun/awt/UNIXToolkit.java
+++ b/src/java.desktop/unix/classes/sun/awt/UNIXToolkit.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,8 +26,12 @@
 
 import java.awt.RenderingHints;
 import static java.awt.RenderingHints.*;
+import static java.util.concurrent.TimeUnit.SECONDS;
 import java.awt.color.ColorSpace;
 import java.awt.image.*;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 
@@ -214,6 +218,72 @@
         return img;
     }
 
+    private static volatile Boolean shouldDisableSystemTray = null;
+
+    /**
+     * There is an issue displaying the xembed icons in appIndicators
+     * area with certain Gnome Shell versions.
+     * To avoid any loss of quality of service, we are disabling
+     * SystemTray support in such cases.
+     *
+     * @return true if system tray should be disabled
+     */
+    public boolean shouldDisableSystemTray() {
+        Boolean result = shouldDisableSystemTray;
+        if (result == null) {
+            synchronized (GTK_LOCK) {
+                result = shouldDisableSystemTray;
+                if (result == null) {
+                    if ("gnome".equals(getDesktop())) {
+                        @SuppressWarnings("removal")
+                        Integer gnomeShellMajorVersion =
+                                AccessController
+                                        .doPrivileged((PrivilegedAction<Integer>)
+                                                this::getGnomeShellMajorVersion);
+
+                        if (gnomeShellMajorVersion == null
+                                || gnomeShellMajorVersion < 45) {
+
+                            return shouldDisableSystemTray = true;
+                        }
+                    }
+                    shouldDisableSystemTray = result = false;
+                }
+            }
+        }
+        return result;
+    }
+
+    private Integer getGnomeShellMajorVersion() {
+        try {
+            Process process =
+                new ProcessBuilder("/usr/bin/gnome-shell", "--version")
+                        .start();
+            try (InputStreamReader isr = new InputStreamReader(process.getInputStream());
+                 BufferedReader reader = new BufferedReader(isr)) {
+
+                if (process.waitFor(2, SECONDS) &&  process.exitValue() == 0) {
+                    String line = reader.readLine();
+                    if (line != null) {
+                        String[] versionComponents = line
+                                .replaceAll("[^\\d.]", "")
+                                .split("\\.");
+
+                        if (versionComponents.length >= 1) {
+                            return Integer.parseInt(versionComponents[0]);
+                        }
+                    }
+                }
+            }
+        } catch (IOException
+                 | InterruptedException
+                 | IllegalThreadStateException
+                 | NumberFormatException ignored) {
+        }
+
+        return null;
+    }
+
     /**
      * Returns a BufferedImage which contains the Gtk icon requested.  If no
      * such icon exists or an error occurs loading the icon the result will
diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XBaseWindow.java b/src/java.desktop/unix/classes/sun/awt/X11/XBaseWindow.java
index a74d904..7a37220 100644
--- a/src/java.desktop/unix/classes/sun/awt/X11/XBaseWindow.java
+++ b/src/java.desktop/unix/classes/sun/awt/X11/XBaseWindow.java
@@ -209,6 +209,10 @@
         }
     }
 
+    protected boolean isInitialising() {
+        return initialising == InitialiseState.INITIALISING;
+    }
+
     public boolean checkInitialised() {
         awtLock();
         try {
diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XFramePeer.java b/src/java.desktop/unix/classes/sun/awt/X11/XFramePeer.java
index 0149492..69b5842 100644
--- a/src/java.desktop/unix/classes/sun/awt/X11/XFramePeer.java
+++ b/src/java.desktop/unix/classes/sun/awt/X11/XFramePeer.java
@@ -330,6 +330,15 @@
         XWM.getWM().setExtendedState(this, newState);
     }
 
+    @Override
+    public void toFront() {
+        if ((state & Frame.ICONIFIED) != 0) {
+            changeState(state & ~Frame.ICONIFIED);
+        }
+
+        super.toFront();
+    }
+
     public void handlePropertyNotify(XEvent xev) {
         super.handlePropertyNotify(xev);
         XPropertyEvent ev = xev.get_xproperty();
diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XInputMethod.java b/src/java.desktop/unix/classes/sun/awt/X11/XInputMethod.java
index a7968bc..3c8f8ee 100644
--- a/src/java.desktop/unix/classes/sun/awt/X11/XInputMethod.java
+++ b/src/java.desktop/unix/classes/sun/awt/X11/XInputMethod.java
@@ -33,12 +33,15 @@
 import java.awt.peer.ComponentPeer;
 import java.lang.ref.WeakReference;
 import java.util.Arrays;
+import java.util.ArrayDeque;
 import java.util.Iterator;
 import java.util.Objects;
+import java.util.Queue;
 import java.util.function.Supplier;
 import java.util.stream.Stream;
 
 import sun.awt.AWTAccessor;
+import sun.awt.SunToolkit;
 import sun.awt.X11GraphicsDevice;
 import sun.awt.X11GraphicsEnvironment;
 import sun.awt.X11InputMethod;
@@ -246,6 +249,155 @@
     }
 
 
+    // JBR-6456: Sudden keyboard death on Linux using iBus.
+    // xicDestroyMustBeDelayed, XIC_DELAYED_TO_BE_DESTROYED_CAPACITY, xicDelayedToBeDestroyed can only be accessed
+    //   under the AWT lock
+    // See the #disposeXIC method for the purpose of these fields
+    private static boolean xicDestroyMustBeDelayed = false;
+    private static final int XIC_DELAYED_TO_BE_DESTROYED_CAPACITY = 16;
+    private static final Queue<Long> xicDelayedToBeDestroyed = new ArrayDeque<>(XIC_DELAYED_TO_BE_DESTROYED_CAPACITY);
+
+    static void delayAllXICDestroyUntilAFurtherNotice()  {
+        if (log.isLoggable(PlatformLogger.Level.FINE)) {
+            log.fine("delayAllXICDestroyUntilAFurtherNotice(): is being called", new Throwable("Stacktrace"));
+        }
+
+        XToolkit.awtLock();
+        try {
+            if (log.isLoggable(PlatformLogger.Level.FINE)) {
+                log.fine("delayAllXICDestroyUntilAFurtherNotice(): xicDestroyMustBeDelayed=={0}", xicDestroyMustBeDelayed);
+            }
+
+            xicDestroyMustBeDelayed = true;
+        } finally {
+            XToolkit.awtUnlock();
+        }
+    }
+
+    static void delayedXICDestroyShouldBeDone() {
+        XToolkit.awtLock();
+        try {
+            xicDestroyMustBeDelayed = false;
+            doDelayedXICDestroy(false, -1);
+        } finally {
+            XToolkit.awtUnlock();
+        }
+    }
+
+    private static void doDelayedXICDestroy(boolean forced, int maxCountToDestroy) {
+        final boolean isFineLoggable = log.isLoggable(PlatformLogger.Level.FINE);
+
+        if (isFineLoggable) {
+            log.fine(
+                "doDelayedXICDestroy(forced==" + forced + ", maxCountToDestroy==" + maxCountToDestroy + "): is being called",
+                new Throwable("Stacktrace")
+            );
+        }
+
+        assert(SunToolkit.isAWTLockHeldByCurrentThread());
+        assert(forced || !xicDestroyMustBeDelayed);
+
+        while ( (maxCountToDestroy != 0) && !xicDelayedToBeDestroyed.isEmpty() ) {
+            final long pX11IMData = xicDelayedToBeDestroyed.remove();
+            --maxCountToDestroy;
+
+            if (isFineLoggable) {
+                log.fine("doDelayedXICDestroy(): destroying pX11IMData={0}", pX11IMData);
+            }
+
+            assert(pX11IMData != 0);
+            delayedDisposeXIC_disposeXICNative(pX11IMData);
+        }
+    }
+
+    @Override
+    protected void disposeXIC() {
+        awtLock();
+        try {
+            if (log.isLoggable(PlatformLogger.Level.FINE)) {
+                log.fine("disposeXIC(): xicDestroyMustBeDelayed=={0}", xicDestroyMustBeDelayed);
+            }
+
+            if (!xicDestroyMustBeDelayed) {
+                // JBR-6456: Sudden keyboard death on Linux using iBus.
+                // iBus's X11 frontend being run in the async mode (IBUS_ENABLE_SYNC_MODE=0) has a bug leading to a
+                //   violation of the communication protocol between iBus and Xlib (so-called "XIM protocol"),
+                //   later causing Xlib to behave unexpectedly from iBus's point of view, breaking iBus's
+                //   internal state. After all, iBus starts to "steal" all the keyboard events
+                //   (so that each call of XFilterEvent(...) with an instance of XKeyEvent returns True).
+                // The initial iBus's bug only appears when XDestroyIC(...) gets called right after a call of
+                //   XFilterEvent(...) with an instance of XKeyEvent returned True,
+                //   meaning that iBus has started, but hasn't finished yet processing of the key event.
+                // In case of AWT/Swing apps, XDestroyIC gets called whenever a focused HW window gets closed
+                //   (because it leads to disposing of the associated input context,
+                //    see java.awt.Window#doDispose and sun.awt.im.InputContext#dispose)
+                // So, to work around iBus's bug, we have to avoid calling XDestroyIC until iBus finishes processing of
+                //   all the keyboard events it has already started processing of, i.e. until a call of
+                //   XFilterEvent(...) returns False.
+                // To achieve that, the implemented fix delays destroying of input contexts whenever a call of
+                //   XFilterEvent(...) with an instance of XKeyEvent returns True until one of the next calls of
+                //   XFilterEvent(...) with the same instance of XKeyEvent returns False.
+                //   The delaying is implemented via storing the native pointers to the input contexts to
+                //   xicDelayedToBeDestroyed instead of applying XDestroyIC(...) immediately.
+                //   The xicDelayedToBeDestroyed's size is explicitly limited to
+                //      XIC_DELAYED_TO_BE_DESTROYED_CAPACITY. If the limit gets reached, a few input contexts gets
+                //      pulled from there and destroyed regardless of the current value of xicDestroyMustBeDelayed.
+                // The xicDestroyMustBeDelayed field is responsible for indication whether it's required to delay
+                //   the destroying or not. It gets set in #delayAllXICDestroyUntilAFurtherNotice
+                //   and unset in delayedXICDestroyShouldBeDone; both are called by sun.awt.X11.XToolkit depending on
+                //   the value returned by the calls of sun.awt.X11.XlibWrapper#XFilterEvent.
+
+                super.disposeXIC();
+                return;
+            }
+
+            final long pX11IMData = pData;
+
+            // To make sure that the delayed to be destroyed input context won't get used by AWT/Swing or Xlib
+            //   by a mistake, the following things are done:
+            //     1. The input method focus gets detached from the input context (via a call of XUnsetICFocus)
+            //     2. All the native pointers to this instance of XInputMethod
+            //        (now it's just the variable currentX11InputMethodInstance in awt_InputMethod.c) get unset
+            //     3. All the java pointers to the native context (now it's just sun.awt.X11InputMethodBase#pData)
+            //        get unset as well
+            delayedDisposeXIC_preparation_unsetFocusAndDetachCurrentXICNative();
+
+            //     4. The state of the native context gets reset (effectively via a call of XmbResetIC)
+            delayedDisposeXIC_preparation_resetSpecifiedCtxNative(pX11IMData);
+
+            if (pX11IMData == 0) {
+                if (log.isLoggable(PlatformLogger.Level.FINE)) {
+                    log.fine("disposeXIC(): pX11IMData==NULL, skipped");
+                }
+                return;
+            }
+
+            // If the storage is full, a few input context are pulled from there and destroyed regardless of
+            //   the value of xicDestroyMustBeDelayed
+            if (xicDelayedToBeDestroyed.size() >= XIC_DELAYED_TO_BE_DESTROYED_CAPACITY) {
+                if (log.isLoggable(PlatformLogger.Level.FINE)) {
+                    log.fine(
+                        "disposeXIC(): xicDelayedToBeDestroyed.size()=={0} >= XIC_DELAYED_TO_BE_DESTROYED_CAPACITY",
+                        xicDelayedToBeDestroyed.size()
+                    );
+                }
+
+                doDelayedXICDestroy(true, xicDelayedToBeDestroyed.size() - XIC_DELAYED_TO_BE_DESTROYED_CAPACITY + 1);
+            }
+
+            if (log.isLoggable(PlatformLogger.Level.FINE)) {
+                log.fine(
+                    "disposeXIC(): adding pX11IMData=={0} to xicDelayedToBeDestroyed (which already contains {1} elements)",
+                    pX11IMData, xicDelayedToBeDestroyed.size()
+                );
+            }
+            xicDelayedToBeDestroyed.add(pX11IMData);
+        } finally {
+            awtUnlock();
+        }
+    }
+
+
     static void onXKeyEventFiltering(final boolean isXKeyEventFiltered) {
         // Fix of JBR-1573, JBR-2444, JBR-4394 (a.k.a. IDEA-246833).
         // Input method is considered broken if and only if all the following statements are true:
@@ -559,6 +711,15 @@
     private native void setXICFocusNative(long window, boolean value, boolean active);
     private native void adjustStatusWindow(long window);
 
+    // 1. Applies XUnsetICFocus to the current input context
+    // 2. Unsets currentX11InputMethodInstance if it's set to this instance of XInputMethod
+    // 3. Unsets sun.awt.X11InputMethodBase#pData
+    private native void delayedDisposeXIC_preparation_unsetFocusAndDetachCurrentXICNative();
+    // Applies XmbResetIC to the passed input context
+    private static native void delayedDisposeXIC_preparation_resetSpecifiedCtxNative(long pX11IMData);
+    // Applies XDestroyIC to the passed input context
+    private static native void delayedDisposeXIC_disposeXICNative(long pX11IMData);
+
     private native boolean doesFocusedXICSupportMovingCandidatesNativeWindow();
 
     private native void adjustCandidatesNativeWindowPosition(int x, int y);
diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XSystemTrayPeer.java b/src/java.desktop/unix/classes/sun/awt/X11/XSystemTrayPeer.java
index 1a9d040..cdbb74d 100644
--- a/src/java.desktop/unix/classes/sun/awt/X11/XSystemTrayPeer.java
+++ b/src/java.desktop/unix/classes/sun/awt/X11/XSystemTrayPeer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,6 +30,7 @@
 import sun.awt.SunToolkit;
 import sun.awt.AppContext;
 import sun.awt.AWTAccessor;
+import sun.awt.UNIXToolkit;
 import sun.util.logging.PlatformLogger;
 
 public class XSystemTrayPeer implements SystemTrayPeer, XMSelectionListener {
@@ -48,22 +49,32 @@
     private static final XAtom _NET_SYSTEM_TRAY_OPCODE = XAtom.get("_NET_SYSTEM_TRAY_OPCODE");
     private static final XAtom _NET_WM_ICON = XAtom.get("_NET_WM_ICON");
     private static final long SYSTEM_TRAY_REQUEST_DOCK = 0;
+    private final boolean shouldDisableSystemTray;
 
     XSystemTrayPeer(SystemTray target) {
         this.target = target;
         peerInstance = this;
 
-        selection.addSelectionListener(this);
+        UNIXToolkit tk = (UNIXToolkit)Toolkit.getDefaultToolkit();
+        shouldDisableSystemTray = tk.shouldDisableSystemTray();
 
-        long selection_owner = selection.getOwner(SCREEN);
-        available = (selection_owner != XConstants.None);
+        if (!shouldDisableSystemTray) {
+            selection.addSelectionListener(this);
 
-        if (log.isLoggable(PlatformLogger.Level.FINE)) {
-            log.fine(" check if system tray is available. selection owner: " + selection_owner);
+            long selection_owner = selection.getOwner(SCREEN);
+            available = (selection_owner != XConstants.None);
+
+            if (log.isLoggable(PlatformLogger.Level.FINE)) {
+                log.fine(" check if system tray is available. selection owner: " + selection_owner);
+            }
         }
     }
 
     public void ownerChanged(int screen, XMSelection sel, long newOwner, long data, long timestamp) {
+        if (shouldDisableSystemTray) {
+            return;
+        }
+
         if (screen != SCREEN) {
             return;
         }
@@ -77,6 +88,10 @@
     }
 
     public void ownerDeath(int screen, XMSelection sel, long deadOwner) {
+        if (shouldDisableSystemTray) {
+            return;
+        }
+
         if (screen != SCREEN) {
             return;
         }
diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java b/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java
index e2594b3..2d57707 100644
--- a/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java
+++ b/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java
@@ -1016,11 +1016,22 @@
                 final boolean isKeyEvent = ( (ev.get_type() == XConstants.KeyPress) ||
                                              (ev.get_type() == XConstants.KeyRelease) );
 
+                final long keyEventSerial = isKeyEvent ? ev.get_xkey().get_serial() : -1;
+
                 if (keyEventLog.isLoggable(PlatformLogger.Level.FINE) && isKeyEvent) {
                     keyEventLog.fine("before XFilterEvent:" + ev);
                 }
                 if (XlibWrapper.XFilterEvent(ev.getPData(), w)) {
                     if (isKeyEvent) {
+                        if (keyEventLog.isLoggable(PlatformLogger.Level.FINE)) {
+                            keyEventLog.fine(
+                                "Setting lastFilteredKeyEventSerial=={0} to {1}",
+                                lastFilteredKeyEventSerial, keyEventSerial
+                            );
+                        }
+                        lastFilteredKeyEventSerial = keyEventSerial;
+
+                        XInputMethod.delayAllXICDestroyUntilAFurtherNotice();
                         XInputMethod.onXKeyEventFiltering(true);
                     }
                     continue;
@@ -1032,6 +1043,14 @@
 
                 if (isKeyEvent) {
                     XInputMethod.onXKeyEventFiltering(false);
+                    if (keyEventSerial == lastFilteredKeyEventSerial) {
+                        // JBR-6456: Sudden keyboard death on Linux using iBus.
+                        // If more than 1 key events are being processed by iBus
+                        //   (i.e. more than one in a row calls of XFilterEvent(...) with instances of XKeyEvent have
+                        //    returned true),
+                        //   we have to postpone destroying until the very last one is completely processed)
+                        XInputMethod.delayedXICDestroyShouldBeDone();
+                    }
                 }
 
                 dispatchEvent(ev);
@@ -1052,6 +1071,15 @@
         }
     }
 
+
+    // JBR-6456: Sudden keyboard death on Linux using iBus.
+    // The field holds the value of sun.awt.X11.XKeyEvent#get_serial of the last key event, which
+    //   XFilterEvent(...) returned True for.
+    // See the usages of the variable for more info.
+    // See sun.awt.X11.XInputMethod#disposeXIC for the detailed explanation of the whole fix.
+    private long lastFilteredKeyEventSerial = -1;
+
+
     /**
      * Listener installed to detect display changes.
      */
diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java b/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java
index dbf5cef..44b8730 100644
--- a/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java
+++ b/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java
@@ -1287,8 +1287,10 @@
 
     @Override
     void setUserTimeBeforeShowing() {
-        if (XWM.getWMID() == XWM.KDE2_WM && isSimpleWindow() && ((Window)target).getType() == Window.Type.POPUP) {
+        if (XWM.getWMID() == XWM.KDE2_WM && isSimpleWindow() && ((Window)target).getType() == Window.Type.POPUP &&
+            !isInitialising()) {
             // Workaround, to suppress blinking of taskbar icon, when hover popup is displayed for a background window
+            // Checking of initializing status of XBaseWindow class allows to avoid deadlock.
             setUserTime(XToolkit.getCurrentServerTime(), false);
         }
         else if (winAttr.initialFocus || shouldSuppressWmTakeFocus()) {
diff --git a/src/java.desktop/unix/native/libawt_xawt/awt/awt_InputMethod.c b/src/java.desktop/unix/native/libawt_xawt/awt/awt_InputMethod.c
index a769721..93f54ac 100644
--- a/src/java.desktop/unix/native/libawt_xawt/awt/awt_InputMethod.c
+++ b/src/java.desktop/unix/native/libawt_xawt/awt/awt_InputMethod.c
@@ -1634,6 +1634,81 @@
 
 
 JNIEXPORT void JNICALL
+Java_sun_awt_X11_XInputMethod_delayedDisposeXIC_1preparation_1unsetFocusAndDetachCurrentXICNative
+  (JNIEnv *env, jobject this)
+{
+    DASSERT(env != NULL);
+    X11InputMethodData *pX11IMData = NULL;
+
+    AWT_LOCK();
+
+    pX11IMData = getX11InputMethodData(env, this);
+    if (pX11IMData == NULL) {
+        AWT_UNLOCK();
+        return;
+    }
+
+    if (pX11IMData->ic_active.xic != (XIC)0) {
+        setXICFocus(pX11IMData->ic_active.xic, False);
+    }
+    if ( (pX11IMData->ic_passive.xic != (XIC)0) && (pX11IMData->ic_passive.xic != pX11IMData->ic_active.xic) ) {
+        setXICFocus(pX11IMData->ic_passive.xic, False);
+    }
+    pX11IMData->current_ic = (XIC)0;
+
+    setX11InputMethodData(env, this, NULL);
+    if ( (*env)->IsSameObject(env, pX11IMData->x11inputmethod, currentX11InputMethodInstance) == JNI_TRUE ) {
+        // currentX11InputMethodInstance never holds a "unique" java ref - it only holds a "weak" copy of
+        //   _X11InputMethodData::x11inputmethod, so we mustn't DeleteGlobalRef here
+        currentX11InputMethodInstance = NULL;
+        currentFocusWindow = 0;
+    }
+
+    AWT_UNLOCK();
+}
+
+JNIEXPORT void JNICALL
+Java_sun_awt_X11_XInputMethod_delayedDisposeXIC_1preparation_1resetSpecifiedCtxNative
+  (JNIEnv *env, jclass clazz, const jlong pData)
+{
+    X11InputMethodData * const pX11IMData = (X11InputMethodData *)pData;
+    char* preeditText = NULL;
+
+    if (pX11IMData == NULL) {
+        return;
+    }
+
+    AWT_LOCK();
+
+    if (pX11IMData->ic_active.xic != (XIC)0) {
+        if ( (preeditText = XmbResetIC(pX11IMData->ic_active.xic)) != NULL ) {
+           (void)XFree(preeditText); preeditText = NULL;
+        }
+    }
+    if ( (pX11IMData->ic_passive.xic != (XIC)0) && (pX11IMData->ic_passive.xic != pX11IMData->ic_active.xic) ) {
+        if ( (preeditText = XmbResetIC(pX11IMData->ic_passive.xic)) != NULL ) {
+            (void)XFree(preeditText); preeditText = NULL;
+        }
+    }
+
+    AWT_UNLOCK();
+}
+
+JNIEXPORT void JNICALL
+Java_sun_awt_X11_XInputMethod_delayedDisposeXIC_1disposeXICNative(JNIEnv *env, jclass clazz, jlong pData)
+{
+    X11InputMethodData *pX11IMData = (X11InputMethodData *)pData;
+    if (pX11IMData == NULL) {
+        return;
+    }
+
+    AWT_LOCK();
+    destroyX11InputMethodData(env, pX11IMData); pX11IMData = NULL; pData = 0;
+    AWT_UNLOCK();
+}
+
+
+JNIEXPORT void JNICALL
 Java_sun_awt_X11_XInputMethod_setXICFocusNative(JNIEnv *env,
                                                 jobject this,
                                                 jlong w,
diff --git a/src/java.desktop/unix/native/libawt_xawt/xawt/XlibWrapper.c b/src/java.desktop/unix/native/libawt_xawt/xawt/XlibWrapper.c
index 16d7225..7108320 100644
--- a/src/java.desktop/unix/native/libawt_xawt/xawt/XlibWrapper.c
+++ b/src/java.desktop/unix/native/libawt_xawt/xawt/XlibWrapper.c
@@ -2375,6 +2375,7 @@
 
     pRect = (RECT_T *)SAFE_SIZE_ARRAY_ALLOC(malloc, worstBufferSize, sizeof(RECT_T));
     if (!pRect) {
+        (*env)->ReleaseIntArrayElements(env, bitmap, values, JNI_ABORT);
         return;
     }
 
diff --git a/src/java.desktop/windows/native/libawt/windows/AccessibleAnnouncer/JawsAnnouncer.cpp b/src/java.desktop/windows/native/libawt/windows/AccessibleAnnouncer/JawsAnnouncer.cpp
index 37b10d5..12fc71c 100644
--- a/src/java.desktop/windows/native/libawt/windows/AccessibleAnnouncer/JawsAnnouncer.cpp
+++ b/src/java.desktop/windows/native/libawt/windows/AccessibleAnnouncer/JawsAnnouncer.cpp
@@ -31,7 +31,6 @@
 #include "sun_swing_AccessibleAnnouncer.h"

 #include "jni_util.h"                           // JNU_ThrowOutOfMemoryError

 #include "debug_assert.h"                       // DASSERT

-#include <windows.h>                            // GetCurrentThreadId

 #include <initguid.h>                           // DEFINE_GUID

 

 

@@ -57,7 +56,7 @@
 public:

     HRESULT tryInitialize() {

         if (!isInitialized()) {

-            m_initializeResult = CoInitialize(nullptr);

+            m_initializeResult = CoInitializeEx(nullptr, COINIT_MULTITHREADED);

         }

         return m_initializeResult;

     }

@@ -109,17 +108,7 @@
     DASSERT(env != nullptr);

     DASSERT(str != nullptr);

 

-    static const DWORD comInitThreadId = ::GetCurrentThreadId();

-

-    const DWORD currThread = ::GetCurrentThreadId();

-    if (currThread != comInitThreadId) {

-#ifdef DEBUG

-        fprintf(stderr, "JawsAnnounce: currThread != comInitThreadId.\n");

-#endif

-        return false;

-    }

-

-    static ComInitializationWrapper comInitializer;

+    ComInitializationWrapper comInitializer;

     comInitializer.tryInitialize();

     if (!comInitializer.isInitialized()) {

 #ifdef DEBUG

diff --git a/src/java.desktop/windows/native/libawt/windows/ThemeReader.cpp b/src/java.desktop/windows/native/libawt/windows/ThemeReader.cpp
index 97a496f..b9064c5 100644
--- a/src/java.desktop/windows/native/libawt/windows/ThemeReader.cpp
+++ b/src/java.desktop/windows/native/libawt/windows/ThemeReader.cpp
@@ -52,6 +52,7 @@
 typedef HRESULT(__stdcall *PFNDRAWTHEMEBACKGROUND)(HTHEME hTheme, HDC hdc,
         int iPartId, int iStateId, const RECT *pRect,  const RECT *pClipRect);
 
+typedef HTHEME(__stdcall *PFNOPENTHEMEDATA)(HWND hwnd, LPCWSTR pszClassList);
 typedef HTHEME(__stdcall *PFNOPENTHEMEDATAFORDPI)(HWND hwnd, LPCWSTR pszClassList, UINT dpi);
 
 typedef HRESULT (__stdcall *PFNDRAWTHEMETEXT)(HTHEME hTheme, HDC hdc,
@@ -96,6 +97,7 @@
                 (HTHEME hTheme, int iPartId, int iStateIdFrom, int iStateIdTo,
                  int iPropId, DWORD *pdwDuration);
 
+static PFNOPENTHEMEDATA OpenThemeDataFunc = NULL;
 static PFNOPENTHEMEDATAFORDPI OpenThemeDataForDpiFunc = NULL;
 static PFNDRAWTHEMEBACKGROUND DrawThemeBackgroundFunc = NULL;
 static PFNCLOSETHEMEDATA CloseThemeDataFunc = NULL;
@@ -115,13 +117,17 @@
                                IsThemeBackgroundPartiallyTransparentFunc = NULL;
 static PFNGETTHEMETRANSITIONDURATION GetThemeTransitionDurationFunc = NULL;
 
+constexpr unsigned int defaultDPI = 96;
 
-BOOL InitThemes() {
+
+static BOOL InitThemes() {
     static HMODULE hModThemes = NULL;
     hModThemes = JDK_LoadSystemLibrary("UXTHEME.DLL");
     DTRACE_PRINTLN1("InitThemes hModThemes = %x\n", hModThemes);
     if(hModThemes) {
         DTRACE_PRINTLN("Loaded UxTheme.dll\n");
+        OpenThemeDataFunc = (PFNOPENTHEMEDATA)GetProcAddress(hModThemes,
+                                                         "OpenThemeData");
         OpenThemeDataForDpiFunc = (PFNOPENTHEMEDATAFORDPI)GetProcAddress(
                                    hModThemes, "OpenThemeDataForDpi");
         DrawThemeBackgroundFunc = (PFNDRAWTHEMEBACKGROUND)GetProcAddress(
@@ -158,7 +164,7 @@
             (PFNGETTHEMETRANSITIONDURATION)GetProcAddress(hModThemes,
                                         "GetThemeTransitionDuration");
 
-        if(OpenThemeDataForDpiFunc
+        if((OpenThemeDataForDpiFunc || OpenThemeDataFunc)
            && DrawThemeBackgroundFunc
            && CloseThemeDataFunc
            && DrawThemeTextFunc
@@ -179,10 +185,12 @@
               DTRACE_PRINTLN("Loaded function pointers.\n");
               // We need to make sure we can load the Theme.
               // Use the default DPI value of 96 on windows.
-              constexpr unsigned int defaultDPI = 96;
-              HTHEME hTheme = OpenThemeDataForDpiFunc (
-                              AwtToolkit::GetInstance().GetHWnd(),
-                              L"Button", defaultDPI);
+              HTHEME hTheme = OpenThemeDataForDpiFunc
+                              ? OpenThemeDataForDpiFunc(AwtToolkit::GetInstance().GetHWnd(),
+                                                        L"Button", defaultDPI)
+                              : OpenThemeDataFunc(AwtToolkit::GetInstance().GetHWnd(),
+                                                  L"Button");
+
               if(hTheme) {
                   DTRACE_PRINTLN("Loaded Theme data.\n");
                   CloseThemeDataFunc(hTheme);
@@ -252,11 +260,13 @@
         JNU_ThrowOutOfMemoryError(env, 0);
         return 0;
     }
+
     // We need to open the Theme on a Window that will stick around.
     // The best one for that purpose is the Toolkit window.
-    HTHEME htheme = OpenThemeDataForDpiFunc(
-                    AwtToolkit::GetInstance().GetHWnd(),
-                    str, dpi);
+    HTHEME htheme = OpenThemeDataForDpiFunc
+                    ? OpenThemeDataForDpiFunc(AwtToolkit::GetInstance().GetHWnd(), str, dpi)
+                    : OpenThemeDataFunc(AwtToolkit::GetInstance().GetHWnd(), str);
+
     JNU_ReleaseStringPlatformChars(env, widget, str);
     return (jlong) htheme;
 }
@@ -436,9 +446,14 @@
 
     rect.left = 0;
     rect.top = 0;
-    rect.bottom = rectBottom;
-    rect.right = rectRight;
 
+    if (OpenThemeDataForDpiFunc) {
+        rect.bottom = rectBottom;
+        rect.right = rectRight;
+    } else {
+        rect.bottom = h;
+        rect.right = w;
+    }
     ZeroMemory(pSrcBits,(BITS_PER_PIXEL>>3)*w*h);
 
     HRESULT hres = DrawThemeBackgroundFunc(hTheme, memDC, part, state, &rect, NULL);
@@ -461,6 +476,28 @@
     ReleaseDC(NULL,defaultDC);
 }
 
+static void rescale(SIZE *size) {
+    static int dpiX = -1;
+    static int dpiY = -1;
+
+    if (dpiX == -1 || dpiY == -1) {
+        HWND hWnd = ::GetDesktopWindow();
+        HDC hDC = ::GetDC(hWnd);
+        dpiX = ::GetDeviceCaps(hDC, LOGPIXELSX);
+        dpiY = ::GetDeviceCaps(hDC, LOGPIXELSY);
+        ::ReleaseDC(hWnd, hDC);
+    }
+
+    if (dpiX !=0 && dpiX != defaultDPI) {
+        float invScaleX = (float) defaultDPI / dpiX;
+        size->cx = (int) round(size->cx * invScaleX);
+    }
+    if (dpiY != 0 && dpiY != defaultDPI) {
+        float invScaleY = (float) defaultDPI / dpiY;
+        size->cy = (int) round(size->cy * invScaleY);
+    }
+}
+
 jobject newInsets(JNIEnv *env, jint top, jint left, jint bottom, jint right) {
     if (env->EnsureLocalCapacity(2) < 0) {
         return NULL;
@@ -752,6 +789,10 @@
                 CHECK_NULL_RETURN(dimMID, NULL);
             }
 
+            if (!OpenThemeDataForDpiFunc) {
+                rescale(&size);
+            }
+
             jobject dimObj = env->NewObject(dimClassID, dimMID, size.cx, size.cy);
             if (safe_ExceptionOccurred(env)) {
                 env->ExceptionDescribe();
diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp
index 33253b8..f815d9a 100644
--- a/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp
+++ b/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp
@@ -1342,8 +1342,10 @@
       }
       /* Session management */
       case WM_QUERYENDSESSION: {
-          /* Shut down cleanly */
-          if (!isSuddenTerminationEnabled) {
+          // Shut down cleanly
+          // If m_messageLoopResult is EXIT_ALL_ENCLOSING_LOOPS means that application is already in process a closing.
+          // No need to repeat such logic via WM_QUERYENDSESSION and WM_ENDSESSION.
+          if (!isSuddenTerminationEnabled || AwtToolkit::GetInstance().m_messageLoopResult == EXIT_ALL_ENCLOSING_LOOPS) {
               return FALSE;
           }
           if (JVM_RaiseSignal(SIGTERM)) {
diff --git a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp
index ea188e9..1ca8d7a 100644
--- a/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp
+++ b/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -184,6 +184,12 @@
         return 0;
     }
 
+    HRESULT hr = ::CoInitializeEx(NULL, COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE);
+    if (FAILED(hr) && hr != RPC_E_CHANGED_MODE) {
+        DS_unlockCache();
+        return 0;
+    }
+
     if (g_lastCacheRefreshTime == 0
         || (UINT64) timeGetTime() > (UINT64) (g_lastCacheRefreshTime + WAIT_BETWEEN_CACHE_REFRESH_MILLIS)) {
         /* first, initialize any old cache items */
@@ -224,6 +230,11 @@
 
         g_lastCacheRefreshTime = (UINT64) timeGetTime();
     }
+
+    if (hr != RPC_E_CHANGED_MODE) {
+        ::CoUninitialize();
+    }
+
     DS_unlockCache();
     /*TRACE1("DirectSound: %d installed devices\n", g_mixerCount);*/
     return g_mixerCount;
@@ -258,6 +269,13 @@
         DS_unlockCache();
         return FALSE;
     }
+
+    HRESULT hr = ::CoInitializeEx(NULL, COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE);
+    if (FAILED(hr) && hr != RPC_E_CHANGED_MODE) {
+        DS_unlockCache();
+        return 0;
+    }
+
     desc->maxSimulLines = 0;
     if (g_audioDeviceCache[desc->deviceID].isSource) {
         DirectSoundEnumerateW((LPDSENUMCALLBACKW) DS_GetDescEnum, desc);
@@ -267,6 +285,10 @@
         strncpy(desc->description, "DirectSound Capture", DAUDIO_STRING_LENGTH);
     }
 
+    if (hr != RPC_E_CHANGED_MODE) {
+        ::CoUninitialize();
+    }
+
     /*desc->vendor;
     desc->version;*/
 
diff --git a/src/java.management/share/classes/sun/management/ThreadImpl.java b/src/java.management/share/classes/sun/management/ThreadImpl.java
index 8472a66..ce240af 100644
--- a/src/java.management/share/classes/sun/management/ThreadImpl.java
+++ b/src/java.management/share/classes/sun/management/ThreadImpl.java
@@ -349,6 +349,13 @@
         }
     }
 
+    protected long getTotalThreadAllocatedBytes() {
+        if (isThreadAllocatedMemoryEnabled()) {
+            return getTotalThreadAllocatedMemory();
+        }
+        return -1;
+    }
+
     protected long getCurrentThreadAllocatedBytes() {
         if (isThreadAllocatedMemoryEnabled()) {
             return getThreadAllocatedMemory0(0);
@@ -532,6 +539,7 @@
     private static native void getThreadUserCpuTime1(long[] ids, long[] result);
     private static native long getThreadAllocatedMemory0(long id);
     private static native void getThreadAllocatedMemory1(long[] ids, long[] result);
+    private static native long getTotalThreadAllocatedMemory();
     private static native void setThreadCpuTimeEnabled0(boolean enable);
     private static native void setThreadAllocatedMemoryEnabled0(boolean enable);
     private static native void setThreadContentionMonitoringEnabled0(boolean enable);
diff --git a/src/java.management/share/native/libmanagement/ThreadImpl.c b/src/java.management/share/native/libmanagement/ThreadImpl.c
index d4b151d..ec575bb 100644
--- a/src/java.management/share/native/libmanagement/ThreadImpl.c
+++ b/src/java.management/share/native/libmanagement/ThreadImpl.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -98,7 +98,7 @@
 Java_sun_management_ThreadImpl_getThreadAllocatedMemory0
   (JNIEnv *env, jclass cls, jlong tid)
 {
-  return jmm_interface->GetOneThreadAllocatedMemory(env, tid);
+    return jmm_interface->GetOneThreadAllocatedMemory(env, tid);
 }
 
 JNIEXPORT void JNICALL
@@ -108,6 +108,13 @@
     jmm_interface->GetThreadAllocatedMemory(env, ids, sizeArray);
 }
 
+JNIEXPORT jlong JNICALL
+Java_sun_management_ThreadImpl_getTotalThreadAllocatedMemory
+  (JNIEnv *env, jclass cls)
+{
+    return jmm_interface->GetTotalThreadAllocatedMemory(env);
+}
+
 JNIEXPORT jobjectArray JNICALL
 Java_sun_management_ThreadImpl_findMonitorDeadlockedThreads0
   (JNIEnv *env, jclass cls)
diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/ConnectionPool.java b/src/java.net.http/share/classes/jdk/internal/net/http/ConnectionPool.java
index 6c31b8b..a13aadd 100644
--- a/src/java.net.http/share/classes/jdk/internal/net/http/ConnectionPool.java
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/ConnectionPool.java
@@ -103,14 +103,10 @@
                 return false;
             }
             if (secure && destination != null) {
-                if (destination.getHostName() != null) {
-                    if (!destination.getHostName().equalsIgnoreCase(
-                            other.destination.getHostName())) {
-                        return false;
-                    }
-                } else {
-                    if (other.destination.getHostName() != null)
-                        return false;
+                String hostString = destination.getHostString();
+                if (hostString == null || !hostString.equalsIgnoreCase(
+                        other.destination.getHostString())) {
+                    return false;
                 }
             }
             return true;
diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Http2ClientImpl.java b/src/java.net.http/share/classes/jdk/internal/net/http/Http2ClientImpl.java
index 6bd9bad..9f74a70 100644
--- a/src/java.net.http/share/classes/jdk/internal/net/http/Http2ClientImpl.java
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/Http2ClientImpl.java
@@ -93,9 +93,7 @@
      */
     CompletableFuture<Http2Connection> getConnectionFor(HttpRequestImpl req,
                                                         Exchange<?> exchange) {
-        URI uri = req.uri();
-        InetSocketAddress proxy = req.proxy();
-        String key = Http2Connection.keyFor(uri, proxy);
+        String key = Http2Connection.keyFor(req);
 
         synchronized (this) {
             Http2Connection connection = connections.get(key);
diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java b/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java
index 59c88e9..1aa19ee 100644
--- a/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/Http2Connection.java
@@ -402,7 +402,7 @@
         this(connection,
              h2client,
              1,
-             keyFor(request.uri(), request.proxy()));
+             keyFor(request));
 
         Log.logTrace("Connection send window size {0} ", windowController.connectionWindowSize());
 
@@ -534,15 +534,13 @@
         return keyString(isSecure, proxyAddr, addr.getHostString(), addr.getPort());
     }
 
-    static String keyFor(URI uri, InetSocketAddress proxy) {
-        boolean isSecure = uri.getScheme().equalsIgnoreCase("https");
-
-        String host = uri.getHost();
-        int port = uri.getPort();
-        return keyString(isSecure, proxy, host, port);
+    static String keyFor(final HttpRequestImpl request) {
+        final InetSocketAddress targetAddr = request.getAddress();
+        final InetSocketAddress proxy = request.proxy();
+        final boolean secure = request.secure();
+        return keyString(secure, proxy, targetAddr.getHostString(), targetAddr.getPort());
     }
 
-
     // Compute the key for an HttpConnection in the Http2ClientImpl pool:
     // The key string follows one of the three forms below:
     //    {C,S}:H:host:port
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/Init.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/Init.java
index a35a469..7215316 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/Init.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/Init.java
@@ -57,17 +57,22 @@
  */
 public class Init {
 
-    /** The namespace for CONF file **/
+    /**
+     * The namespace for CONF file
+     **/
     public static final String CONF_NS = "http://www.xmlsecurity.org/NS/#configuration";
 
     private static final com.sun.org.slf4j.internal.Logger LOG =
-        com.sun.org.slf4j.internal.LoggerFactory.getLogger(Init.class);
+            com.sun.org.slf4j.internal.LoggerFactory.getLogger(Init.class);
 
-    /** Field alreadyInitialized */
+    /**
+     * Field alreadyInitialized
+     */
     private static boolean alreadyInitialized = false;
 
     /**
      * Method isInitialized
+     *
      * @return true if the library is already initialized.
      */
     public static final synchronized boolean isInitialized() {
@@ -76,35 +81,28 @@
 
     /**
      * Method init
-     *
      */
     public static synchronized void init() {
         if (alreadyInitialized) {
             return;
         }
-
-        @SuppressWarnings("removal")
-        InputStream is =    //NOPMD
-            AccessController.doPrivileged(
-                (PrivilegedAction<InputStream>)
-                    () -> {
-                        String cfile =
-                            System.getProperty("com.sun.org.apache.xml.internal.security.resource.config");
-                        if (cfile == null) {
-                            return null;
-                        }
-                        return getResourceAsStream(cfile, Init.class);
-                    }
-                );
-        if (is == null) {
-            dynamicInit();
-        } else {
-            fileInit(is);
-            try {
-                is.close();
-            } catch (IOException ex) {
-                LOG.warn(ex.getMessage());
+        PrivilegedAction<InputStream> action = () -> {
+            String cfile = System.getProperty("com.sun.org.apache.xml.internal.security.resource.config");
+            if (cfile == null) {
+                return null;
             }
+            return getResourceAsStream(cfile, Init.class);
+        };
+
+        try (@SuppressWarnings("removal")
+             InputStream is = AccessController.doPrivileged(action)) {
+            if (is == null) {
+                dynamicInit();
+            } else {
+                fileInit(is);
+            }
+        } catch (IOException ex) {
+            LOG.warn(ex.getMessage(), ex);
         }
 
         alreadyInitialized = true;
@@ -412,9 +410,11 @@
         }
         List<URL> ret = new ArrayList<>();
         Enumeration<URL> urls = new Enumeration<URL>() {
+            @Override
             public boolean hasMoreElements() {
                 return false;
             }
+            @Override
             public URL nextElement() {
                 return null;
             }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/JCEMapper.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/JCEMapper.java
index 46a265d..e4c1a30 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/JCEMapper.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/JCEMapper.java
@@ -40,7 +40,9 @@
 
     private static Map<String, Algorithm> algorithmsMap = new ConcurrentHashMap<>();
 
-    private static String providerName;
+    private static String globalProviderName;
+
+    private static final ThreadLocal<String> threadSpecificProviderName = new ThreadLocal<>();
 
     /**
      * Method register
@@ -210,6 +212,14 @@
             new Algorithm("EC", "RIPEMD160withECDSA", "Signature")
         );
         algorithmsMap.put(
+            XMLSignature.ALGO_ID_SIGNATURE_EDDSA_ED25519,
+            new Algorithm("Ed25519", "Ed25519", "Signature")
+        );
+        algorithmsMap.put(
+            XMLSignature.ALGO_ID_SIGNATURE_EDDSA_ED448,
+            new Algorithm("Ed448", "Ed448", "Signature")
+        );
+        algorithmsMap.put(
             XMLSignature.ALGO_ID_MAC_HMAC_NOT_RECOMMENDED_MD5,
             new Algorithm("", "HmacMD5", "Mac", 0, 0)
         );
@@ -336,7 +346,10 @@
      * @return the default providerId.
      */
     public static String getProviderId() {
-        return providerName;
+        if (threadSpecificProviderName.get() != null) {
+            return threadSpecificProviderName.get();
+        }
+        return globalProviderName;
     }
 
     /**
@@ -347,7 +360,18 @@
      */
     public static void setProviderId(String provider) {
         JavaUtils.checkRegisterPermission();
-        providerName = provider;
+        globalProviderName = provider;
+    }
+
+    /**
+     * Sets the default Provider for this thread to obtain the security algorithms
+     * @param threadSpecificProviderName the default providerId.
+     * @throws SecurityException if a security manager is installed and the
+     *    caller does not have permission to register the JCE algorithm
+     */
+    public static void setThreadSpecificProviderName(String threadSpecificProviderName) {
+        JavaUtils.checkRegisterPermission();
+        JCEMapper.threadSpecificProviderName.set(threadSpecificProviderName);
     }
 
     /**
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/MessageDigestAlgorithm.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/MessageDigestAlgorithm.java
index 6c3f500..17351f0 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/MessageDigestAlgorithm.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/MessageDigestAlgorithm.java
@@ -256,11 +256,13 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public String getBaseNamespace() {
         return Constants.SignatureSpecNS;
     }
 
     /** {@inheritDoc} */
+    @Override
     public String getBaseLocalName() {
         return Constants._TAG_DIGESTMETHOD;
     }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/SignatureAlgorithm.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/SignatureAlgorithm.java
index 750692f..439eefb 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/SignatureAlgorithm.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/SignatureAlgorithm.java
@@ -35,6 +35,7 @@
 import com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureBaseRSA;
 import com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureDSA;
 import com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureECDSA;
+import com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureEDDSA;
 import com.sun.org.apache.xml.internal.security.exceptions.AlgorithmAlreadyRegisteredException;
 import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException;
 import com.sun.org.apache.xml.internal.security.signature.XMLSignature;
@@ -497,6 +498,12 @@
             XMLSignature.ALGO_ID_SIGNATURE_ECDSA_RIPEMD160, SignatureECDSA.SignatureECDSARIPEMD160.class
         );
         algorithmHash.put(
+                XMLSignature.ALGO_ID_SIGNATURE_EDDSA_ED25519, SignatureEDDSA.SignatureEd25519.class
+        );
+        algorithmHash.put(
+                XMLSignature.ALGO_ID_SIGNATURE_EDDSA_ED448, SignatureEDDSA.SignatureEd448.class
+        );
+        algorithmHash.put(
             XMLSignature.ALGO_ID_MAC_HMAC_NOT_RECOMMENDED_MD5, IntegrityHmac.IntegrityHmacMD5.class
         );
         algorithmHash.put(
@@ -521,6 +528,7 @@
      *
      * @return URI of this element
      */
+    @Override
     public String getBaseNamespace() {
         return Constants.SignatureSpecNS;
     }
@@ -530,6 +538,7 @@
      *
      * @return Local name
      */
+    @Override
     public String getBaseLocalName() {
         return Constants._TAG_SIGNATUREMETHOD;
     }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/SignatureAlgorithmSpi.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/SignatureAlgorithmSpi.java
index a049733..fde070f 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/SignatureAlgorithmSpi.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/SignatureAlgorithmSpi.java
@@ -22,7 +22,12 @@
  */
 package com.sun.org.apache.xml.internal.security.algorithms;
 
-import java.security.*;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.Signature;
 import java.security.spec.AlgorithmParameterSpec;
 
 import com.sun.org.apache.xml.internal.security.signature.XMLSignatureException;
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/ECDSAUtils.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/ECDSAUtils.java
index 63449ee..73e0286 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/ECDSAUtils.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/ECDSAUtils.java
@@ -28,9 +28,13 @@
 import java.io.IOException;
 import java.math.BigInteger;
 import java.security.interfaces.ECPublicKey;
-import java.security.spec.*;
+import java.security.spec.ECField;
+import java.security.spec.ECFieldF2m;
+import java.security.spec.ECFieldFp;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.ECPoint;
+import java.security.spec.EllipticCurve;
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
 
 public final class ECDSAUtils {
@@ -786,9 +790,7 @@
             field = ecFieldF2m.getReductionPolynomial();
         }
 
-        Iterator<ECCurveDefinition> ecCurveDefinitionIterator = ecCurveDefinitions.iterator();
-        while (ecCurveDefinitionIterator.hasNext()) {
-            ECCurveDefinition ecCurveDefinition = ecCurveDefinitionIterator.next();
+        for (ECCurveDefinition ecCurveDefinition : ecCurveDefinitions) {
             String oid = ecCurveDefinition.equals(field, a, b, affineX, affineY, order, h);
             if (oid != null) {
                 return oid;
@@ -798,9 +800,7 @@
     }
 
     public static ECCurveDefinition getECCurveDefinition(String oid) {
-        Iterator<ECCurveDefinition> ecCurveDefinitionIterator = ecCurveDefinitions.iterator();
-        while (ecCurveDefinitionIterator.hasNext()) {
-            ECCurveDefinition ecCurveDefinition = ecCurveDefinitionIterator.next();
+        for (ECCurveDefinition ecCurveDefinition : ecCurveDefinitions) {
             if (ecCurveDefinition.getOid().equals(oid)) {
                 return ecCurveDefinition;
             }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/IntegrityHmac.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/IntegrityHmac.java
index fdaf864..8f83375 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/IntegrityHmac.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/IntegrityHmac.java
@@ -90,6 +90,7 @@
      * @param params
      * @throws XMLSignatureException
      */
+    @Override
     protected void engineSetParameter(AlgorithmParameterSpec params) throws XMLSignatureException {
         throw new XMLSignatureException("empty", new Object[]{"Incorrect method call"});
     }
@@ -102,6 +103,7 @@
      * @return true if the signature is correct
      * @throws XMLSignatureException
      */
+    @Override
     protected boolean engineVerify(byte[] signature) throws XMLSignatureException {
         try {
             if (hmacOutputLength != null && hmacOutputLength.length < getDigestLength()) {
@@ -124,6 +126,7 @@
      * @param secretKey
      * @throws XMLSignatureException
      */
+    @Override
     protected void engineInitVerify(Key secretKey) throws XMLSignatureException {
         if (!(secretKey instanceof SecretKey)) {
             String supplied = null;
@@ -150,6 +153,7 @@
      * @return the result of the {@link java.security.Signature#sign()} method
      * @throws XMLSignatureException
      */
+    @Override
     protected byte[] engineSign() throws XMLSignatureException {
         try {
             if (hmacOutputLength != null && hmacOutputLength.length < getDigestLength()) {
@@ -170,6 +174,7 @@
      * @param secretKey
      * @throws XMLSignatureException
      */
+    @Override
     protected void engineInitSign(Key secretKey) throws XMLSignatureException {
         engineInitSign(secretKey, (AlgorithmParameterSpec)null);
     }
@@ -181,6 +186,7 @@
      * @param algorithmParameterSpec
      * @throws XMLSignatureException
      */
+    @Override
     protected void engineInitSign(
         Key secretKey, AlgorithmParameterSpec algorithmParameterSpec
     ) throws XMLSignatureException {
@@ -213,6 +219,7 @@
      * @param secureRandom
      * @throws XMLSignatureException
      */
+    @Override
     protected void engineInitSign(Key secretKey, SecureRandom secureRandom)
         throws XMLSignatureException {
         throw new XMLSignatureException("algorithms.CannotUseSecureRandomOnMAC");
@@ -225,6 +232,7 @@
      * @param input
      * @throws XMLSignatureException
      */
+    @Override
     protected void engineUpdate(byte[] input) throws XMLSignatureException {
         try {
             this.macAlgorithm.update(input);
@@ -240,6 +248,7 @@
      * @param input
      * @throws XMLSignatureException
      */
+    @Override
     protected void engineUpdate(byte input) throws XMLSignatureException {
         try {
             this.macAlgorithm.update(input);
@@ -257,6 +266,7 @@
      * @param len
      * @throws XMLSignatureException
      */
+    @Override
     protected void engineUpdate(byte[] buf, int offset, int len) throws XMLSignatureException {
         try {
             this.macAlgorithm.update(buf, offset, len);
@@ -270,6 +280,7 @@
      * {@inheritDoc}
      *
      */
+    @Override
     protected String engineGetJCEAlgorithmString() {
         return this.macAlgorithm.getAlgorithm();
     }
@@ -279,6 +290,7 @@
      *
      * {@inheritDoc}
      */
+    @Override
     protected String engineGetJCEProviderName() {
         return this.macAlgorithm.getProvider().getName();
     }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureBaseRSA.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureBaseRSA.java
index 5186520..45dafc3 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureBaseRSA.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureBaseRSA.java
@@ -31,6 +31,8 @@
 import java.security.Signature;
 import java.security.SignatureException;
 import java.security.spec.AlgorithmParameterSpec;
+import java.security.spec.MGF1ParameterSpec;
+import java.security.spec.PSSParameterSpec;
 
 import com.sun.org.apache.xml.internal.security.algorithms.JCEMapper;
 import com.sun.org.apache.xml.internal.security.algorithms.SignatureAlgorithmSpi;
@@ -43,8 +45,6 @@
 import org.w3c.dom.Text;
 
 import javax.xml.crypto.dsig.DigestMethod;
-import java.security.spec.MGF1ParameterSpec;
-import java.security.spec.PSSParameterSpec;
 
 public abstract class SignatureBaseRSA extends SignatureAlgorithmSpi {
 
@@ -65,20 +65,25 @@
 
     public SignatureBaseRSA(Provider provider) throws XMLSignatureException {
         String algorithmID = JCEMapper.translateURItoJCEID(this.engineGetURI());
-        LOG.debug("Created SignatureRSA using {}", algorithmID);
+        this.signatureAlgorithm = getSignature(provider, algorithmID);
+        LOG.debug("Created SignatureRSA using {0} and provider {1}",
+            algorithmID, signatureAlgorithm.getProvider());
+    }
 
+    Signature getSignature(Provider provider, String algorithmID)
+        throws XMLSignatureException {
         try {
             if (provider == null) {
                 String providerId = JCEMapper.getProviderId();
                 if (providerId == null) {
-                    this.signatureAlgorithm = Signature.getInstance(algorithmID);
+                    return Signature.getInstance(algorithmID);
 
                 } else {
-                    this.signatureAlgorithm = Signature.getInstance(algorithmID, providerId);
+                    return Signature.getInstance(algorithmID, providerId);
                 }
 
             } else {
-                this.signatureAlgorithm = Signature.getInstance(algorithmID, provider);
+                return Signature.getInstance(algorithmID, provider);
             }
 
         } catch (NoSuchAlgorithmException | NoSuchProviderException ex) {
@@ -88,6 +93,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     protected void engineSetParameter(AlgorithmParameterSpec params)
         throws XMLSignatureException {
         try {
@@ -98,6 +104,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     protected boolean engineVerify(byte[] signature) throws XMLSignatureException {
         try {
             return this.signatureAlgorithm.verify(signature);
@@ -107,11 +114,13 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     protected void engineInitVerify(Key publicKey) throws XMLSignatureException {
         engineInitVerify(publicKey, this.signatureAlgorithm);
     }
 
     /** {@inheritDoc} */
+    @Override
     protected byte[] engineSign() throws XMLSignatureException {
         try {
             return this.signatureAlgorithm.sign();
@@ -121,17 +130,20 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     protected void engineInitSign(Key privateKey, SecureRandom secureRandom)
         throws XMLSignatureException {
         engineInitSign(privateKey, secureRandom, this.signatureAlgorithm);
     }
 
     /** {@inheritDoc} */
+    @Override
     protected void engineInitSign(Key privateKey) throws XMLSignatureException {
         engineInitSign(privateKey, (SecureRandom)null);
     }
 
     /** {@inheritDoc} */
+    @Override
     protected void engineUpdate(byte[] input) throws XMLSignatureException {
         try {
             this.signatureAlgorithm.update(input);
@@ -141,6 +153,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     protected void engineUpdate(byte input) throws XMLSignatureException {
         try {
             this.signatureAlgorithm.update(input);
@@ -150,6 +163,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     protected void engineUpdate(byte[] buf, int offset, int len) throws XMLSignatureException {
         try {
             this.signatureAlgorithm.update(buf, offset, len);
@@ -159,22 +173,26 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     protected String engineGetJCEAlgorithmString() {
         return this.signatureAlgorithm.getAlgorithm();
     }
 
     /** {@inheritDoc} */
+    @Override
     protected String engineGetJCEProviderName() {
         return this.signatureAlgorithm.getProvider().getName();
     }
 
     /** {@inheritDoc} */
+    @Override
     protected void engineSetHMACOutputLength(int HMACOutputLength)
         throws XMLSignatureException {
         throw new XMLSignatureException("algorithms.HMACOutputLengthOnlyForHMAC");
     }
 
     /** {@inheritDoc} */
+    @Override
     protected void engineInitSign(
         Key signingKey, AlgorithmParameterSpec algorithmParameterSpec
     ) throws XMLSignatureException {
@@ -356,10 +374,53 @@
         }
     }
 
+    public abstract static class SignatureBaseRSAPSS extends SignatureBaseRSA {
+
+        public SignatureBaseRSAPSS() throws XMLSignatureException {
+            super();
+        }
+
+        public SignatureBaseRSAPSS(Provider provider) throws XMLSignatureException {
+            super(provider);
+        }
+
+        @Override
+        Signature getSignature(Provider provider, String algorithmID)
+            throws XMLSignatureException {
+            try {
+                Signature sig;
+                if (provider == null) {
+                    String providerId = JCEMapper.getProviderId();
+                    if (providerId == null) {
+                        sig = Signature.getInstance("RSASSA-PSS");
+                    } else {
+                        sig = Signature.getInstance("RSASSA-PSS", providerId);
+                    }
+                } else {
+                    sig = Signature.getInstance("RSASSA-PSS", provider);
+                }
+                try {
+                    sig.setParameter(getPSSParameterSpec());
+                } catch (InvalidAlgorithmParameterException e) {
+                    throw new NoSuchAlgorithmException("Should not happen", e);
+                }
+                return sig;
+            } catch (NoSuchAlgorithmException | NoSuchProviderException e) {
+                return super.getSignature(provider, algorithmID);
+            }
+        }
+
+        abstract PSSParameterSpec getPSSParameterSpec();
+    }
+
     /**
      * Class SignatureRSASHA1MGF1
      */
-    public static class SignatureRSASHA1MGF1 extends SignatureBaseRSA {
+    public static class SignatureRSASHA1MGF1 extends SignatureBaseRSAPSS {
+
+        private static final PSSParameterSpec SHA1_MGF1_PARAMS
+                = new PSSParameterSpec("SHA-1", "MGF1", MGF1ParameterSpec.SHA1,
+                20, PSSParameterSpec.TRAILER_FIELD_BC);
 
         /**
          * Constructor SignatureRSASHA1MGF1
@@ -379,12 +440,21 @@
         public String engineGetURI() {
             return XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1_MGF1;
         }
+
+        @Override
+        public PSSParameterSpec getPSSParameterSpec() {
+            return SHA1_MGF1_PARAMS;
+        }
     }
 
     /**
      * Class SignatureRSASHA224MGF1
      */
-    public static class SignatureRSASHA224MGF1 extends SignatureBaseRSA {
+    public static class SignatureRSASHA224MGF1 extends SignatureBaseRSAPSS {
+
+        private static final PSSParameterSpec SHA224_MGF1_PARAMS
+                = new PSSParameterSpec("SHA-224", "MGF1", MGF1ParameterSpec.SHA224,
+                28, PSSParameterSpec.TRAILER_FIELD_BC);
 
         /**
          * Constructor SignatureRSASHA224MGF1
@@ -404,12 +474,21 @@
         public String engineGetURI() {
             return XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA224_MGF1;
         }
+
+        @Override
+        public PSSParameterSpec getPSSParameterSpec() {
+            return SHA224_MGF1_PARAMS;
+        }
     }
 
     /**
      * Class SignatureRSASHA256MGF1
      */
-    public static class SignatureRSASHA256MGF1 extends SignatureBaseRSA {
+    public static class SignatureRSASHA256MGF1 extends SignatureBaseRSAPSS {
+
+        private static final PSSParameterSpec SHA256_MGF1_PARAMS
+                = new PSSParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256,
+                32, PSSParameterSpec.TRAILER_FIELD_BC);
 
         /**
          * Constructor SignatureRSASHA256MGF1
@@ -429,12 +508,21 @@
         public String engineGetURI() {
             return XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA256_MGF1;
         }
+
+        @Override
+        public PSSParameterSpec getPSSParameterSpec() {
+            return SHA256_MGF1_PARAMS;
+        }
     }
 
     /**
      * Class SignatureRSASHA384MGF1
      */
-    public static class SignatureRSASHA384MGF1 extends SignatureBaseRSA {
+    public static class SignatureRSASHA384MGF1 extends SignatureBaseRSAPSS {
+
+        private static final PSSParameterSpec SHA384_MGF1_PARAMS
+                = new PSSParameterSpec("SHA-384", "MGF1", MGF1ParameterSpec.SHA384,
+                48, PSSParameterSpec.TRAILER_FIELD_BC);
 
         /**
          * Constructor SignatureRSASHA384MGF1
@@ -454,12 +542,21 @@
         public String engineGetURI() {
             return XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA384_MGF1;
         }
+
+        @Override
+        public PSSParameterSpec getPSSParameterSpec() {
+            return SHA384_MGF1_PARAMS;
+        }
     }
 
     /**
      * Class SignatureRSASHA512MGF1
      */
-    public static class SignatureRSASHA512MGF1 extends SignatureBaseRSA {
+    public static class SignatureRSASHA512MGF1 extends SignatureBaseRSAPSS {
+
+        private static final PSSParameterSpec SHA512_MGF1_PARAMS
+                = new PSSParameterSpec("SHA-512", "MGF1", MGF1ParameterSpec.SHA512,
+                64, PSSParameterSpec.TRAILER_FIELD_BC);
 
         /**
          * Constructor SignatureRSASHA512MGF1
@@ -479,12 +576,22 @@
         public String engineGetURI() {
             return XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA512_MGF1;
         }
+
+        @Override
+        public PSSParameterSpec getPSSParameterSpec() {
+            return SHA512_MGF1_PARAMS;
+        }
     }
 
     /**
      * Class SignatureRSA3_SHA224MGF1
      */
-    public static class SignatureRSASHA3_224MGF1 extends SignatureBaseRSA {
+    public static class SignatureRSASHA3_224MGF1 extends SignatureBaseRSAPSS {
+
+        private static final PSSParameterSpec SHA3_224_MGF1_PARAMS
+                = new PSSParameterSpec("SHA3-224", "MGF1",
+                new MGF1ParameterSpec("SHA3-224"),
+                28, PSSParameterSpec.TRAILER_FIELD_BC);
 
         /**
          * Constructor SignatureRSASHA3_224MGF1
@@ -504,12 +611,22 @@
         public String engineGetURI() {
             return XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA3_224_MGF1;
         }
+
+        @Override
+        public PSSParameterSpec getPSSParameterSpec() {
+            return SHA3_224_MGF1_PARAMS;
+        }
     }
 
     /**
      * Class SignatureRSA3_SHA256MGF1
      */
-    public static class SignatureRSASHA3_256MGF1 extends SignatureBaseRSA {
+    public static class SignatureRSASHA3_256MGF1 extends SignatureBaseRSAPSS {
+
+        private static final PSSParameterSpec SHA3_256_MGF1_PARAMS
+                = new PSSParameterSpec("SHA3-256", "MGF1",
+                new MGF1ParameterSpec("SHA3-256"),
+                32, PSSParameterSpec.TRAILER_FIELD_BC);
 
         /**
          * Constructor SignatureRSASHA3_256MGF1
@@ -529,12 +646,22 @@
         public String engineGetURI() {
             return XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA3_256_MGF1;
         }
+
+        @Override
+        public PSSParameterSpec getPSSParameterSpec() {
+            return SHA3_256_MGF1_PARAMS;
+        }
     }
 
     /**
      * Class SignatureRSA3_SHA384MGF1
      */
-    public static class SignatureRSASHA3_384MGF1 extends SignatureBaseRSA {
+    public static class SignatureRSASHA3_384MGF1 extends SignatureBaseRSAPSS {
+
+        private static final PSSParameterSpec SHA3_384_MGF1_PARAMS
+                = new PSSParameterSpec("SHA3-384", "MGF1",
+                new MGF1ParameterSpec("SHA3-384"),
+                48, PSSParameterSpec.TRAILER_FIELD_BC);
 
         /**
          * Constructor SignatureRSASHA3_384MGF1
@@ -554,12 +681,22 @@
         public String engineGetURI() {
             return XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA3_384_MGF1;
         }
+
+        @Override
+        public PSSParameterSpec getPSSParameterSpec() {
+            return SHA3_384_MGF1_PARAMS;
+        }
     }
 
     /**
      * Class SignatureRSASHA3_512MGF1
      */
-    public static class SignatureRSASHA3_512MGF1 extends SignatureBaseRSA {
+    public static class SignatureRSASHA3_512MGF1 extends SignatureBaseRSAPSS {
+
+        private static final PSSParameterSpec SHA3_512_MGF1_PARAMS
+                = new PSSParameterSpec("SHA3-512", "MGF1",
+                new MGF1ParameterSpec("SHA3-512"),
+                64, PSSParameterSpec.TRAILER_FIELD_BC);
 
         /**
          * Constructor SignatureRSASHA3_512MGF1
@@ -579,10 +716,15 @@
         public String engineGetURI() {
             return XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA3_512_MGF1;
         }
+
+        @Override
+        public PSSParameterSpec getPSSParameterSpec() {
+            return SHA3_512_MGF1_PARAMS;
+        }
     }
 
     public static class SignatureRSASSAPSS extends SignatureBaseRSA {
-        PSSParameterSpec pssParameterSpec;
+        private PSSParameterSpec pssParameterSpec;
 
         public enum DigestAlgorithm {
             SHA224("SHA-224", DigestMethod.SHA224, 28),
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureDSA.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureDSA.java
index 0f9f846..c2b0d05 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureDSA.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureDSA.java
@@ -60,6 +60,7 @@
      *
      * {@inheritDoc}
      */
+    @Override
     protected String engineGetURI() {
         return XMLSignature.ALGO_ID_SIGNATURE_DSA;
     }
@@ -100,6 +101,7 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     protected void engineSetParameter(AlgorithmParameterSpec params)
         throws XMLSignatureException {
         try {
@@ -112,6 +114,7 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     protected boolean engineVerify(byte[] signature)
         throws XMLSignatureException {
         try {
@@ -130,6 +133,7 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     protected void engineInitVerify(Key publicKey) throws XMLSignatureException {
         engineInitVerify(publicKey, this.signatureAlgorithm);
         size = ((DSAKey)publicKey).getParams().getQ().bitLength();
@@ -138,6 +142,7 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     protected byte[] engineSign() throws XMLSignatureException {
         try {
             byte[] jcebytes = this.signatureAlgorithm.sign();
@@ -151,6 +156,7 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     protected void engineInitSign(Key privateKey, SecureRandom secureRandom)
         throws XMLSignatureException {
         engineInitSign(privateKey, secureRandom, this.signatureAlgorithm);
@@ -160,6 +166,7 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     protected void engineInitSign(Key privateKey) throws XMLSignatureException {
         engineInitSign(privateKey, (SecureRandom)null);
     }
@@ -167,6 +174,7 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     protected void engineUpdate(byte[] input) throws XMLSignatureException {
         try {
             this.signatureAlgorithm.update(input);
@@ -178,6 +186,7 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     protected void engineUpdate(byte input) throws XMLSignatureException {
         try {
             this.signatureAlgorithm.update(input);
@@ -189,6 +198,7 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     protected void engineUpdate(byte[] buf, int offset, int len) throws XMLSignatureException {
         try {
             this.signatureAlgorithm.update(buf, offset, len);
@@ -202,6 +212,7 @@
      *
      * {@inheritDoc}
      */
+    @Override
     protected String engineGetJCEAlgorithmString() {
         return this.signatureAlgorithm.getAlgorithm();
     }
@@ -211,6 +222,7 @@
      *
      * {@inheritDoc}
      */
+    @Override
     protected String engineGetJCEProviderName() {
         return this.signatureAlgorithm.getProvider().getName();
     }
@@ -221,6 +233,7 @@
      * @param HMACOutputLength
      * @throws XMLSignatureException
      */
+    @Override
     protected void engineSetHMACOutputLength(int HMACOutputLength) throws XMLSignatureException {
         throw new XMLSignatureException("algorithms.HMACOutputLengthOnlyForHMAC");
     }
@@ -232,6 +245,7 @@
      * @param algorithmParameterSpec
      * @throws XMLSignatureException
      */
+    @Override
     protected void engineInitSign(
         Key signingKey, AlgorithmParameterSpec algorithmParameterSpec
     ) throws XMLSignatureException {
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureECDSA.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureECDSA.java
index 381ead9..75a88b8 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureECDSA.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureECDSA.java
@@ -26,7 +26,14 @@
 package com.sun.org.apache.xml.internal.security.algorithms.implementations;
 
 import java.io.IOException;
-import java.security.*;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Provider;
+import java.security.SecureRandom;
+import java.security.Signature;
+import java.security.SignatureException;
 import java.security.interfaces.ECPrivateKey;
 import java.security.spec.AlgorithmParameterSpec;
 
@@ -118,6 +125,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     protected void engineSetParameter(AlgorithmParameterSpec params)
         throws XMLSignatureException {
         try {
@@ -128,6 +136,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     protected boolean engineVerify(byte[] signature) throws XMLSignatureException {
         try {
             byte[] jcebytes = SignatureECDSA.convertXMLDSIGtoASN1(signature);
@@ -143,11 +152,13 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     protected void engineInitVerify(Key publicKey) throws XMLSignatureException {
         engineInitVerify(publicKey, signatureAlgorithm);
     }
 
     /** {@inheritDoc} */
+    @Override
     protected byte[] engineSign() throws XMLSignatureException {
         try {
             byte[] jcebytes = this.signatureAlgorithm.sign();
@@ -158,6 +169,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     protected void engineInitSign(Key privateKey, SecureRandom secureRandom)
         throws XMLSignatureException {
         if (privateKey instanceof ECPrivateKey) {
@@ -169,11 +181,13 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     protected void engineInitSign(Key privateKey) throws XMLSignatureException {
         engineInitSign(privateKey, (SecureRandom)null);
     }
 
     /** {@inheritDoc} */
+    @Override
     protected void engineUpdate(byte[] input) throws XMLSignatureException {
         try {
             this.signatureAlgorithm.update(input);
@@ -183,6 +197,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     protected void engineUpdate(byte input) throws XMLSignatureException {
         try {
             this.signatureAlgorithm.update(input);
@@ -192,6 +207,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     protected void engineUpdate(byte[] buf, int offset, int len) throws XMLSignatureException {
         try {
             this.signatureAlgorithm.update(buf, offset, len);
@@ -201,22 +217,26 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     protected String engineGetJCEAlgorithmString() {
         return this.signatureAlgorithm.getAlgorithm();
     }
 
     /** {@inheritDoc} */
+    @Override
     protected String engineGetJCEProviderName() {
         return this.signatureAlgorithm.getProvider().getName();
     }
 
     /** {@inheritDoc} */
+    @Override
     protected void engineSetHMACOutputLength(int HMACOutputLength)
         throws XMLSignatureException {
         throw new XMLSignatureException("algorithms.HMACOutputLengthOnlyForHMAC");
     }
 
     /** {@inheritDoc} */
+    @Override
     protected void engineInitSign(
         Key signingKey, AlgorithmParameterSpec algorithmParameterSpec
     ) throws XMLSignatureException {
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureEDDSA.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureEDDSA.java
new file mode 100644
index 0000000..c297d96
--- /dev/null
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/algorithms/implementations/SignatureEDDSA.java
@@ -0,0 +1,247 @@
+/*
+ * reserved comment block
+ * DO NOT REMOVE OR ALTER!
+ */
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.sun.org.apache.xml.internal.security.algorithms.implementations;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.Provider;
+import java.security.SecureRandom;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.spec.AlgorithmParameterSpec;
+
+import com.sun.org.apache.xml.internal.security.algorithms.JCEMapper;
+import com.sun.org.apache.xml.internal.security.algorithms.SignatureAlgorithmSpi;
+import com.sun.org.apache.xml.internal.security.signature.XMLSignature;
+import com.sun.org.apache.xml.internal.security.signature.XMLSignatureException;
+import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
+
+/**
+ *
+ */
+public abstract class SignatureEDDSA extends SignatureAlgorithmSpi {
+
+    private static final com.sun.org.slf4j.internal.Logger LOG =
+        com.sun.org.slf4j.internal.LoggerFactory.getLogger(SignatureEDDSA.class);
+
+    private final Signature signatureAlgorithm;
+
+
+    /**
+     * Constructor SignatureEDDSA
+     *
+     * @throws XMLSignatureException
+     */
+    public SignatureEDDSA() throws XMLSignatureException {
+        this(null);
+    }
+
+    public SignatureEDDSA(Provider provider) throws XMLSignatureException {
+        String algorithmID = JCEMapper.translateURItoJCEID(this.engineGetURI());
+        LOG.debug("Created SignatureEDDSA using {}", algorithmID);
+
+        try {
+            if (provider == null) {
+                String providerId = JCEMapper.getProviderId();
+                if (providerId == null) {
+                    this.signatureAlgorithm = Signature.getInstance(algorithmID);
+
+                } else {
+                    this.signatureAlgorithm = Signature.getInstance(algorithmID, providerId);
+                }
+
+            } else {
+                this.signatureAlgorithm = Signature.getInstance(algorithmID, provider);
+            }
+
+        } catch (NoSuchAlgorithmException | NoSuchProviderException ex) {
+            Object[] exArgs = { algorithmID, ex.getLocalizedMessage() };
+            throw new XMLSignatureException("algorithms.NoSuchAlgorithm", exArgs);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected void engineSetParameter(AlgorithmParameterSpec params)
+        throws XMLSignatureException {
+        try {
+            this.signatureAlgorithm.setParameter(params);
+        } catch (InvalidAlgorithmParameterException ex) {
+            throw new XMLSignatureException(ex);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected boolean engineVerify(byte[] signature) throws XMLSignatureException {
+        try {
+
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Called SignatureEDDSA.verify() on " + XMLUtils.encodeToString(signature));
+            }
+
+            return this.signatureAlgorithm.verify(signature);
+        } catch (SignatureException  ex) {
+            throw new XMLSignatureException(ex);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected void engineInitVerify(Key publicKey) throws XMLSignatureException {
+        engineInitVerify(publicKey, signatureAlgorithm);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected byte[] engineSign() throws XMLSignatureException {
+        try {
+            return this.signatureAlgorithm.sign();
+        } catch (SignatureException ex) {
+            throw new XMLSignatureException(ex);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected void engineInitSign(Key privateKey, SecureRandom secureRandom)
+        throws XMLSignatureException {
+
+        engineInitSign(privateKey, secureRandom, this.signatureAlgorithm);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected void engineInitSign(Key privateKey) throws XMLSignatureException {
+        engineInitSign(privateKey, (SecureRandom)null);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected void engineUpdate(byte[] input) throws XMLSignatureException {
+        try {
+            this.signatureAlgorithm.update(input);
+        } catch (SignatureException ex) {
+            throw new XMLSignatureException(ex);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected void engineUpdate(byte input) throws XMLSignatureException {
+        try {
+            this.signatureAlgorithm.update(input);
+        } catch (SignatureException ex) {
+            throw new XMLSignatureException(ex);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected void engineUpdate(byte[] buf, int offset, int len) throws XMLSignatureException {
+        try {
+            this.signatureAlgorithm.update(buf, offset, len);
+        } catch (SignatureException ex) {
+            throw new XMLSignatureException(ex);
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected String engineGetJCEAlgorithmString() {
+        return this.signatureAlgorithm.getAlgorithm();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected String engineGetJCEProviderName() {
+        return this.signatureAlgorithm.getProvider().getName();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected void engineSetHMACOutputLength(int HMACOutputLength)
+        throws XMLSignatureException {
+        throw new XMLSignatureException("algorithms.HMACOutputLengthOnlyForHMAC");
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected void engineInitSign(
+        Key signingKey, AlgorithmParameterSpec algorithmParameterSpec
+    ) throws XMLSignatureException {
+        throw new XMLSignatureException("algorithms.CannotUseAlgorithmParameterSpecOnEdDSA");
+    }
+
+    /**
+     * Class SignatureEd25519
+     *
+     */
+    public static class SignatureEd25519 extends SignatureEDDSA {
+        /**
+         * Constructor SignatureEd25519
+         *
+         * @throws XMLSignatureException
+         */
+        public SignatureEd25519() throws XMLSignatureException {
+            super();
+        }
+
+        public SignatureEd25519(Provider provider) throws XMLSignatureException {
+            super(provider);
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public String engineGetURI() {
+            return XMLSignature.ALGO_ID_SIGNATURE_EDDSA_ED25519;
+        }
+    }
+
+    /**
+     * Class SignatureEd448
+     */
+    public static class SignatureEd448 extends SignatureEDDSA {
+
+        /**
+         * Constructor SignatureEd448
+         *
+         * @throws XMLSignatureException
+         */
+        public SignatureEd448() throws XMLSignatureException {
+            super();
+        }
+
+        public SignatureEd448(Provider provider) throws XMLSignatureException {
+            super(provider);
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public String engineGetURI() {
+            return XMLSignature.ALGO_ID_SIGNATURE_EDDSA_ED448;
+        }
+    }
+}
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/Canonicalizer.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/Canonicalizer.java
index 71e2d97..4e63933 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/Canonicalizer.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/Canonicalizer.java
@@ -122,7 +122,7 @@
      * @return a Canonicalizer instance ready for the job
      * @throws InvalidCanonicalizerException
      */
-    public static final Canonicalizer getInstance(String algorithmURI)
+    public static Canonicalizer getInstance(String algorithmURI)
         throws InvalidCanonicalizerException {
         return new Canonicalizer(algorithmURI);
     }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/helper/AttrCompare.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/helper/AttrCompare.java
index 5ac239c..cbd541e 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/helper/AttrCompare.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/helper/AttrCompare.java
@@ -22,11 +22,12 @@
  */
 package com.sun.org.apache.xml.internal.security.c14n.helper;
 
-import com.sun.org.apache.xml.internal.security.utils.Constants;
-import org.w3c.dom.Attr;
 import java.io.Serializable;
 import java.util.Comparator;
 
+import com.sun.org.apache.xml.internal.security.utils.Constants;
+import org.w3c.dom.Attr;
+
 /**
  * Compares two attributes based on the C14n specification.
  *
@@ -69,6 +70,7 @@
      *   obj0 is less than, equal to, or greater than obj1
      *
      */
+    @Override
     public int compare(Attr attr0, Attr attr1) {
         String namespaceURI0 = attr0.getNamespaceURI();
         String namespaceURI1 = attr1.getNamespaceURI();
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer11_OmitComments.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer11_OmitComments.java
index 867faad..2f82544 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer11_OmitComments.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer11_OmitComments.java
@@ -32,6 +32,7 @@
         super(false, true);
     }
 
+    @Override
     public final String engineGetURI() {
         return Canonicalizer.ALGO_ID_C14N11_OMIT_COMMENTS;
     }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer11_WithComments.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer11_WithComments.java
index b4ded12..181e559 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer11_WithComments.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer11_WithComments.java
@@ -32,6 +32,7 @@
         super(true, true);
     }
 
+    @Override
     public final String engineGetURI() {
         return Canonicalizer.ALGO_ID_C14N11_WITH_COMMENTS;
     }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315.java
index f0cd610..6b6fda3 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315.java
@@ -83,6 +83,7 @@
      * @param writer OutputStream to write the canonicalization result
      * @throws CanonicalizationException always
      */
+    @Override
     public void engineCanonicalizeXPathNodeSet(Set<Node> xpathNodeSet, String inclusiveNamespaces, OutputStream writer)
         throws CanonicalizationException {
 
@@ -98,6 +99,7 @@
      * @param writer OutputStream to write the canonicalization result
      * @throws CanonicalizationException
      */
+    @Override
     public void engineCanonicalizeSubTree(Node rootNode, String inclusiveNamespaces, OutputStream writer)
         throws CanonicalizationException {
 
@@ -113,6 +115,7 @@
      * @param writer OutputStream to write the canonicalization result
      * @throws CanonicalizationException
      */
+    @Override
     public void engineCanonicalizeSubTree(
             Node rootNode, String inclusiveNamespaces, boolean propagateDefaultNamespace, OutputStream writer)
             throws CanonicalizationException {
@@ -297,6 +300,7 @@
         }
     }
 
+    @Override
     protected void circumventBugIfNeeded(XMLSignatureInput input)
         throws XMLParserException, IOException {
         if (!input.isNeedsToBeExpanded()) {
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315Excl.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315Excl.java
index b7c543e..4432369 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315Excl.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315Excl.java
@@ -82,6 +82,7 @@
      * @param writer OutputStream to write the canonicalization result
      * @throws CanonicalizationException
      */
+    @Override
     public void engineCanonicalizeSubTree(Node rootNode, OutputStream writer)
         throws CanonicalizationException {
         engineCanonicalizeSubTree(rootNode, "", null, writer);
@@ -95,6 +96,7 @@
      * @param writer OutputStream to write the canonicalization result
      * @throws CanonicalizationException
      */
+    @Override
     public void engineCanonicalizeSubTree(
         Node rootNode, String inclusiveNamespaces, OutputStream writer
     ) throws CanonicalizationException {
@@ -110,6 +112,7 @@
      * @param writer OutputStream to write the canonicalization result
      * @throws CanonicalizationException
      */
+    @Override
     public void engineCanonicalizeSubTree(
         Node rootNode, String inclusiveNamespaces, boolean propagateDefaultNamespace, OutputStream writer
     ) throws CanonicalizationException {
@@ -155,6 +158,7 @@
      * @param writer OutputStream to write the canonicalization result
      * @throws CanonicalizationException
      */
+    @Override
     public void engineCanonicalizeXPathNodeSet(
         Set<Node> xpathNodeSet, String inclusiveNamespaces, OutputStream writer
     ) throws CanonicalizationException {
@@ -336,6 +340,7 @@
         }
     }
 
+    @Override
     protected void circumventBugIfNeeded(XMLSignatureInput input)
         throws XMLParserException, IOException {
         if (!input.isNeedsToBeExpanded() || inclusiveNSSet.isEmpty()) {
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315ExclOmitComments.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315ExclOmitComments.java
index df9f88a..ab6a65c 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315ExclOmitComments.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315ExclOmitComments.java
@@ -34,6 +34,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public final String engineGetURI() {
         return Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS;
     }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315ExclWithComments.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315ExclWithComments.java
index 6b80e68..0543430 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315ExclWithComments.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315ExclWithComments.java
@@ -38,6 +38,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public final String engineGetURI() {
         return Canonicalizer.ALGO_ID_C14N_EXCL_WITH_COMMENTS;
     }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315OmitComments.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315OmitComments.java
index 6615436..46f4436 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315OmitComments.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315OmitComments.java
@@ -37,6 +37,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public final String engineGetURI() {
         return Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS;
     }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315WithComments.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315WithComments.java
index 23dd349..54742c6 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315WithComments.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/Canonicalizer20010315WithComments.java
@@ -36,6 +36,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public final String engineGetURI() {
         return Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS;
     }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/CanonicalizerBase.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/CanonicalizerBase.java
index ce971a4..c1f4990 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/CanonicalizerBase.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/CanonicalizerBase.java
@@ -27,7 +27,6 @@
 import java.io.UnsupportedEncodingException;
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
 import java.util.ListIterator;
 import java.util.Map;
@@ -108,6 +107,7 @@
      * @param writer OutputStream to write the canonicalization result
      * @throws CanonicalizationException
      */
+    @Override
     public void engineCanonicalizeSubTree(Node rootNode, OutputStream writer)
         throws CanonicalizationException {
         engineCanonicalizeSubTree(rootNode, (Node)null, writer);
@@ -120,6 +120,7 @@
      * @param writer OutputStream to write the canonicalization result
      * @throws CanonicalizationException
      */
+    @Override
     public void engineCanonicalizeXPathNodeSet(Set<Node> xpathNodeSet, OutputStream writer)
         throws CanonicalizationException {
         this.xpathNodeSet = xpathNodeSet;
@@ -458,13 +459,16 @@
         } while(true);
     }
 
-    protected int isVisibleDO(Node currentNode, int level) {
+    protected int isVisibleDO(Node currentNode, int level) throws CanonicalizationException {
         if (nodeFilter != null) {
-            Iterator<NodeFilter> it = nodeFilter.iterator();
-            while (it.hasNext()) {
-                int i = it.next().isNodeIncludeDO(currentNode, level);
-                if (i != 1) {
-                    return i;
+            for (NodeFilter filter : nodeFilter) {
+                try {
+                    int i = filter.isNodeIncludeDO(currentNode, level);
+                    if (i != 1) {
+                        return i;
+                    }
+                } catch (Exception e) {
+                    throw new CanonicalizationException(e);
                 }
             }
         }
@@ -474,13 +478,16 @@
         return 1;
     }
 
-    protected int isVisibleInt(Node currentNode) {
+    protected int isVisibleInt(Node currentNode) throws CanonicalizationException {
         if (nodeFilter != null) {
-            Iterator<NodeFilter> it = nodeFilter.iterator();
-            while (it.hasNext()) {
-                int i = it.next().isNodeInclude(currentNode);
-                if (i != 1) {
-                    return i;
+            for (NodeFilter filter : nodeFilter) {
+                try {
+                    int i = filter.isNodeInclude(currentNode);
+                    if (i != 1) {
+                        return i;
+                    }
+                } catch (Exception e) {
+                    throw new CanonicalizationException(e);
                 }
             }
         }
@@ -490,12 +497,15 @@
         return 1;
     }
 
-    protected boolean isVisible(Node currentNode) {
+    protected boolean isVisible(Node currentNode) throws CanonicalizationException {
         if (nodeFilter != null) {
-            Iterator<NodeFilter> it = nodeFilter.iterator();
-            while (it.hasNext()) {
-                if (it.next().isNodeInclude(currentNode) != 1) {
-                    return false;
+            for (NodeFilter filter : nodeFilter) {
+                try {
+                    if (filter.isNodeInclude(currentNode) != 1) {
+                        return false;
+                    }
+                } catch (Exception e) {
+                    throw new CanonicalizationException(e);
                 }
             }
         }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/CanonicalizerPhysical.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/CanonicalizerPhysical.java
index 66ad120..c0756d5 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/CanonicalizerPhysical.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/CanonicalizerPhysical.java
@@ -68,6 +68,7 @@
      * @param writer OutputStream to write the canonicalization result
      * @throws CanonicalizationException always
      */
+    @Override
     public void engineCanonicalizeXPathNodeSet(Set<Node> xpathNodeSet, String inclusiveNamespaces, OutputStream writer)
         throws CanonicalizationException {
 
@@ -83,6 +84,7 @@
      * @param writer OutputStream to write the canonicalization result
      * @throws CanonicalizationException
      */
+    @Override
     public void engineCanonicalizeSubTree(Node rootNode, String inclusiveNamespaces, OutputStream writer)
         throws CanonicalizationException {
 
@@ -98,6 +100,7 @@
      * @param writer OutputStream to write the canonicalization result
      * @throws CanonicalizationException
      */
+    @Override
     public void engineCanonicalizeSubTree(
             Node rootNode, String inclusiveNamespaces, boolean propagateDefaultNamespace, OutputStream writer)
             throws CanonicalizationException {
@@ -165,6 +168,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public final String engineGetURI() {
         return Canonicalizer.ALGO_ID_C14N_PHYSICAL;
     }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/NameSpaceSymbTable.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/NameSpaceSymbTable.java
index f0b1903..290ff35 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/NameSpaceSymbTable.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/NameSpaceSymbTable.java
@@ -24,10 +24,8 @@
 
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Iterator;
 import java.util.List;
 
-
 import org.w3c.dom.Attr;
 import org.w3c.dom.Node;
 
@@ -50,7 +48,7 @@
         initialMap.put(XMLNS, ne);
     }
 
-    /**The map betwen prefix-> entry table. */
+    /**The map between prefix-> entry table. */
     private SymbMap symb;
 
     /**The stacks for removing the definitions when doing pop.*/
@@ -58,7 +56,7 @@
     private boolean cloned = true;
 
     /**
-     * Default constractor
+     * Default constructor
      **/
     public NameSpaceSymbTable() {
         //Insert the default binding for xmlns.
@@ -75,18 +73,16 @@
      * @param result the list where to fill the unrendered xmlns definitions.
      **/
     public void getUnrenderedNodes(Collection<Attr> result) {
-        Iterator<NameSpaceSymbEntry> it = symb.entrySet().iterator();
-        while (it.hasNext()) {
-            NameSpaceSymbEntry n = it.next();
+        for (NameSpaceSymbEntry nsEntry : symb.entrySet()) {
             //put them rendered?
-            if (!n.rendered && n.n != null) {
-                n = n.clone();
+            if (!nsEntry.rendered && nsEntry.n != null) {
+                nsEntry = nsEntry.clone();
                 needsClone();
-                symb.put(n.prefix, n);
-                n.lastrendered = n.uri;
-                n.rendered = true;
+                symb.put(nsEntry.prefix, nsEntry);
+                nsEntry.lastrendered = nsEntry.uri;
+                nsEntry.rendered = true;
 
-                result.add(n.n);
+                result.add(nsEntry.n);
             }
         }
     }
@@ -170,14 +166,14 @@
         symb.put(prefix, entry);
         entry.rendered = true;
         entry.lastrendered = entry.uri;
-        // Return the node for outputing.
+        // Return the node for outputting.
         return entry.n;
     }
 
     /**
      * Gets a definition without mark it as render.
      * For render in exclusive c14n the namespaces in the include prefixes.
-     * @param prefix The prefix whose definition is neaded.
+     * @param prefix The prefix whose definition is needed.
      * @return the attr to render, null if there is no need to render
      **/
     public Attr getMappingWithoutRendered(String prefix) {
@@ -314,6 +310,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public NameSpaceSymbEntry clone() { //NOPMD
         try {
             return (NameSpaceSymbEntry)super.clone();
@@ -347,9 +344,9 @@
 
     List<NameSpaceSymbEntry> entrySet() {
         List<NameSpaceSymbEntry> a = new ArrayList<>();
-        for (int i = 0;i < entries.length;i++) {
-            if (entries[i] != null && entries[i].uri.length() != 0) {
-                a.add(entries[i]);
+        for (NameSpaceSymbEntry nsEntry : entries) {
+            if (nsEntry != null && !nsEntry.uri.isEmpty()) {
+                a.add(nsEntry);
             }
         }
         return a;
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/XmlAttrStack.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/XmlAttrStack.java
index 71b8413..a636a77 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/XmlAttrStack.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/c14n/implementations/XmlAttrStack.java
@@ -129,20 +129,16 @@
                 }
             }
             if (!baseAttrs.isEmpty()) {
-                Iterator<Attr> it = col.iterator();
                 String base = null;
                 Attr baseAttr = null;
-                while (it.hasNext()) {
-                    Attr n = it.next();
+                for (Attr n : col) {
                     if ("base".equals(n.getLocalName())) {
                         base = n.getValue();
                         baseAttr = n;
                         break;
                     }
                 }
-                it = baseAttrs.iterator();
-                while (it.hasNext()) {
-                    Attr n = it.next();
+                for (Attr n : baseAttrs) {
                     if (base == null) {
                         base = n.getValue();
                         baseAttr = n;
@@ -162,9 +158,7 @@
         } else {
             for (; size >= 0; size--) {
                 e = levels.get(size);
-                Iterator<Attr> it = e.nodes.iterator();
-                while (it.hasNext()) {
-                    Attr n = it.next();
+                for (Attr n : e.nodes) {
                     if (!loa.containsKey(n.getName())) {
                         loa.put(n.getName(), n);
                     }
@@ -352,7 +346,7 @@
                 // that from the input buffer else if the input buffer consists
                 // only of ".." and if the output buffer does not contain only
                 // the root slash "/", then move the ".." to the output buffer
-                // else delte it.; otherwise,
+                // else delete it.; otherwise,
             } else if (".".equals(input)) {
                 input = "";
                 printStep("2D", output.toString(), input);
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/exceptions/XMLSecurityException.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/exceptions/XMLSecurityException.java
index 9876401..1831407 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/exceptions/XMLSecurityException.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/exceptions/XMLSecurityException.java
@@ -160,6 +160,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public String toString() {
         String s = this.getClass().getName();
         String message = super.getLocalizedMessage();
@@ -181,6 +182,7 @@
      * Method printStackTrace
      *
      */
+    @Override
     public void printStackTrace() {
         synchronized (System.err) {
             super.printStackTrace(System.err);
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/KeyInfo.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/KeyInfo.java
index 519df28..62f25d1 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/KeyInfo.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/KeyInfo.java
@@ -1184,6 +1184,7 @@
 
 
     /** {@inheritDoc} */
+    @Override
     public String getBaseLocalName() {
         return Constants._TAG_KEYINFO;
     }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/DEREncodedKeyValue.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/DEREncodedKeyValue.java
index 6a727b2..823a503 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/DEREncodedKeyValue.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/DEREncodedKeyValue.java
@@ -98,6 +98,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public String getBaseLocalName() {
         return Constants._TAG_DERENCODEDKEYVALUE;
     }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/KeyInfoReference.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/KeyInfoReference.java
index 89e95de..66ef3e3 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/KeyInfoReference.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/KeyInfoReference.java
@@ -95,6 +95,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public String getBaseLocalName() {
         return Constants._TAG_KEYINFOREFERENCE;
     }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/KeyName.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/KeyName.java
index c098cfa..45c18b6 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/KeyName.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/KeyName.java
@@ -65,6 +65,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public String getBaseLocalName() {
         return Constants._TAG_KEYNAME;
     }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/KeyValue.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/KeyValue.java
index d30f504..ee999e6 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/KeyValue.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/KeyValue.java
@@ -160,6 +160,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public String getBaseLocalName() {
         return Constants._TAG_KEYVALUE;
     }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/MgmtData.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/MgmtData.java
index b76ec1e..affe29c 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/MgmtData.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/MgmtData.java
@@ -59,13 +59,14 @@
     /**
      * Method getMgmtData
      *
-     * @return the managment data
+     * @return the management data
      */
     public String getMgmtData() {
         return this.getTextFromTextChild();
     }
 
     /** {@inheritDoc} */
+    @Override
     public String getBaseLocalName() {
         return Constants._TAG_MGMTDATA;
     }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/PGPData.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/PGPData.java
index 27e2550..240bf48 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/PGPData.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/PGPData.java
@@ -44,6 +44,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public String getBaseLocalName() {
         return Constants._TAG_PGPDATA;
     }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/RetrievalMethod.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/RetrievalMethod.java
index 82a949d..84054dd 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/RetrievalMethod.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/RetrievalMethod.java
@@ -129,6 +129,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public String getBaseLocalName() {
         return Constants._TAG_RETRIEVALMETHOD;
     }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/SPKIData.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/SPKIData.java
index a352c05..23eaf1c 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/SPKIData.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/SPKIData.java
@@ -45,6 +45,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public String getBaseLocalName() {
         return Constants._TAG_SPKIDATA;
     }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/X509Data.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/X509Data.java
index 06aeae2..c7640e4 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/X509Data.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/X509Data.java
@@ -528,6 +528,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public String getBaseLocalName() {
         return Constants._TAG_X509DATA;
     }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/keyvalues/DSAKeyValue.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/keyvalues/DSAKeyValue.java
index 9569789..9b2a2d2 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/keyvalues/DSAKeyValue.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/keyvalues/DSAKeyValue.java
@@ -97,6 +97,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public PublicKey getPublicKey() throws XMLSecurityException {
         try {
             DSAPublicKeySpec pkspec =
@@ -123,6 +124,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public String getBaseLocalName() {
         return Constants._TAG_DSAKEYVALUE;
     }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/keyvalues/ECKeyValue.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/keyvalues/ECKeyValue.java
index 0517aa4..839d9e4 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/keyvalues/ECKeyValue.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/keyvalues/ECKeyValue.java
@@ -40,16 +40,15 @@
 
 import javax.xml.crypto.MarshalException;
 
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.Text;
-
 import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException;
 import com.sun.org.apache.xml.internal.security.utils.Constants;
 import com.sun.org.apache.xml.internal.security.utils.I18n;
 import com.sun.org.apache.xml.internal.security.utils.Signature11ElementProxy;
 import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
 
 public class ECKeyValue extends Signature11ElementProxy implements KeyValueContent {
 
@@ -161,6 +160,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public PublicKey getPublicKey() throws XMLSecurityException {
         try {
             ECParameterSpec ecParams = null;
@@ -210,6 +210,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public String getBaseLocalName() {
         return Constants._TAG_ECKEYVALUE;
     }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/keyvalues/RSAKeyValue.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/keyvalues/RSAKeyValue.java
index 5025dcd..b691091 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/keyvalues/RSAKeyValue.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/keyvalues/RSAKeyValue.java
@@ -93,6 +93,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public PublicKey getPublicKey() throws XMLSecurityException {
         try {
             KeyFactory rsaFactory = KeyFactory.getInstance("RSA");
@@ -115,6 +116,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public String getBaseLocalName() {
         return Constants._TAG_RSAKEYVALUE;
     }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509CRL.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509CRL.java
index 5b50fa9..2d0a13a 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509CRL.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509CRL.java
@@ -64,6 +64,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public String getBaseLocalName() {
         return Constants._TAG_X509CRL;
     }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509Certificate.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509Certificate.java
index 56844e4..c50458f 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509Certificate.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509Certificate.java
@@ -127,6 +127,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public boolean equals(Object obj) {
         if (!(obj instanceof XMLX509Certificate)) {
             return false;
@@ -139,12 +140,13 @@
         }
     }
 
+    @Override
     public int hashCode() {
         int result = 17;
         try {
             byte[] bytes = getCertificateBytes();
-            for (int i = 0; i < bytes.length; i++) {
-                result = 31 * result + bytes[i];
+            for (byte element : bytes) {
+                result = 31 * result + element;
             }
         } catch (XMLSecurityException e) {
             LOG.debug(e.getMessage(), e);
@@ -153,6 +155,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public String getBaseLocalName() {
         return Constants._TAG_X509CERTIFICATE;
     }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509Digest.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509Digest.java
index 502a9a4..7011016 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509Digest.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509Digest.java
@@ -132,6 +132,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public String getBaseLocalName() {
         return Constants._TAG_X509DIGEST;
     }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509IssuerSerial.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509IssuerSerial.java
index 0a186da..6e90ae6 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509IssuerSerial.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509IssuerSerial.java
@@ -132,6 +132,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public boolean equals(Object obj) {
         if (!(obj instanceof XMLX509IssuerSerial)) {
             return false;
@@ -143,6 +144,7 @@
             && this.getIssuerName().equals(other.getIssuerName());
     }
 
+    @Override
     public int hashCode() {
         int result = 17;
         result = 31 * result + getSerialNumber().hashCode();
@@ -151,6 +153,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public String getBaseLocalName() {
         return Constants._TAG_X509ISSUERSERIAL;
     }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509SKI.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509SKI.java
index 197d417..451f955 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509SKI.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509SKI.java
@@ -145,6 +145,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public boolean equals(Object obj) {
         if (!(obj instanceof XMLX509SKI)) {
             return false;
@@ -159,12 +160,13 @@
         }
     }
 
+    @Override
     public int hashCode() {
         int result = 17;
         try {
             byte[] bytes = getSKIBytes();
-            for (int i = 0; i < bytes.length; i++) {
-                result = 31 * result + bytes[i];
+            for (byte element : bytes) {
+                result = 31 * result + element;
             }
         } catch (XMLSecurityException e) {
             LOG.debug(e.getMessage(), e);
@@ -174,6 +176,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public String getBaseLocalName() {
         return Constants._TAG_X509SKI;
     }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509SubjectName.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509SubjectName.java
index 564c45e..7b8008f 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509SubjectName.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/content/x509/XMLX509SubjectName.java
@@ -80,6 +80,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public boolean equals(Object obj) {
         if (!(obj instanceof XMLX509SubjectName)) {
             return false;
@@ -92,6 +93,7 @@
         return thisSubject.equals(otherSubject);
     }
 
+    @Override
     public int hashCode() {
         int result = 17;
         result = 31 * result + this.getSubjectName().hashCode();
@@ -99,6 +101,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public String getBaseLocalName() {
         return Constants._TAG_X509SUBJECTNAME;
     }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolver.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolver.java
index 7445013..f0e0785 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolver.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/KeyResolver.java
@@ -31,9 +31,6 @@
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.atomic.AtomicBoolean;
 
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-
 import com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations.DEREncodedKeyValueResolver;
 import com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations.DSAKeyValueResolver;
 import com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations.ECKeyValueResolver;
@@ -47,6 +44,8 @@
 import com.sun.org.apache.xml.internal.security.keys.keyresolver.implementations.X509SubjectNameResolver;
 import com.sun.org.apache.xml.internal.security.keys.storage.StorageResolver;
 import com.sun.org.apache.xml.internal.security.utils.JavaUtils;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
 
 /**
  * KeyResolver is factory class for subclass of KeyResolverSpi that
@@ -295,10 +294,12 @@
             it = res.iterator();
         }
 
+        @Override
         public boolean hasNext() {
             return it.hasNext();
         }
 
+        @Override
         public KeyResolverSpi next() {
             KeyResolverSpi resolver = it.next();
             if (resolver == null) {
@@ -308,6 +309,7 @@
             return resolver;
         }
 
+        @Override
         public void remove() {
             throw new UnsupportedOperationException("Can't remove resolvers using the iterator");
         }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/PrivateKeyResolver.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/PrivateKeyResolver.java
index 20ecdbe..a891104 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/PrivateKeyResolver.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/PrivateKeyResolver.java
@@ -32,7 +32,9 @@
 import java.security.cert.X509Certificate;
 import java.util.Arrays;
 import java.util.Enumeration;
+
 import javax.crypto.SecretKey;
+
 import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException;
 import com.sun.org.apache.xml.internal.security.keys.content.X509Data;
 import com.sun.org.apache.xml.internal.security.keys.content.x509.XMLX509Certificate;
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/RSAKeyValueResolver.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/RSAKeyValueResolver.java
index 6c21cf0..3c44833 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/RSAKeyValueResolver.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/RSAKeyValueResolver.java
@@ -26,7 +26,6 @@
 import java.security.PublicKey;
 import java.security.cert.X509Certificate;
 
-
 import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException;
 import com.sun.org.apache.xml.internal.security.keys.content.keyvalues.RSAKeyValue;
 import com.sun.org.apache.xml.internal.security.keys.keyresolver.KeyResolverSpi;
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/RetrievalMethodResolver.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/RetrievalMethodResolver.java
index 3683ddb..c3170fe 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/RetrievalMethodResolver.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/RetrievalMethodResolver.java
@@ -31,7 +31,6 @@
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
 import java.util.ListIterator;
 import java.util.Set;
@@ -283,10 +282,8 @@
     }
 
     private static Element getDocumentElement(Set<Node> set) {
-        Iterator<Node> it = set.iterator();
         Element e = null;
-        while (it.hasNext()) {
-            Node currentNode = it.next();
+        for (Node currentNode : set) {
             if (currentNode != null && Node.ELEMENT_NODE == currentNode.getNodeType()) {
                 e = (Element) currentNode;
                 break;
@@ -294,7 +291,7 @@
         }
         List<Node> parents = new ArrayList<>();
 
-        // Obtain all the parents of the elemnt
+        // Obtain all the parents of the element
         while (e != null) {
             parents.add(e);
             Node n = e.getParentNode();
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/SecretKeyResolver.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/SecretKeyResolver.java
index f8b6040..761ac9f 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/SecretKeyResolver.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/SecretKeyResolver.java
@@ -27,7 +27,9 @@
 import java.security.PrivateKey;
 import java.security.PublicKey;
 import java.security.cert.X509Certificate;
+
 import javax.crypto.SecretKey;
+
 import com.sun.org.apache.xml.internal.security.keys.keyresolver.KeyResolverException;
 import com.sun.org.apache.xml.internal.security.keys.keyresolver.KeyResolverSpi;
 import com.sun.org.apache.xml.internal.security.keys.storage.StorageResolver;
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/SingleKeyResolver.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/SingleKeyResolver.java
index 6d54380..4e6223f 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/SingleKeyResolver.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/SingleKeyResolver.java
@@ -25,7 +25,9 @@
 import java.security.PrivateKey;
 import java.security.PublicKey;
 import java.security.cert.X509Certificate;
+
 import javax.crypto.SecretKey;
+
 import com.sun.org.apache.xml.internal.security.keys.keyresolver.KeyResolverException;
 import com.sun.org.apache.xml.internal.security.keys.keyresolver.KeyResolverSpi;
 import com.sun.org.apache.xml.internal.security.keys.storage.StorageResolver;
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/X509CertificateResolver.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/X509CertificateResolver.java
index 0be1e5b..7977a55 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/X509CertificateResolver.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/X509CertificateResolver.java
@@ -86,8 +86,8 @@
             }
 
             // populate Object array
-            for (int i = 0; i < els.length; i++) {
-                XMLX509Certificate xmlCert = new XMLX509Certificate(els[i], baseURI);
+            for (Element el : els) {
+                XMLX509Certificate xmlCert = new XMLX509Certificate(el, baseURI);
                 X509Certificate cert = xmlCert.getX509Certificate();
                 if (cert != null) {
                     return cert;
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/X509DigestResolver.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/X509DigestResolver.java
index 9826ea3..047e7ac 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/X509DigestResolver.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/X509DigestResolver.java
@@ -134,8 +134,7 @@
             while (storageIterator.hasNext()) {
                 X509Certificate cert = (X509Certificate) storageIterator.next();
 
-                for (int i = 0; i < x509Digests.length; i++) {
-                    XMLX509Digest keyInfoDigest = x509Digests[i];
+                for (XMLX509Digest keyInfoDigest : x509Digests) {
                     byte[] certDigestBytes = XMLX509Digest.getDigestBytesFromCert(cert, keyInfoDigest.getAlgorithm());
 
                     if (Arrays.equals(keyInfoDigest.getDigestBytes(), certDigestBytes)) {
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/X509SKIResolver.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/X509SKIResolver.java
index c2d8f9c..09150a5 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/X509SKIResolver.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/X509SKIResolver.java
@@ -28,7 +28,6 @@
 import java.security.cert.X509Certificate;
 import java.util.Iterator;
 
-
 import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException;
 import com.sun.org.apache.xml.internal.security.keys.content.x509.XMLX509SKI;
 import com.sun.org.apache.xml.internal.security.keys.keyresolver.KeyResolverException;
@@ -95,20 +94,18 @@
             }
 
             XMLX509SKI[] x509childObject = new XMLX509SKI[x509childNodes.length];
-
             for (int i = 0; i < x509childNodes.length; i++) {
                 x509childObject[i] = new XMLX509SKI(x509childNodes[i], baseURI);
             }
 
             Iterator<Certificate> storageIterator = storage.getIterator();
             while (storageIterator.hasNext()) {
-                X509Certificate cert = (X509Certificate)storageIterator.next();
+                X509Certificate cert = (X509Certificate) storageIterator.next();
                 XMLX509SKI certSKI = new XMLX509SKI(element.getOwnerDocument(), cert);
 
-                for (int i = 0; i < x509childObject.length; i++) {
-                    if (certSKI.equals(x509childObject[i])) {
+                for (XMLX509SKI childNodeSKI : x509childObject) {
+                    if (certSKI.equals(childNodeSKI)) {
                         LOG.debug("Return PublicKey from {}", cert.getSubjectX500Principal().getName());
-
                         return cert;
                     }
                 }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/X509SubjectNameResolver.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/X509SubjectNameResolver.java
index f90ff89..b2bd0770 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/X509SubjectNameResolver.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/keyresolver/implementations/X509SubjectNameResolver.java
@@ -28,7 +28,6 @@
 import java.security.cert.X509Certificate;
 import java.util.Iterator;
 
-
 import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException;
 import com.sun.org.apache.xml.internal.security.keys.content.x509.XMLX509SubjectName;
 import com.sun.org.apache.xml.internal.security.keys.keyresolver.KeyResolverException;
@@ -101,18 +100,15 @@
 
             Iterator<Certificate> storageIterator = storage.getIterator();
             while (storageIterator.hasNext()) {
-                X509Certificate cert = (X509Certificate)storageIterator.next();
-                XMLX509SubjectName certSN =
-                    new XMLX509SubjectName(element.getOwnerDocument(), cert);
-
+                X509Certificate cert = (X509Certificate) storageIterator.next();
+                XMLX509SubjectName certSN = new XMLX509SubjectName(element.getOwnerDocument(), cert);
                 LOG.debug("Found Certificate SN: {}", certSN.getSubjectName());
 
-                for (int i = 0; i < x509childObject.length; i++) {
-                    LOG.debug("Found Element SN:     {}", x509childObject[i].getSubjectName());
+                for (XMLX509SubjectName childSubject : x509childObject) {
+                    LOG.debug("Found Element SN:     {}", childSubject.getSubjectName());
 
-                    if (certSN.equals(x509childObject[i])) {
+                    if (certSN.equals(childSubject)) {
                         LOG.debug("match !!! ");
-
                         return cert;
                     }
                     LOG.debug("no match...");
@@ -122,7 +118,6 @@
             return null;
         } catch (XMLSecurityException ex) {
             LOG.debug("XMLSecurityException", ex);
-
             throw new KeyResolverException(ex);
         }
     }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/StorageResolver.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/StorageResolver.java
index 2da744c..2b90e79 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/StorageResolver.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/StorageResolver.java
@@ -133,6 +133,7 @@
         }
 
         /** {@inheritDoc} */
+        @Override
         public boolean hasNext() {
             if (currentResolver == null) {
                 return false;
@@ -147,6 +148,7 @@
         }
 
         /** {@inheritDoc} */
+        @Override
         public Certificate next() {
             if (hasNext()) {
                 return currentResolver.next();
@@ -158,6 +160,7 @@
         /**
          * Method remove
          */
+        @Override
         public void remove() {
             throw new UnsupportedOperationException("Can't remove keys from KeyStore");
         }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/implementations/KeyStoreResolver.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/implementations/KeyStoreResolver.java
index 6f7ff7d..cfe9c6e 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/implementations/KeyStoreResolver.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/implementations/KeyStoreResolver.java
@@ -64,6 +64,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public Iterator<Certificate> getIterator() {
         return new KeyStoreIterator(this.keyStore);
     }
@@ -103,11 +104,13 @@
         }
 
         /** {@inheritDoc} */
+        @Override
         public boolean hasNext() {
             return this.i < this.certs.size();
         }
 
         /** {@inheritDoc} */
+        @Override
         public Certificate next() {
             if (hasNext()) {
                 return this.certs.get(this.i++);
@@ -119,6 +122,7 @@
         /**
          * Method remove
          */
+        @Override
         public void remove() {
             throw new UnsupportedOperationException("Can't remove keys from KeyStore");
         }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/implementations/SingleCertificateResolver.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/implementations/SingleCertificateResolver.java
index 2b57b3c..9476cfd 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/implementations/SingleCertificateResolver.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/keys/storage/implementations/SingleCertificateResolver.java
@@ -46,6 +46,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public Iterator<Certificate> getIterator() {
         return new InternalIterator(this.certificate);
     }
@@ -71,11 +72,13 @@
         }
 
         /** {@inheritDoc} */
+        @Override
         public boolean hasNext() {
             return !this.alreadyReturned;
         }
 
         /** {@inheritDoc} */
+        @Override
         public Certificate next() {
             if (this.alreadyReturned) {
                 throw new NoSuchElementException();
@@ -87,6 +90,7 @@
         /**
          * Method remove
          */
+        @Override
         public void remove() {
             throw new UnsupportedOperationException("Can't remove keys from KeyStore");
         }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/parser/XMLParser.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/parser/XMLParser.java
index 0942b6b..24acfe3 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/parser/XMLParser.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/parser/XMLParser.java
@@ -31,6 +31,15 @@
  */
 public interface XMLParser {
 
+    /**
+     * Parses a document from the input stream.
+     * Caller is responsible for closing the stream.
+     *
+     * @param inputStream
+     * @param disallowDocTypeDeclarations
+     * @return {@link Document}
+     * @throws XMLParserException
+     */
     Document parse(InputStream inputStream, boolean disallowDocTypeDeclarations) throws XMLParserException;
 
 }
\ No newline at end of file
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/parser/XMLParserImpl.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/parser/XMLParserImpl.java
index be28d28..91f4054 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/parser/XMLParserImpl.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/parser/XMLParserImpl.java
@@ -51,10 +51,10 @@
                     (PrivilegedAction<Integer>) () -> Integer.getInteger("com.sun.org.apache.xml.internal.security.parser.pool-size", 20));
 
     private static final Map<ClassLoader, Queue<DocumentBuilder>> DOCUMENT_BUILDERS =
-            Collections.synchronizedMap(new WeakHashMap<ClassLoader, Queue<DocumentBuilder>>());
+            Collections.synchronizedMap(new WeakHashMap<>());
 
     private static final Map<ClassLoader, Queue<DocumentBuilder>> DOCUMENT_BUILDERS_DISALLOW_DOCTYPE =
-            Collections.synchronizedMap(new WeakHashMap<ClassLoader, Queue<DocumentBuilder>>());
+            Collections.synchronizedMap(new WeakHashMap<>());
 
     @Override
     public Document parse(InputStream inputStream, boolean disallowDocTypeDeclarations) throws XMLParserException {
@@ -119,6 +119,7 @@
         final SecurityManager sm = System.getSecurityManager();
         if (sm != null) {
             return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+                @Override
                 public ClassLoader run() {
                     return Thread.currentThread().getContextClassLoader();
                 }
@@ -132,6 +133,7 @@
         final SecurityManager sm = System.getSecurityManager();
         if (sm != null) {
             return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+                @Override
                 public ClassLoader run() {
                     return clazz.getClassLoader();
                 }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/resource/config.xml b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/resource/config.xml
index bbd26a3..65af7b8 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/resource/config.xml
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/resource/config.xml
@@ -128,6 +128,10 @@
                           JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureECDSA$SignatureECDSASHA512" />

       <SignatureAlgorithm URI="http://www.w3.org/2007/05/xmldsig-more#ecdsa-ripemd160"

                           JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureECDSA$SignatureECDSARIPEMD160" />

+      <SignatureAlgorithm URI="http://www.w3.org/2021/04/xmldsig-more#eddsa-ed25519"

+                          JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureEDDSA$SignatureEd2559" />

+      <SignatureAlgorithm URI="http://www.w3.org/2021/04/xmldsig-more#eddsa-ed448"

+                          JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureEDDSA$SignatureEd448" />

                           

       <SignatureAlgorithm URI="http://www.w3.org/2001/04/xmldsig-more#hmac-md5"

                           JAVACLASS="com.sun.org.apache.xml.internal.security.algorithms.implementations.IntegrityHmac$IntegrityHmacMD5" />

diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/Manifest.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/Manifest.java
index 285d87e..f63ac10 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/Manifest.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/Manifest.java
@@ -28,7 +28,6 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -357,11 +356,8 @@
                             currentRef.dereferenceURIandPerformTransforms(null);
                         Set<Node> nl = signedManifestNodes.getNodeSet();
                         Manifest referencedManifest = null;
-                        Iterator<Node> nlIterator = nl.iterator();
 
-                        while (nlIterator.hasNext()) {
-                            Node n = nlIterator.next();
-
+                        for (Node n : nl) {
                             if (n.getNodeType() == Node.ELEMENT_NODE
                                 && ((Element) n).getNamespaceURI().equals(Constants.SignatureSpecNS)
                                 && ((Element) n).getLocalName().equals(Constants._TAG_MANIFEST)
@@ -579,6 +575,7 @@
      *
      * {@inheritDoc}
      */
+    @Override
     public String getBaseLocalName() {
         return Constants._TAG_MANIFEST;
     }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/NodeFilter.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/NodeFilter.java
index 7b901ec..e53dda3 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/NodeFilter.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/NodeFilter.java
@@ -22,6 +22,7 @@
  */
 package com.sun.org.apache.xml.internal.security.signature;
 
+import com.sun.org.apache.xml.internal.security.transforms.TransformationException;
 import org.w3c.dom.Node;
 
 /**
@@ -37,7 +38,7 @@
      *           -1 if the node and all it's child must not be output.
      *
      */
-    int isNodeInclude(Node n);
+    int isNodeInclude(Node n) throws TransformationException;
 
     /**
      * Tells if a node must be output in a c14n.
@@ -50,6 +51,6 @@
      *            0 if node must not be output,
      *           -1 if the node and all it's child must not be output.
      */
-    int isNodeIncludeDO(Node n, int level);
+    int isNodeIncludeDO(Node n, int level) throws TransformationException;
 
 }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/ObjectContainer.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/ObjectContainer.java
index cf515b8..d1f049b 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/ObjectContainer.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/ObjectContainer.java
@@ -34,7 +34,7 @@
  * Handles {@code &lt;ds:Object&gt;} elements
  * {@code Object} {@link Element} supply facility which can contain any kind data
  *
- * $todo$ if we remove childen, the boolean values are not updated
+ * $todo$ if we remove children, the boolean values are not updated
  */
 public class ObjectContainer extends SignatureElementProxy {
 
@@ -130,6 +130,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public String getBaseLocalName() {
         return Constants._TAG_OBJECT;
     }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/Reference.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/Reference.java
index 384436b..9636031 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/Reference.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/Reference.java
@@ -193,10 +193,12 @@
 
         // Create DigestMethod Element without actually instantiating a MessageDigest Object
         Algorithm digestAlgorithm = new Algorithm(getDocument(), messageDigestAlgorithm) {
+            @Override
             public String getBaseNamespace() {
                 return Constants.SignatureSpecNS;
             }
 
+            @Override
             public String getBaseLocalName() {
                 return Constants._TAG_DIGESTMETHOD;
             }
@@ -612,6 +614,7 @@
             try {
                 final Set<Node> s = input.getNodeSet();
                 referenceData = new ReferenceNodeSetData() {
+                    @Override
                     public Iterator<Node> iterator() {
                         return new Iterator<Node>() {
 
@@ -808,6 +811,7 @@
      * Method getBaseLocalName
      * {@inheritDoc}
      */
+    @Override
     public String getBaseLocalName() {
         return Constants._TAG_REFERENCE;
     }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/SignatureProperties.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/SignatureProperties.java
index 22f19b8..3e5c7e3 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/SignatureProperties.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/SignatureProperties.java
@@ -139,6 +139,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public String getBaseLocalName() {
         return Constants._TAG_SIGNATUREPROPERTIES;
     }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/SignatureProperty.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/SignatureProperty.java
index be83a2a..bc9a700 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/SignatureProperty.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/SignatureProperty.java
@@ -49,7 +49,7 @@
     }
 
     /**
-     * Constructs {@link SignatureProperty} using sepcified {@code target} attribute and
+     * Constructs {@link SignatureProperty} using specified {@code target} attribute and
      * {@code id} attribute
      *
      * @param doc the {@link Document} in which {@code XMLsignature} is placed
@@ -126,6 +126,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public String getBaseLocalName() {
         return Constants._TAG_SIGNATUREPROPERTY;
     }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/SignedInfo.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/SignedInfo.java
index 6d4e4ad..90511f1 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/SignedInfo.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/SignedInfo.java
@@ -27,6 +27,7 @@
 import java.io.OutputStream;
 import java.security.Provider;
 import java.security.spec.AlgorithmParameterSpec;
+
 import javax.crypto.SecretKey;
 import javax.crypto.spec.SecretKeySpec;
 
@@ -38,7 +39,6 @@
 import com.sun.org.apache.xml.internal.security.transforms.params.InclusiveNamespaces;
 import com.sun.org.apache.xml.internal.security.utils.Constants;
 import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
-
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
@@ -401,6 +401,7 @@
      * {@inheritDoc}
      *
      */
+    @Override
     public String getBaseLocalName() {
         return Constants._TAG_SIGNEDINFO;
     }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/VerifiedReference.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/VerifiedReference.java
index df9e301..b2254cf 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/VerifiedReference.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/VerifiedReference.java
@@ -38,7 +38,7 @@
      * @param valid Whether this Reference was successfully validated or not
      * @param uri The URI of this Reference
      * @param manifestReferences If this reference is a reference to a Manifest, this holds the list
-     * of verified referenes associated with this Manifest
+     * of verified references associated with this Manifest
      */
     public VerifiedReference(boolean valid, String uri, List<VerifiedReference> manifestReferences) {
         this.valid = valid;
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/XMLSignature.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/XMLSignature.java
index e9cdaa1..cfa545e 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/XMLSignature.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/XMLSignature.java
@@ -201,6 +201,14 @@
     public static final String ALGO_ID_SIGNATURE_ECDSA_RIPEMD160 =
         "http://www.w3.org/2007/05/xmldsig-more#ecdsa-ripemd160";
 
+    /**Signature - EDDSA ED25519 */
+    public static final String ALGO_ID_SIGNATURE_EDDSA_ED25519 =
+            "http://www.w3.org/2021/04/xmldsig-more#eddsa-ed25519";
+
+    /**Signature - EDDSA ED448 */
+    public static final String ALGO_ID_SIGNATURE_EDDSA_ED448 =
+            "http://www.w3.org/2021/04/xmldsig-more#eddsa-ed448";
+
     /** Signature - Optional RSASSA-PSS */
     public static final String ALGO_ID_SIGNATURE_RSA_PSS =
             Constants.XML_DSIG_NS_MORE_07_05 + "rsa-pss";
@@ -1023,6 +1031,7 @@
      *
      * @return Constants._TAG_SIGNATURE
      */
+    @Override
     public String getBaseLocalName() {
         return Constants._TAG_SIGNATURE;
     }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/XMLSignatureInput.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/XMLSignatureInput.java
index 165bc98..1f192e0 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/XMLSignatureInput.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/XMLSignatureInput.java
@@ -391,6 +391,7 @@
      * Method toString
      * {@inheritDoc}
      */
+    @Override
     public String toString() {
         if (isNodeSet()) {
             return "XMLSignatureInput/NodeSet/" + inputNodeSet.size()
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/XMLSignatureInputDebugger.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/XMLSignatureInputDebugger.java
index 45c2508..193bd20 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/XMLSignatureInputDebugger.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/XMLSignatureInputDebugger.java
@@ -127,7 +127,7 @@
     /**
      * Constructor XMLSignatureInputDebugger
      *
-     * @param xmlSignatureInput the signatur to pretty print
+     * @param xmlSignatureInput the signature to pretty print
      * @param inclusiveNamespace
      */
     public XMLSignatureInputDebugger(
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/reference/ReferenceSubTreeData.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/reference/ReferenceSubTreeData.java
index 2152060..14050f0 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/reference/ReferenceSubTreeData.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/signature/reference/ReferenceSubTreeData.java
@@ -30,6 +30,7 @@
 import java.util.List;
 import java.util.ListIterator;
 import java.util.NoSuchElementException;
+
 import org.w3c.dom.NamedNodeMap;
 import org.w3c.dom.Node;
 
@@ -51,6 +52,7 @@
         this.excludeComments = excludeComments;
     }
 
+    @Override
     public Iterator<Node> iterator() {
         return new DelayedNodeIterator(root, excludeComments);
     }
@@ -78,6 +80,7 @@
             this.withComments = !excludeComments;
         }
 
+        @Override
         public boolean hasNext() {
             if (nodeSet == null) {
                 nodeSet = dereferenceSameDocumentURI(root);
@@ -86,6 +89,7 @@
             return li.hasNext();
         }
 
+        @Override
         public Node next() {
             if (nodeSet == null) {
                 nodeSet = dereferenceSameDocumentURI(root);
@@ -98,6 +102,7 @@
             }
         }
 
+        @Override
         public void remove() {
             throw new UnsupportedOperationException();
         }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/Transform.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/Transform.java
index 5554446..f227ba2 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/Transform.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/Transform.java
@@ -309,7 +309,7 @@
     /**
      * Transforms the input, and generates {@link XMLSignatureInput} as output.
      *
-     * @param input input {@link XMLSignatureInput} which can supplied Octect
+     * @param input input {@link XMLSignatureInput} which can supplied Octet
      * Stream and NodeSet as Input of Transformation
      * @param os where to output the result of the last transformation
      * @param secureValidation Whether secure validation is enabled
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformXPath.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformXPath.java
index ca844c0..72dd114 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformXPath.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformXPath.java
@@ -20,10 +20,16 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+/*
+ * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+ */
 package com.sun.org.apache.xml.internal.security.transforms.implementations;
 
 import java.io.IOException;
 import java.io.OutputStream;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.Security;
 
 import javax.xml.transform.TransformerException;
 
@@ -33,10 +39,7 @@
 import com.sun.org.apache.xml.internal.security.transforms.TransformSpi;
 import com.sun.org.apache.xml.internal.security.transforms.TransformationException;
 import com.sun.org.apache.xml.internal.security.transforms.Transforms;
-import com.sun.org.apache.xml.internal.security.utils.Constants;
-import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
-import com.sun.org.apache.xml.internal.security.utils.XPathAPI;
-import com.sun.org.apache.xml.internal.security.utils.XPathFactory;
+import com.sun.org.apache.xml.internal.security.utils.*;
 import org.w3c.dom.DOMException;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
@@ -52,8 +55,25 @@
  */
 public class TransformXPath extends TransformSpi {
 
-    private static final com.sun.org.slf4j.internal.Logger LOG =
-            com.sun.org.slf4j.internal.LoggerFactory.getLogger(TransformXPath.class);
+    // Whether the here() XPath function is supported.
+    static final boolean HEREFUNC;
+
+    static {
+        @SuppressWarnings("removal")
+        String prop =
+                AccessController.doPrivileged((PrivilegedAction<String>) () ->
+                        Security.getProperty("jdk.xml.dsig.hereFunctionSupported"));
+        if (prop == null) {
+            HEREFUNC = true; // default true
+        } else if (prop.equals("true")) {
+            HEREFUNC = true;
+        } else if (prop.equals("false")) {
+            HEREFUNC = false;
+        } else {
+            throw new IllegalArgumentException(
+                    "Invalid jdk.xml.dsig.hereFunctionSupported setting: " + prop);
+        }
+    }
 
     /**
      * {@inheritDoc}
@@ -112,7 +132,9 @@
     }
 
     protected XPathFactory getXPathFactory() {
-        return XPathFactory.newInstance();
+        return HEREFUNC
+                ? XPathFactory.newInstance()
+                : new JDKXPathFactory();
     }
 
     /**
@@ -140,20 +162,19 @@
         /**
          * @see com.sun.org.apache.xml.internal.security.signature.NodeFilter#isNodeInclude(org.w3c.dom.Node)
          */
-        public int isNodeInclude(Node currentNode) {
+        public int isNodeInclude(Node currentNode) throws TransformationException {
             try {
                 boolean include = xPathAPI.evaluate(currentNode, xpathnode, str, xpathElement);
                 if (include) {
                     return 1;
                 }
                 return 0;
-            } catch (TransformerException e) {
-                LOG.debug("Error evaluating XPath expression", e);
-                return 0;
+            } catch (TransformerException ex) {
+                throw new TransformationException(ex);
             }
         }
 
-        public int isNodeIncludeDO(Node n, int level) {
+        public int isNodeIncludeDO(Node n, int level) throws TransformationException {
             return isNodeInclude(n);
         }
 
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformXPath2Filter.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformXPath2Filter.java
index 800f7ca..b198c54 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformXPath2Filter.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/transforms/implementations/TransformXPath2Filter.java
@@ -38,6 +38,7 @@
 import com.sun.org.apache.xml.internal.security.transforms.TransformationException;
 import com.sun.org.apache.xml.internal.security.transforms.Transforms;
 import com.sun.org.apache.xml.internal.security.transforms.params.XPath2FilterContainer;
+import com.sun.org.apache.xml.internal.security.utils.JDKXPathFactory;
 import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
 import com.sun.org.apache.xml.internal.security.utils.XPathAPI;
 import com.sun.org.apache.xml.internal.security.utils.XPathFactory;
@@ -94,7 +95,9 @@
                 inputDoc = XMLUtils.getOwnerDocument(input.getNodeSet());
             }
 
-            XPathFactory xpathFactory = XPathFactory.newInstance();
+            XPathFactory xpathFactory = TransformXPath.HEREFUNC
+                    ? XPathFactory.newInstance()
+                    : new JDKXPathFactory();
             for (int i = 0; i < xpathElements.length; i++) {
                 Element xpathElement = xpathElements[i];
 
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/Base64.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/Base64.java
index 0534fff..2d5c019 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/Base64.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/Base64.java
@@ -108,7 +108,7 @@
      * @param bitlen {@code int} the desired length in bits of the representation
      * @return a byte array with {@code bitlen} bits of {@code big}
      */
-    static final byte[] getBytes(BigInteger big, int bitlen) {
+    static byte[] getBytes(BigInteger big, int bitlen) {
 
         //round bitlen
         bitlen = ((bitlen + 7) >> 3) << 3;
@@ -148,7 +148,7 @@
      * @param big
      * @return String with Base64 encoding
      */
-    public static final String encode(BigInteger big) {
+    public static String encode(BigInteger big) {
         byte[] bytes = XMLUtils.getBytes(big, big.bitLength());
         return XMLUtils.encodeToString(bytes);
     }
@@ -164,7 +164,7 @@
      * @param bitlen {@code int} the desired length in bits of the representation
      * @return a byte array with {@code bitlen} bits of {@code big}
      */
-    public static final byte[] encode(BigInteger big, int bitlen) {
+    public static byte[] encode(BigInteger big, int bitlen) {
 
         //round bitlen
         bitlen = ((bitlen + 7) >> 3) << 3;
@@ -205,7 +205,7 @@
      * @return the biginteger obtained from the node
      * @throws Base64DecodingException
      */
-    public static final BigInteger decodeBigIntegerFromElement(Element element)
+    public static BigInteger decodeBigIntegerFromElement(Element element)
         throws Base64DecodingException {
         return new BigInteger(1, Base64.decode(element));
     }
@@ -216,7 +216,7 @@
      * @return a decoded BigInteger
      * @throws Base64DecodingException
      */
-    public static final BigInteger decodeBigIntegerFromText(Text text)
+    public static BigInteger decodeBigIntegerFromText(Text text)
         throws Base64DecodingException {
         return new BigInteger(1, Base64.decode(text.getData()));
     }
@@ -228,7 +228,7 @@
      * @param element
      * @param biginteger
      */
-    public static final void fillElementWithBigInteger(Element element, BigInteger biginteger) {
+    public static void fillElementWithBigInteger(Element element, BigInteger biginteger) {
 
         String encodedInt = encode(biginteger);
 
@@ -253,7 +253,7 @@
      * $todo$ not tested yet
      * @throws Base64DecodingException
      */
-    public static final byte[] decode(Element element) throws Base64DecodingException {
+    public static byte[] decode(Element element) throws Base64DecodingException {
 
         Node sibling = element.getFirstChild();
         StringBuilder sb = new StringBuilder();
@@ -279,7 +279,7 @@
      * @return an Element with the base64 encoded in the text.
      *
      */
-    public static final Element encodeToElement(Document doc, String localName, byte[] bytes) {
+    public static Element encodeToElement(Document doc, String localName, byte[] bytes) {
         Element el = XMLUtils.createElementInSignatureSpace(doc, localName);
         Text text = doc.createTextNode(encode(bytes));
 
@@ -296,7 +296,7 @@
      * @throws Base64DecodingException
      *
      */
-    public static final byte[] decode(byte[] base64) throws Base64DecodingException  {
+    public static byte[] decode(byte[] base64) throws Base64DecodingException  {
         return decodeInternal(base64, -1);
     }
 
@@ -307,7 +307,7 @@
      * @param binaryData {@code byte[]} to be base64 encoded
      * @return the {@code String} with encoded data
      */
-    public static final String encode(byte[] binaryData) {
+    public static String encode(byte[] binaryData) {
         return XMLUtils.ignoreLineBreaks()
             ? encode(binaryData, Integer.MAX_VALUE)
             : encode(binaryData, BASE64DEFAULTLENGTH);
@@ -323,7 +323,7 @@
      * @throws IOException
      * @throws Base64DecodingException
      */
-    public static final byte[] decode(BufferedReader reader)
+    public static byte[] decode(BufferedReader reader)
         throws IOException, Base64DecodingException {
 
         byte[] retBytes = null;
@@ -342,11 +342,11 @@
         return retBytes;
     }
 
-    protected static final boolean isWhiteSpace(byte octet) {
+    protected static boolean isWhiteSpace(byte octet) {
         return octet == 0x20 || octet == 0xd || octet == 0xa || octet == 0x9;
     }
 
-    protected static final boolean isPad(byte octet) {
+    protected static boolean isPad(byte octet) {
         return octet == PAD;
     }
 
@@ -364,7 +364,7 @@
      * @param length {@code int} length of wrapped lines; No wrapping if less than 4.
      * @return a {@code String} with encoded data
      */
-    public static final String  encode(byte[] binaryData, int length) {
+    public static String  encode(byte[] binaryData, int length) {
         if (length < 4) {
             length = Integer.MAX_VALUE;
         }
@@ -474,7 +474,7 @@
      * @return byte array containing the decoded data
      * @throws Base64DecodingException if there is a problem decoding the data
      */
-    public static final byte[] decode(String encoded) throws Base64DecodingException {
+    public static byte[] decode(String encoded) throws Base64DecodingException {
         if (encoded == null) {
             return null;
         }
@@ -483,7 +483,7 @@
         return decodeInternal(bytes, len);
     }
 
-    protected static final int getBytesInternal(String s, byte[] result) {
+    protected static int getBytesInternal(String s, byte[] result) {
         int length = s.length();
 
         int newSize = 0;
@@ -496,7 +496,7 @@
         return newSize;
     }
 
-    protected static final byte[] decodeInternal(byte[] base64Data, int len)
+    protected static byte[] decodeInternal(byte[] base64Data, int len)
         throws Base64DecodingException {
         // remove white spaces
         if (len == -1) {
@@ -591,7 +591,7 @@
      * @throws IOException
      * @throws Base64DecodingException
      */
-    public static final void decode(String base64Data, OutputStream os)
+    public static void decode(String base64Data, OutputStream os)
         throws Base64DecodingException, IOException {
         byte[] bytes = new byte[base64Data.length()];
         int len = getBytesInternal(base64Data, bytes);
@@ -606,12 +606,12 @@
      * @throws IOException
      * @throws Base64DecodingException
      */
-    public static final void decode(byte[] base64Data, OutputStream os)
+    public static void decode(byte[] base64Data, OutputStream os)
         throws Base64DecodingException, IOException {
         decode(base64Data, os, -1);
     }
 
-    protected static final void decode(byte[] base64Data, OutputStream os, int len)
+    protected static void decode(byte[] base64Data, OutputStream os, int len)
         throws Base64DecodingException, IOException {
         // remove white spaces
         if (len == -1) {
@@ -694,7 +694,7 @@
      * @throws IOException
      * @throws Base64DecodingException
      */
-    public static final void decode(InputStream is, OutputStream os)
+    public static void decode(InputStream is, OutputStream os)
         throws Base64DecodingException, IOException {
         //byte[] decodedData = null;
         byte b1 = 0, b2 = 0, b3 = 0, b4 = 0;
@@ -771,7 +771,7 @@
      * @param data  the byte array of base64 data (with WS)
      * @return the new length
      */
-    protected static final int removeWhiteSpace(byte[] data) {
+    protected static int removeWhiteSpace(byte[] data) {
         if (data == null) {
             return 0;
         }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/DOMNamespaceContext.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/DOMNamespaceContext.java
index 6a2f5d5..0c2c5c8 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/DOMNamespaceContext.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/DOMNamespaceContext.java
@@ -84,6 +84,7 @@
         this.context = context;
     }
 
+    @Override
     public String getNamespaceURI(String prefix) {
         if (prefix == null) {
             throw new IllegalArgumentException("prefix is null");
@@ -107,6 +108,7 @@
         return NULL_NS_URI;
     }
 
+    @Override
     public String getPrefix(String namespaceURI) {
         if (namespaceURI == null) {
             throw new IllegalArgumentException("namespace URI is null");
@@ -140,6 +142,7 @@
     /**
      * Throws {@link UnsupportedOperationException}.
      */
+    @Override
     public Iterator<String> getPrefixes(String namespaceURI) {
         throw new UnsupportedOperationException();
     }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/DigesterOutputStream.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/DigesterOutputStream.java
index 8f584c3..06840f7 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/DigesterOutputStream.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/DigesterOutputStream.java
@@ -43,16 +43,19 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public void write(byte[] arg0) {
         write(arg0, 0, arg0.length);
     }
 
     /** {@inheritDoc} */
-    public void write(int arg0) {
+    @Override
+    public synchronized void write(int arg0) {
         mda.update((byte)arg0);
     }
 
     /** {@inheritDoc} */
+    @Override
     public void write(byte[] arg0, int arg1, int arg2) {
         if (LOG.isDebugEnabled()) {
             LOG.debug("Pre-digested input:");
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/ElementProxy.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/ElementProxy.java
index c1d4c5d..6f061fc 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/ElementProxy.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/ElementProxy.java
@@ -23,8 +23,8 @@
 package com.sun.org.apache.xml.internal.security.utils;
 
 import java.math.BigInteger;
-import java.util.concurrent.ConcurrentHashMap;
 import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 
 import com.sun.org.apache.xml.internal.security.exceptions.XMLSecurityException;
 import org.w3c.dom.Attr;
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/HelperNodeList.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/HelperNodeList.java
index 65f9b8f..b198861 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/HelperNodeList.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/HelperNodeList.java
@@ -57,6 +57,7 @@
      * @param index
      * @return node with index i
      */
+    @Override
     public Node item(int index) {
         return nodes.get(index);
     }
@@ -66,6 +67,7 @@
      *
      *  @return length of the list
      */
+    @Override
     public int getLength() {
         return nodes.size();
     }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/I18n.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/I18n.java
index 9b92879..0159aa1 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/I18n.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/I18n.java
@@ -55,7 +55,7 @@
     /**
      * Method translate
      *
-     * translates a message ID into an internationalized String, see alse
+     * translates a message ID into an internationalized String, see also
      * {@code XMLSecurityException.getExceptionMEssage()}. The strings are
      * stored in the {@code ResourceBundle}, which is identified in
      * {@code exceptionMessagesResourceBundleBase}
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/JDKXPathAPI.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/JDKXPathAPI.java
index e6b65e0..ea5524e 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/JDKXPathAPI.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/JDKXPathAPI.java
@@ -57,6 +57,7 @@
      *
      * @throws TransformerException
      */
+    @Override
     public NodeList selectNodeList(
         Node contextNode, Node xpathnode, String str, Node namespaceNode
     ) throws TransformerException {
@@ -92,6 +93,7 @@
      *  @param str The XPath expression
      *  @param namespaceNode The node from which prefixes in the XPath will be resolved to namespaces.
      */
+    @Override
     public boolean evaluate(Node contextNode, Node xpathnode, String str, Node namespaceNode)
         throws TransformerException {
         if (!str.equals(xpathStr) || xpathExpression == null) {
@@ -122,6 +124,7 @@
     /**
      * Clear any context information from this object
      */
+    @Override
     public void clear() {
         xpathStr = null;
         xpathExpression = null;
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/JDKXPathFactory.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/JDKXPathFactory.java
index 98c1872..2659fc0 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/JDKXPathFactory.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/JDKXPathFactory.java
@@ -31,6 +31,7 @@
     /**
      * Get a new XPathAPI instance
      */
+    @Override
     public XPathAPI newXPathAPI() {
         return new JDKXPathAPI();
     }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/JavaUtils.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/JavaUtils.java
index 4f5cb7d..647675a 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/JavaUtils.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/JavaUtils.java
@@ -95,7 +95,7 @@
 
     /**
      * This method reads all bytes from the given InputStream till EOF and
-     * returns them as a byte array.
+     * returns them as a byte array. The method doesn't close the input stream.
      *
      * @param inputStream
      * @return the bytes read from the stream
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/RFC2253Parser.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/RFC2253Parser.java
index 552d133..1f0fc29 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/RFC2253Parser.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/RFC2253Parser.java
@@ -468,15 +468,15 @@
      */
     static String trim(String str) {
 
-        String trimed = str.trim();
-        int i = str.indexOf(trimed) + trimed.length();
+        String trimmed = str.trim();
+        int i = str.indexOf(trimmed) + trimmed.length();
 
-        if (str.length() > i && trimed.endsWith("\\")
-            && !trimed.endsWith("\\\\") && str.charAt(i) == ' ') {
-            trimed = trimed + " ";
+        if (str.length() > i && trimmed.endsWith("\\")
+            && !trimmed.endsWith("\\\\") && str.charAt(i) == ' ') {
+            trimmed = trimmed + " ";
         }
 
-        return trimed;
+        return trimmed;
     }
 
 }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/Signature11ElementProxy.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/Signature11ElementProxy.java
index 6a5981f..086698c 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/Signature11ElementProxy.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/Signature11ElementProxy.java
@@ -69,6 +69,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public String getBaseNamespace() {
         return Constants.SignatureSpec11NS;
     }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/SignatureElementProxy.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/SignatureElementProxy.java
index e10f09f..847ed4e 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/SignatureElementProxy.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/SignatureElementProxy.java
@@ -63,6 +63,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public String getBaseNamespace() {
         return Constants.SignatureSpecNS;
     }
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/SignerOutputStream.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/SignerOutputStream.java
index beb0604..04c2555 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/SignerOutputStream.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/SignerOutputStream.java
@@ -44,6 +44,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public void write(byte[] arg0)  {
         try {
             sa.update(arg0);
@@ -53,6 +54,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public void write(int arg0) {
         try {
             sa.update((byte)arg0);
@@ -62,6 +64,7 @@
     }
 
     /** {@inheritDoc} */
+    @Override
     public void write(byte[] arg0, int arg1, int arg2) {
         if (LOG.isDebugEnabled()) {
             LOG.debug("Canonicalized SignedInfo:");
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/UnsyncByteArrayOutputStream.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/UnsyncByteArrayOutputStream.java
index a0358ff..f0dc143 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/UnsyncByteArrayOutputStream.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/UnsyncByteArrayOutputStream.java
@@ -44,6 +44,7 @@
         buf = new byte[INITIAL_SIZE];
     }
 
+    @Override
     public void write(byte[] arg0) {
         if ((VM_ARRAY_INDEX_MAX_VALUE - pos) < arg0.length) {
             throw new OutOfMemoryError("Required length exceeds implementation limit");
@@ -56,6 +57,7 @@
         pos = newPos;
     }
 
+    @Override
     public void write(byte[] arg0, int arg1, int arg2) {
         if ((VM_ARRAY_INDEX_MAX_VALUE - pos) < arg2) {
             throw new OutOfMemoryError("Required length exceeds implementation limit");
@@ -68,6 +70,7 @@
         pos = newPos;
     }
 
+    @Override
     public void write(int arg0) {
         if (VM_ARRAY_INDEX_MAX_VALUE - pos == 0) {
             throw new OutOfMemoryError("Required length exceeds implementation limit");
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/XMLUtils.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/XMLUtils.java
index 446d640..ca1eea1 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/XMLUtils.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/XMLUtils.java
@@ -22,11 +22,15 @@
  */
 package com.sun.org.apache.xml.internal.security.utils;
 
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.lang.reflect.InvocationTargetException;
 import java.math.BigInteger;
+import java.nio.file.Files;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.ArrayList;
@@ -42,6 +46,8 @@
 import com.sun.org.apache.xml.internal.security.parser.XMLParser;
 import com.sun.org.apache.xml.internal.security.parser.XMLParserException;
 import com.sun.org.apache.xml.internal.security.parser.XMLParserImpl;
+import com.sun.org.slf4j.internal.Logger;
+import com.sun.org.slf4j.internal.LoggerFactory;
 import org.w3c.dom.Attr;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -50,6 +56,8 @@
 import org.w3c.dom.NodeList;
 import org.w3c.dom.Text;
 
+import static java.nio.charset.StandardCharsets.UTF_8;
+
 /**
  * DOM and XML accessibility and comfort functions.
  *
@@ -61,8 +69,7 @@
             AccessController.doPrivileged(
                     (PrivilegedAction<Boolean>) () -> Boolean.getBoolean("com.sun.org.apache.xml.internal.security.ignoreLineBreaks"));
 
-    private static final com.sun.org.slf4j.internal.Logger LOG =
-            com.sun.org.slf4j.internal.LoggerFactory.getLogger(XMLUtils.class);
+    private static final Logger LOG = LoggerFactory.getLogger(XMLUtils.class);
 
     @SuppressWarnings("removal")
     private static XMLParser xmlParserImpl =
@@ -74,7 +81,7 @@
                                 return (XMLParser) JavaUtils.newInstanceWithEmptyConstructor(
                                         ClassLoaderUtils.loadClass(xmlParserClass, XMLUtils.class));
                             } catch (ClassNotFoundException | IllegalAccessException | InstantiationException | InvocationTargetException e) {
-                                LOG.error("Error instantiating XMLParser. Falling back to XMLParserImpl");
+                                LOG.error("Error instantiating XMLParser. Falling back to XMLParserImpl", e);
                             }
                         }
                         return new XMLParserImpl();
@@ -149,18 +156,18 @@
      * @param rootNode
      * @param result
      * @param exclude
-     * @param com whether comments or not
+     * @param comments whether comments or not
      */
-    public static void getSet(Node rootNode, Set<Node> result, Node exclude, boolean com) {
+    public static void getSet(Node rootNode, Set<Node> result, Node exclude, boolean comments) {
         if (exclude != null && isDescendantOrSelf(exclude, rootNode)) {
             return;
         }
-        getSetRec(rootNode, result, exclude, com);
+        getSetRec(rootNode, result, exclude, comments);
     }
 
     @SuppressWarnings("fallthrough")
     private static void getSetRec(final Node rootNode, final Set<Node> result,
-                                final Node exclude, final boolean com) {
+                                final Node exclude, final boolean comments) {
         if (rootNode == exclude) {
             return;
         }
@@ -187,11 +194,11 @@
                         return;
                     }
                 }
-                getSetRec(r, result, exclude, com);
+                getSetRec(r, result, exclude, comments);
             }
             break;
         case Node.COMMENT_NODE:
-            if (com) {
+            if (comments) {
                 result.add(rootNode);
             }
             break;
@@ -202,6 +209,18 @@
         }
     }
 
+    /**
+     * Outputs a DOM tree to a {@link File}.
+     *
+     * @param contextNode root node of the DOM tree
+     * @param outputFile the file to write to
+     * @throws IOException
+     */
+    public static void outputDOM(Node contextNode, File outputFile) throws IOException {
+        try (OutputStream os = new BufferedOutputStream(Files.newOutputStream(outputFile.toPath()), 8192)) {
+            outputDOM(contextNode, os, false);
+        }
+    }
 
     /**
      * Outputs a DOM tree to an {@link OutputStream}.
@@ -210,7 +229,7 @@
      * @param os the {@link OutputStream}
      */
     public static void outputDOM(Node contextNode, OutputStream os) {
-        XMLUtils.outputDOM(contextNode, os, false);
+        outputDOM(contextNode, os, false);
     }
 
     /**
@@ -225,13 +244,12 @@
     public static void outputDOM(Node contextNode, OutputStream os, boolean addPreamble) {
         try {
             if (addPreamble) {
-                os.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n".getBytes(java.nio.charset.StandardCharsets.UTF_8));
+                os.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n".getBytes(UTF_8));
             }
-
             Canonicalizer.getInstance(
                 Canonicalizer.ALGO_ID_C14N_PHYSICAL).canonicalizeSubtree(contextNode, os);
         } catch (IOException | InvalidCanonicalizerException | CanonicalizationException ex) {
-            LOG.debug(ex.getMessage(), ex);
+            LOG.error(ex.getMessage(), ex);
         }
     }
 
@@ -253,7 +271,7 @@
             Canonicalizer.getInstance(
                 Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS).canonicalizeSubtree(contextNode, os);
         } catch (InvalidCanonicalizerException | CanonicalizationException ex) {
-            LOG.debug(ex.getMessage(), ex);
+            LOG.error(ex.getMessage(), ex);
             // throw new RuntimeException(ex.getMessage());
         }
     }
@@ -862,7 +880,7 @@
                                 // Continue searching to find duplicates
                                 foundElement = attr.getOwnerElement();
                             } else {
-                                LOG.debug("Multiple elements with the same 'Id' attribute value!");
+                                LOG.warn("Multiple elements with the same 'Id' attribute value!");
                                 return false;
                             }
                         }
@@ -921,8 +939,8 @@
                     int length = attributes.getLength();
                     for (int i = 0; i < length; i++) {
                         Attr attr = (Attr)attributes.item(i);
-                        if (attr.isId() && id.equals(attr.getValue()) && se != knownElement) {
-                            LOG.debug("Multiple elements with the same 'Id' attribute value!");
+                        if (attr.isId() && id.equals(attr.getValue()) && !knownElement.isSameNode(se)) {
+                            LOG.warn("Multiple elements with the same 'Id' attribute value!");
                             return false;
                         }
                     }
@@ -952,6 +970,49 @@
         return true;
     }
 
+    /**
+     * Reads a document from the input stream.
+     *
+     * @param file
+     * @param disallowDocTypeDeclarations
+     * @return {@link Document}
+     * @throws XMLParserException
+     * @throws IOException
+     */
+    public static Document read(File file, boolean disallowDocTypeDeclarations) throws XMLParserException, IOException {
+        try (InputStream inputStream = new BufferedInputStream(Files.newInputStream(file.toPath()), 8192)) {
+            return read(inputStream, disallowDocTypeDeclarations);
+        }
+    }
+
+    /**
+     * Reads a document from the input stream and closes it.
+     *
+     * @param name - resource name to be opened by the class loader
+     * @param loader
+     * @param disallowDocTypeDeclarations
+     * @return {@link Document}
+     * @throws XMLParserException
+     * @throws IOException inputStream.close() failed.
+     */
+    public static Document readResource(String name, ClassLoader loader, boolean disallowDocTypeDeclarations)
+        throws XMLParserException, IOException {
+        // Delegate to XMLParser implementation
+        try (InputStream inputStream = loader.getResourceAsStream(name)) {
+            return read(inputStream, disallowDocTypeDeclarations);
+        }
+
+    }
+
+    /**
+     * Reads a document from the input stream.
+     * Caller is responsible for closing the stream.
+     *
+     * @param inputStream
+     * @param disallowDocTypeDeclarations
+     * @return {@link Document}
+     * @throws XMLParserException
+     */
     public static Document read(InputStream inputStream, boolean disallowDocTypeDeclarations) throws XMLParserException {
         // Delegate to XMLParser implementation
         return xmlParserImpl.parse(inputStream, disallowDocTypeDeclarations);
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverDirectHTTP.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverDirectHTTP.java
index c1f9e19..deda69e 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverDirectHTTP.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverDirectHTTP.java
@@ -27,8 +27,8 @@
 import java.io.InputStream;
 import java.net.InetSocketAddress;
 import java.net.Proxy;
-import java.net.URISyntaxException;
 import java.net.URI;
+import java.net.URISyntaxException;
 import java.net.URL;
 import java.net.URLConnection;
 import java.nio.charset.StandardCharsets;
@@ -205,6 +205,7 @@
      * @param context
      * @return true if can be resolved
      */
+    @Override
     public boolean engineCanResolveURI(ResourceResolverContext context) {
         if (context.uriToResolve == null) {
             LOG.debug("quick fail, uri == null");
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverFragment.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverFragment.java
index 9af7ee1..4526a8a 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverFragment.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverFragment.java
@@ -110,6 +110,7 @@
      * {@inheritDoc}
      * @param context
      */
+    @Override
     public boolean engineCanResolveURI(ResourceResolverContext context) {
         if (context.uriToResolve == null) {
             LOG.debug("Quick fail for null uri");
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverLocalFilesystem.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverLocalFilesystem.java
index 9d7e00b..d3970a3 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverLocalFilesystem.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverLocalFilesystem.java
@@ -66,6 +66,7 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     public boolean engineCanResolveURI(ResourceResolverContext context) {
         if (context.uriToResolve == null) {
             return false;
diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverXPointer.java b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverXPointer.java
index c360880..fc0447e 100644
--- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverXPointer.java
+++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/utils/resolver/implementations/ResolverXPointer.java
@@ -104,6 +104,7 @@
     /**
      * {@inheritDoc}
      */
+    @Override
     public boolean engineCanResolveURI(ResourceResolverContext context) {
         return isXPointerSlash(context.uriToResolve) || isXPointerId(context.uriToResolve);
     }
diff --git a/src/java.xml.crypto/share/classes/javax/xml/crypto/dsig/DigestMethod.java b/src/java.xml.crypto/share/classes/javax/xml/crypto/dsig/DigestMethod.java
index e58c435..6f7525d 100644
--- a/src/java.xml.crypto/share/classes/javax/xml/crypto/dsig/DigestMethod.java
+++ b/src/java.xml.crypto/share/classes/javax/xml/crypto/dsig/DigestMethod.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -34,7 +34,7 @@
 
 /**
  * A representation of the XML <code>DigestMethod</code> element as
- * defined in the <a href="http://www.w3.org/TR/xmldsig-core/">
+ * defined in the <a href="https://www.w3.org/TR/xmldsig-core/">
  * W3C Recommendation for XML-Signature Syntax and Processing</a>.
  * The XML Schema Definition is defined as:
  * <pre>
@@ -59,8 +59,6 @@
  */
 public interface DigestMethod extends XMLStructure, AlgorithmMethod {
 
-    // All methods can be found in RFC 6931.
-
     /**
      * The <a href="http://www.w3.org/2000/09/xmldsig#sha1">
      * SHA1</a> digest method algorithm URI.
diff --git a/src/java.xml.crypto/share/classes/javax/xml/crypto/dsig/SignatureMethod.java b/src/java.xml.crypto/share/classes/javax/xml/crypto/dsig/SignatureMethod.java
index 5459045..3a567db 100644
--- a/src/java.xml.crypto/share/classes/javax/xml/crypto/dsig/SignatureMethod.java
+++ b/src/java.xml.crypto/share/classes/javax/xml/crypto/dsig/SignatureMethod.java
@@ -34,7 +34,7 @@
 
 /**
  * A representation of the XML <code>SignatureMethod</code> element
- * as defined in the <a href="http://www.w3.org/TR/xmldsig-core/">
+ * as defined in the <a href="https://www.w3.org/TR/xmldsig-core/">
  * W3C Recommendation for XML-Signature Syntax and Processing</a>.
  * The XML Schema Definition is defined as:
  * <pre>
@@ -52,6 +52,12 @@
  * A <code>SignatureMethod</code> instance may be created by invoking the
  * {@link XMLSignatureFactory#newSignatureMethod newSignatureMethod} method
  * of the {@link XMLSignatureFactory} class.
+ * <p>
+ * The signature method algorithm URIs defined in this class are specified
+ * in the <a href="https://www.w3.org/TR/xmldsig-core/">
+ * W3C Recommendation for XML-Signature Syntax and Processing</a>
+ * and <a href="https://www.rfc-editor.org/info/rfc9231">
+ * RFC 9231: Additional XML Security Uniform Resource Identifiers (URIs)</a>
  *
  * @author Sean Mullan
  * @author JSR 105 Expert Group
@@ -60,8 +66,6 @@
  */
 public interface SignatureMethod extends XMLStructure, AlgorithmMethod {
 
-    // All methods can be found in RFC 6931.
-
     /**
      * The <a href="http://www.w3.org/2000/09/xmldsig#dsa-sha1">DSA-SHA1</a>
      * (DSS) signature method algorithm URI.
@@ -255,6 +259,7 @@
      */
     String RSA_PSS = "http://www.w3.org/2007/05/xmldsig-more#rsa-pss";
 
+
     /**
      * Returns the algorithm-specific input parameters of this
      * <code>SignatureMethod</code>.
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/DigesterOutputStream.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/DigesterOutputStream.java
index 774eb36..3b03dc8 100644
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/DigesterOutputStream.java
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/DigesterOutputStream.java
@@ -71,6 +71,7 @@
         }
     }
 
+    @Override
     public void write(int input) {
         if (buffer) {
             bos.write(input);
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/MacOutputStream.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/MacOutputStream.java
index be55430..727b3b9 100644
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/MacOutputStream.java
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/MacOutputStream.java
@@ -23,6 +23,7 @@
 package org.jcp.xml.dsig.internal;
 
 import java.io.ByteArrayOutputStream;
+
 import javax.crypto.Mac;
 
 /**
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/AbstractDOMSignatureMethod.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/AbstractDOMSignatureMethod.java
index 8ff9fc7..75b21c1 100644
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/AbstractDOMSignatureMethod.java
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/AbstractDOMSignatureMethod.java
@@ -23,20 +23,22 @@
 
 package org.jcp.xml.dsig.internal.dom;
 
-import java.security.Key;
 import java.security.InvalidAlgorithmParameterException;
 import java.security.InvalidKeyException;
+import java.security.Key;
 import java.security.SignatureException;
 import java.security.spec.AlgorithmParameterSpec;
+
 import javax.xml.crypto.MarshalException;
 import javax.xml.crypto.dom.DOMCryptoContext;
 import javax.xml.crypto.dsig.SignatureMethod;
 import javax.xml.crypto.dsig.SignedInfo;
+import javax.xml.crypto.dsig.XMLSignContext;
 import javax.xml.crypto.dsig.XMLSignature;
 import javax.xml.crypto.dsig.XMLSignatureException;
-import javax.xml.crypto.dsig.XMLSignContext;
 import javax.xml.crypto.dsig.XMLValidateContext;
 import javax.xml.crypto.dsig.spec.SignatureMethodParameterSpec;
+
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
@@ -49,7 +51,7 @@
     implements SignatureMethod {
 
     // denotes the type of signature algorithm
-    enum Type { DSA, RSA, ECDSA, HMAC }
+    enum Type { DSA, RSA, ECDSA, EDDSA, HMAC }
 
     /**
      * Verifies the passed-in signature with the specified key, using the
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheCanonicalizer.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheCanonicalizer.java
index 7655866..5dff44e 100644
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheCanonicalizer.java
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheCanonicalizer.java
@@ -28,11 +28,16 @@
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.OutputStream;
-import java.security.spec.AlgorithmParameterSpec;
 import java.security.InvalidAlgorithmParameterException;
+import java.security.spec.AlgorithmParameterSpec;
 import java.util.Set;
 
-import javax.xml.crypto.*;
+import javax.xml.crypto.Data;
+import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.NodeSetData;
+import javax.xml.crypto.OctetStreamData;
+import javax.xml.crypto.XMLCryptoContext;
+import javax.xml.crypto.XMLStructure;
 import javax.xml.crypto.dom.DOMCryptoContext;
 import javax.xml.crypto.dsig.TransformException;
 import javax.xml.crypto.dsig.TransformService;
@@ -61,11 +66,13 @@
     protected Document ownerDoc;
     protected Element transformElem;
 
+    @Override
     public final AlgorithmParameterSpec getParameterSpec()
     {
         return params;
     }
 
+    @Override
     public void init(XMLStructure parent, XMLCryptoContext context)
         throws InvalidAlgorithmParameterException
     {
@@ -84,6 +91,7 @@
         ownerDoc = DOMUtils.getOwnerDocument(transformElem);
     }
 
+    @Override
     public void marshalParams(XMLStructure parent, XMLCryptoContext context)
         throws MarshalException
     {
@@ -182,6 +190,7 @@
         return null;
     }
 
+    @Override
     public Data transform(Data data, XMLCryptoContext xc, OutputStream os)
         throws TransformException
     {
@@ -249,6 +258,7 @@
         }
     }
 
+    @Override
     public final boolean isFeatureSupported(String feature) {
         if (feature == null) {
             throw new NullPointerException();
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheData.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheData.java
index 109309d..0515066 100644
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheData.java
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheData.java
@@ -26,6 +26,7 @@
 package org.jcp.xml.dsig.internal.dom;
 
 import javax.xml.crypto.Data;
+
 import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
 
 /**
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheNodeSetData.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheNodeSetData.java
index 2ee5777..a59e41c 100644
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheNodeSetData.java
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheNodeSetData.java
@@ -30,11 +30,14 @@
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Set;
+
 import javax.xml.crypto.NodeSetData;
-import org.w3c.dom.Node;
+
 import com.sun.org.apache.xml.internal.security.signature.NodeFilter;
 import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
+import com.sun.org.apache.xml.internal.security.transforms.TransformationException;
 import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
+import org.w3c.dom.Node;
 
 public class ApacheNodeSetData implements ApacheData, NodeSetData<Node> {
 
@@ -44,13 +47,14 @@
         this.xi = xi;
     }
 
+    @Override
     public Iterator<Node> iterator() {
         // If nodefilters are set, must execute them first to create node-set
-        if (xi.getNodeFilters() != null && !xi.getNodeFilters().isEmpty()) {
-            return Collections.unmodifiableSet
-                (getNodeSet(xi.getNodeFilters())).iterator();
-        }
         try {
+            if (xi.getNodeFilters() != null && !xi.getNodeFilters().isEmpty()) {
+                return Collections.unmodifiableSet
+                        (getNodeSet(xi.getNodeFilters())).iterator();
+            }
             return Collections.unmodifiableSet(xi.getNodeSet()).iterator();
         } catch (Exception e) {
             // should not occur
@@ -59,11 +63,13 @@
         }
     }
 
+    @Override
     public XMLSignatureInput getXMLSignatureInput() {
         return xi;
     }
 
-    private Set<Node> getNodeSet(List<NodeFilter> nodeFilters) {
+    private Set<Node> getNodeSet(List<NodeFilter> nodeFilters)
+            throws TransformationException {
         if (xi.isNeedsToBeExpanded()) {
             XMLUtils.circumventBug2650
                 (XMLUtils.getOwnerDocument(xi.getSubNode()));
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheOctetStreamData.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheOctetStreamData.java
index f00bb80..9b919fc 100644
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheOctetStreamData.java
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheOctetStreamData.java
@@ -26,7 +26,9 @@
 package org.jcp.xml.dsig.internal.dom;
 
 import java.io.IOException;
+
 import javax.xml.crypto.OctetStreamData;
+
 import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
 
 public class ApacheOctetStreamData extends OctetStreamData
@@ -41,6 +43,7 @@
         this.xi = xi;
     }
 
+    @Override
     public XMLSignatureInput getXMLSignatureInput() {
         return xi;
     }
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheTransform.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheTransform.java
index 2521192..2efbcb8 100644
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheTransform.java
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/ApacheTransform.java
@@ -30,16 +30,25 @@
 import java.security.spec.AlgorithmParameterSpec;
 import java.util.Set;
 
+
+import javax.xml.crypto.Data;
+import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.NodeSetData;
+import javax.xml.crypto.OctetStreamData;
+import javax.xml.crypto.XMLCryptoContext;
+import javax.xml.crypto.XMLStructure;
+import javax.xml.crypto.dom.DOMCryptoContext;
+import javax.xml.crypto.dsig.TransformException;
+import javax.xml.crypto.dsig.TransformService;
+import javax.xml.crypto.dsig.spec.TransformParameterSpec;
+
+import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
+import com.sun.org.apache.xml.internal.security.transforms.Transform;
+import com.sun.org.apache.xml.internal.security.transforms.Transforms;
+
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
-import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
-import com.sun.org.apache.xml.internal.security.transforms.Transform;
-
-import javax.xml.crypto.*;
-import javax.xml.crypto.dom.DOMCryptoContext;
-import javax.xml.crypto.dsig.*;
-import javax.xml.crypto.dsig.spec.TransformParameterSpec;
 
 /**
  * This is a wrapper/glue class which invokes the Apache XML-Security
@@ -64,6 +73,7 @@
         return params;
     }
 
+    @Override
     public void init(XMLStructure parent, XMLCryptoContext context)
         throws InvalidAlgorithmParameterException
     {
@@ -82,6 +92,7 @@
         ownerDoc = DOMUtils.getOwnerDocument(transformElem);
     }
 
+    @Override
     public void marshalParams(XMLStructure parent, XMLCryptoContext context)
         throws MarshalException
     {
@@ -100,6 +111,7 @@
         ownerDoc = DOMUtils.getOwnerDocument(transformElem);
     }
 
+    @Override
     public Data transform(Data data, XMLCryptoContext xc)
         throws TransformException
     {
@@ -109,6 +121,7 @@
         return transformIt(data, xc, null);
     }
 
+    @Override
     public Data transform(Data data, XMLCryptoContext xc, OutputStream os)
         throws TransformException
     {
@@ -197,6 +210,7 @@
         }
     }
 
+    @Override
     public final boolean isFeatureSupported(String feature) {
         if (feature == null) {
             throw new NullPointerException();
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMCanonicalXMLC14N11Method.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMCanonicalXMLC14N11Method.java
index 1c6c192..4ea74c6 100644
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMCanonicalXMLC14N11Method.java
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMCanonicalXMLC14N11Method.java
@@ -25,12 +25,13 @@
  */
 package org.jcp.xml.dsig.internal.dom;
 
-import javax.xml.crypto.*;
-import javax.xml.crypto.dsig.*;
-import javax.xml.crypto.dsig.spec.TransformParameterSpec;
-
 import java.security.InvalidAlgorithmParameterException;
 
+import javax.xml.crypto.Data;
+import javax.xml.crypto.XMLCryptoContext;
+import javax.xml.crypto.dsig.TransformException;
+import javax.xml.crypto.dsig.spec.TransformParameterSpec;
+
 import com.sun.org.apache.xml.internal.security.c14n.Canonicalizer;
 import com.sun.org.apache.xml.internal.security.c14n.InvalidCanonicalizerException;
 
@@ -45,6 +46,7 @@
     public static final String C14N_11_WITH_COMMENTS
         = "http://www.w3.org/2006/12/xml-c14n11#WithComments";
 
+    @Override
     public void init(TransformParameterSpec params)
         throws InvalidAlgorithmParameterException {
         if (params != null) {
@@ -53,6 +55,7 @@
         }
     }
 
+    @Override
     public Data transform(Data data, XMLCryptoContext xc)
         throws TransformException {
 
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMCanonicalXMLC14NMethod.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMCanonicalXMLC14NMethod.java
index e2d524b..4b60015 100644
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMCanonicalXMLC14NMethod.java
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMCanonicalXMLC14NMethod.java
@@ -25,12 +25,14 @@
  */
 package org.jcp.xml.dsig.internal.dom;
 
-import javax.xml.crypto.*;
-import javax.xml.crypto.dsig.*;
-import javax.xml.crypto.dsig.spec.TransformParameterSpec;
-
 import java.security.InvalidAlgorithmParameterException;
 
+import javax.xml.crypto.Data;
+import javax.xml.crypto.XMLCryptoContext;
+import javax.xml.crypto.dsig.CanonicalizationMethod;
+import javax.xml.crypto.dsig.TransformException;
+import javax.xml.crypto.dsig.spec.TransformParameterSpec;
+
 import com.sun.org.apache.xml.internal.security.c14n.Canonicalizer;
 import com.sun.org.apache.xml.internal.security.c14n.InvalidCanonicalizerException;
 
@@ -41,6 +43,7 @@
  */
 public final class DOMCanonicalXMLC14NMethod extends ApacheCanonicalizer {
 
+    @Override
     public void init(TransformParameterSpec params)
         throws InvalidAlgorithmParameterException {
         if (params != null) {
@@ -49,6 +52,7 @@
         }
     }
 
+    @Override
     public Data transform(Data data, XMLCryptoContext xc)
         throws TransformException {
 
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMCanonicalizationMethod.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMCanonicalizationMethod.java
index ecef17f..c182a22 100644
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMCanonicalizationMethod.java
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMCanonicalizationMethod.java
@@ -33,10 +33,14 @@
 import java.util.HashSet;
 import java.util.Set;
 
-import org.w3c.dom.Element;
+import javax.xml.crypto.Data;
+import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.XMLCryptoContext;
+import javax.xml.crypto.dsig.CanonicalizationMethod;
+import javax.xml.crypto.dsig.TransformException;
+import javax.xml.crypto.dsig.TransformService;
 
-import javax.xml.crypto.*;
-import javax.xml.crypto.dsig.*;
+import org.w3c.dom.Element;
 
 /**
  * DOM-based abstract implementation of CanonicalizationMethod.
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMCryptoBinary.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMCryptoBinary.java
index 9a81a21..1b12481 100644
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMCryptoBinary.java
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMCryptoBinary.java
@@ -26,7 +26,8 @@
 package org.jcp.xml.dsig.internal.dom;
 
 import java.math.BigInteger;
-import javax.xml.crypto.*;
+
+import javax.xml.crypto.MarshalException;
 import javax.xml.crypto.dom.DOMCryptoContext;
 
 import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMDigestMethod.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMDigestMethod.java
index a4d5fea..259c7a9 100644
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMDigestMethod.java
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMDigestMethod.java
@@ -25,13 +25,15 @@
  */
 package org.jcp.xml.dsig.internal.dom;
 
-import javax.xml.crypto.*;
-import javax.xml.crypto.dom.DOMCryptoContext;
-import javax.xml.crypto.dsig.*;
-import javax.xml.crypto.dsig.spec.DigestMethodParameterSpec;
-
 import java.security.InvalidAlgorithmParameterException;
 import java.security.spec.AlgorithmParameterSpec;
+
+import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.dom.DOMCryptoContext;
+import javax.xml.crypto.dsig.DigestMethod;
+import javax.xml.crypto.dsig.XMLSignature;
+import javax.xml.crypto.dsig.spec.DigestMethodParameterSpec;
+
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
@@ -147,6 +149,7 @@
         }
     }
 
+    @Override
     public final AlgorithmParameterSpec getParameterSpec() {
         return params;
     }
@@ -251,9 +254,11 @@
         SHA1(Element dmElem) throws MarshalException {
             super(dmElem);
         }
+        @Override
         public String getAlgorithm() {
             return DigestMethod.SHA1;
         }
+        @Override
         String getMessageDigestAlgorithm() {
             return "SHA-1";
         }
@@ -285,9 +290,11 @@
         SHA256(Element dmElem) throws MarshalException {
             super(dmElem);
         }
+        @Override
         public String getAlgorithm() {
             return DigestMethod.SHA256;
         }
+        @Override
         String getMessageDigestAlgorithm() {
             return "SHA-256";
         }
@@ -301,9 +308,11 @@
         SHA384(Element dmElem) throws MarshalException {
             super(dmElem);
         }
+        @Override
         public String getAlgorithm() {
             return SHA384;
         }
+        @Override
         String getMessageDigestAlgorithm() {
             return "SHA-384";
         }
@@ -317,9 +326,11 @@
         SHA512(Element dmElem) throws MarshalException {
             super(dmElem);
         }
+        @Override
         public String getAlgorithm() {
             return DigestMethod.SHA512;
         }
+        @Override
         String getMessageDigestAlgorithm() {
             return "SHA-512";
         }
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMEnvelopedTransform.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMEnvelopedTransform.java
index a43cb81..9a0ba0b 100644
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMEnvelopedTransform.java
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMEnvelopedTransform.java
@@ -26,6 +26,7 @@
 package org.jcp.xml.dsig.internal.dom;
 
 import java.security.InvalidAlgorithmParameterException;
+
 import javax.xml.crypto.dsig.spec.TransformParameterSpec;
 
 /**
@@ -35,6 +36,7 @@
  */
 public final class DOMEnvelopedTransform extends ApacheTransform {
 
+    @Override
     public void init(TransformParameterSpec params)
         throws InvalidAlgorithmParameterException {
         if (params != null) {
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMExcC14NMethod.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMExcC14NMethod.java
index a8cd434..0490e78 100644
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMExcC14NMethod.java
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMExcC14NMethod.java
@@ -25,19 +25,24 @@
  */
 package org.jcp.xml.dsig.internal.dom;
 
-import javax.xml.crypto.*;
-import javax.xml.crypto.dsig.*;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.spec.AlgorithmParameterSpec;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.crypto.Data;
+import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.XMLCryptoContext;
+import javax.xml.crypto.XMLStructure;
+import javax.xml.crypto.dsig.CanonicalizationMethod;
+import javax.xml.crypto.dsig.TransformException;
 import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
 import javax.xml.crypto.dsig.spec.ExcC14NParameterSpec;
 import javax.xml.crypto.dsig.spec.TransformParameterSpec;
 
-import java.security.InvalidAlgorithmParameterException;
-import java.security.spec.AlgorithmParameterSpec;
-import java.util.*;
-
-import org.w3c.dom.Element;
 import com.sun.org.apache.xml.internal.security.c14n.Canonicalizer;
 import com.sun.org.apache.xml.internal.security.c14n.InvalidCanonicalizerException;
+import org.w3c.dom.Element;
 
 /**
  * DOM-based implementation of CanonicalizationMethod for Exclusive
@@ -47,6 +52,7 @@
  */
 public final class DOMExcC14NMethod extends ApacheCanonicalizer {
 
+    @Override
     public void init(TransformParameterSpec params)
         throws InvalidAlgorithmParameterException
     {
@@ -59,6 +65,7 @@
         }
     }
 
+    @Override
     public void init(XMLStructure parent, XMLCryptoContext context)
         throws InvalidAlgorithmParameterException
     {
@@ -137,6 +144,7 @@
         return CanonicalizationMethod.EXCLUSIVE;
     }
 
+    @Override
     public Data transform(Data data, XMLCryptoContext xc)
         throws TransformException
     {
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMHMACSignatureMethod.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMHMACSignatureMethod.java
index 40bb99c..0a9ef18 100644
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMHMACSignatureMethod.java
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMHMACSignatureMethod.java
@@ -25,11 +25,6 @@
  */
 package org.jcp.xml.dsig.internal.dom;
 
-import javax.xml.crypto.*;
-import javax.xml.crypto.dsig.*;
-import javax.xml.crypto.dsig.spec.HMACParameterSpec;
-import javax.xml.crypto.dsig.spec.SignatureMethodParameterSpec;
-
 import java.security.InvalidAlgorithmParameterException;
 import java.security.InvalidKeyException;
 import java.security.Key;
@@ -38,12 +33,22 @@
 import java.security.Provider;
 import java.security.SignatureException;
 import java.security.spec.AlgorithmParameterSpec;
+
 import javax.crypto.Mac;
 import javax.crypto.SecretKey;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
+import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.dsig.SignatureMethod;
+import javax.xml.crypto.dsig.SignedInfo;
+import javax.xml.crypto.dsig.XMLSignContext;
+import javax.xml.crypto.dsig.XMLSignature;
+import javax.xml.crypto.dsig.XMLSignatureException;
+import javax.xml.crypto.dsig.XMLValidateContext;
+import javax.xml.crypto.dsig.spec.HMACParameterSpec;
+import javax.xml.crypto.dsig.spec.SignatureMethodParameterSpec;
 
 import org.jcp.xml.dsig.internal.MacOutputStream;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
 
 /**
  * DOM-based implementation of HMAC SignatureMethod.
@@ -118,10 +123,12 @@
         }
     }
 
+    @Override
     public final AlgorithmParameterSpec getParameterSpec() {
         return params;
     }
 
+    @Override
     SignatureMethodParameterSpec unmarshalParams(Element paramsElem)
         throws MarshalException
     {
@@ -135,6 +142,7 @@
         return new HMACParameterSpec(outputLength);
     }
 
+    @Override
     void marshalParams(Element parent, String prefix)
         throws MarshalException
     {
@@ -147,6 +155,7 @@
         parent.appendChild(hmacElem);
     }
 
+    @Override
     boolean verify(Key key, SignedInfo si, byte[] sig,
                    XMLValidateContext context)
         throws InvalidKeyException, SignatureException, XMLSignatureException
@@ -178,6 +187,7 @@
         return MessageDigest.isEqual(sig, result);
     }
 
+    @Override
     byte[] sign(Key key, SignedInfo si, XMLSignContext context)
         throws InvalidKeyException, XMLSignatureException
     {
@@ -206,6 +216,7 @@
         return hmac.doFinal();
     }
 
+    @Override
     boolean paramsEqual(AlgorithmParameterSpec spec) {
         if (getParameterSpec() == spec) {
             return true;
@@ -218,6 +229,7 @@
         return outputLength == ospec.getOutputLength();
     }
 
+    @Override
     Type getAlgorithmType() {
         return Type.HMAC;
     }
@@ -235,12 +247,15 @@
         SHA1(Element dmElem) throws MarshalException {
             super(dmElem);
         }
+        @Override
         public String getAlgorithm() {
             return SignatureMethod.HMAC_SHA1;
         }
+        @Override
         String getJCAAlgorithm() {
             return "HmacSHA1";
         }
+        @Override
         int getDigestLength() {
             return 160;
         }
@@ -276,12 +291,15 @@
         SHA256(Element dmElem) throws MarshalException {
             super(dmElem);
         }
+        @Override
         public String getAlgorithm() {
             return HMAC_SHA256;
         }
+        @Override
         String getJCAAlgorithm() {
             return "HmacSHA256";
         }
+        @Override
         int getDigestLength() {
             return 256;
         }
@@ -295,12 +313,15 @@
         SHA384(Element dmElem) throws MarshalException {
             super(dmElem);
         }
+        @Override
         public String getAlgorithm() {
             return HMAC_SHA384;
         }
+        @Override
         String getJCAAlgorithm() {
             return "HmacSHA384";
         }
+        @Override
         int getDigestLength() {
             return 384;
         }
@@ -314,12 +335,15 @@
         SHA512(Element dmElem) throws MarshalException {
             super(dmElem);
         }
+        @Override
         public String getAlgorithm() {
             return HMAC_SHA512;
         }
+        @Override
         String getJCAAlgorithm() {
             return "HmacSHA512";
         }
+        @Override
         int getDigestLength() {
             return 512;
         }
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyInfo.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyInfo.java
index 19cedaf..d13b47c 100644
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyInfo.java
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyInfo.java
@@ -141,14 +141,17 @@
         keyInfoTypes = Collections.unmodifiableList(content);
     }
 
+    @Override
     public String getId() {
         return id;
     }
 
+    @Override
     public List<XMLStructure> getContent() {
         return keyInfoTypes;
     }
 
+    @Override
     public void marshal(XMLStructure parent, XMLCryptoContext context)
         throws MarshalException
     {
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyInfoFactory.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyInfoFactory.java
index 99ca1dc..cec1224 100644
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyInfoFactory.java
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyInfoFactory.java
@@ -28,8 +28,8 @@
 import java.math.BigInteger;
 import java.security.KeyException;
 import java.security.PublicKey;
-import java.security.interfaces.ECPublicKey;
 import java.security.interfaces.DSAPublicKey;
+import java.security.interfaces.ECPublicKey;
 import java.security.interfaces.RSAPublicKey;
 import java.util.List;
 
@@ -59,20 +59,24 @@
 
     public DOMKeyInfoFactory() { }
 
+    @Override
     @SuppressWarnings("rawtypes")
     public KeyInfo newKeyInfo(List content) {
         return newKeyInfo(content, null);
     }
 
+    @Override
     @SuppressWarnings({ "unchecked", "rawtypes" })
     public KeyInfo newKeyInfo(List content, String id) {
         return new DOMKeyInfo(content, id);
     }
 
+    @Override
     public KeyName newKeyName(String name) {
         return new DOMKeyName(name);
     }
 
+    @Override
     public KeyValue newKeyValue(PublicKey key)  throws KeyException {
         String algorithm = key.getAlgorithm();
         if ("DSA".equals(algorithm)) {
@@ -86,24 +90,29 @@
         }
     }
 
+    @Override
     public PGPData newPGPData(byte[] keyId) {
         return newPGPData(keyId, null, null);
     }
 
+    @Override
     @SuppressWarnings({ "rawtypes", "unchecked" })
     public PGPData newPGPData(byte[] keyId, byte[] keyPacket, List other) {
         return new DOMPGPData(keyId, keyPacket, other);
     }
 
+    @Override
     @SuppressWarnings({ "rawtypes", "unchecked" })
     public PGPData newPGPData(byte[] keyPacket, List other) {
         return new DOMPGPData(keyPacket, other);
     }
 
+    @Override
     public RetrievalMethod newRetrievalMethod(String uri) {
         return newRetrievalMethod(uri, null, null);
     }
 
+    @Override
     @SuppressWarnings({ "rawtypes", "unchecked" })
     public RetrievalMethod newRetrievalMethod(String uri, String type,
         List transforms) {
@@ -113,6 +122,7 @@
         return new DOMRetrievalMethod(uri, type, transforms);
     }
 
+    @Override
     @SuppressWarnings({ "rawtypes" })
     public X509Data newX509Data(List content) {
         return new DOMX509Data(content);
@@ -124,6 +134,7 @@
         return new DOMX509IssuerSerial(issuerName, serialNumber);
     }
 
+    @Override
     public boolean isFeatureSupported(String feature) {
         if (feature == null) {
             throw new NullPointerException();
@@ -132,6 +143,7 @@
         }
     }
 
+    @Override
     public URIDereferencer getURIDereferencer() {
         return DOMURIDereferencer.INSTANCE;
     }
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyName.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyName.java
index 888a9c7..3c83e48 100644
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyName.java
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyName.java
@@ -64,6 +64,7 @@
         name = knElem.getFirstChild().getNodeValue();
     }
 
+    @Override
     public String getName() {
         return name;
     }
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyValue.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyValue.java
index 307d0ae..0933c21 100644
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyValue.java
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMKeyValue.java
@@ -101,6 +101,7 @@
         }
     }
 
+    @Override
     public PublicKey getPublicKey() throws KeyException {
         if (publicKey == null) {
             throw new KeyException("can't convert KeyValue to PublicKey");
@@ -198,6 +199,7 @@
             super(elem);
         }
 
+        @Override
         void marshalPublicKey(Node parent, Document doc, String dsPrefix,
             DOMCryptoContext context) throws MarshalException {
             Element rsaElem = DOMUtils.createElement(doc, "RSAKeyValue",
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMManifest.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMManifest.java
index be65eb8..6ed7ee8 100644
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMManifest.java
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMManifest.java
@@ -25,12 +25,17 @@
  */
 package org.jcp.xml.dsig.internal.dom;
 
-import javax.xml.crypto.*;
-import javax.xml.crypto.dom.DOMCryptoContext;
-import javax.xml.crypto.dsig.*;
-
 import java.security.Provider;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.XMLCryptoContext;
+import javax.xml.crypto.dom.DOMCryptoContext;
+import javax.xml.crypto.dsig.Manifest;
+import javax.xml.crypto.dsig.Reference;
+import javax.xml.crypto.dsig.XMLSignature;
 
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -114,6 +119,7 @@
         this.references = Collections.unmodifiableList(refs);
     }
 
+    @Override
     public String getId() {
         return id;
     }
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMPGPData.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMPGPData.java
index f9802c4..df591ce 100644
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMPGPData.java
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMPGPData.java
@@ -25,19 +25,21 @@
  */
 package org.jcp.xml.dsig.internal.dom;
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 
-import javax.xml.crypto.*;
+import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.XMLStructure;
 import javax.xml.crypto.dom.DOMCryptoContext;
 import javax.xml.crypto.dsig.XMLSignature;
 import javax.xml.crypto.dsig.keyinfo.PGPData;
 
+import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 
-import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
-
 /**
  * DOM-based implementation of PGPData.
  *
@@ -171,14 +173,17 @@
         this.externalElements = Collections.unmodifiableList(other);
     }
 
+    @Override
     public byte[] getKeyId() {
         return keyId == null ? null : keyId.clone();
     }
 
+    @Override
     public byte[] getKeyPacket() {
         return keyPacket == null ? null : keyPacket.clone();
     }
 
+    @Override
     public List<XMLStructure> getExternalElements() {
         return externalElements;
     }
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMRSAPSSSignatureMethod.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMRSAPSSSignatureMethod.java
index 88bf38a..c131ab6 100644
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMRSAPSSSignatureMethod.java
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMRSAPSSSignatureMethod.java
@@ -25,25 +25,33 @@
  */
 package org.jcp.xml.dsig.internal.dom;
 
-import javax.xml.crypto.*;
-import javax.xml.crypto.dsig.*;
-import javax.xml.crypto.dsig.spec.RSAPSSParameterSpec;
-import javax.xml.crypto.dsig.spec.SignatureMethodParameterSpec;
-
 import java.io.IOException;
-import java.security.*;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.SignatureException;
 import java.security.spec.AlgorithmParameterSpec;
 import java.security.spec.MGF1ParameterSpec;
 import java.security.spec.PSSParameterSpec;
 
-import org.w3c.dom.DOMException;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Text;
+import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.dsig.*;
+import javax.xml.crypto.dsig.spec.RSAPSSParameterSpec;
+import javax.xml.crypto.dsig.spec.SignatureMethodParameterSpec;
+
 import org.jcp.xml.dsig.internal.SignerOutputStream;
 import com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureBaseRSA.SignatureRSASSAPSS.DigestAlgorithm;
 import com.sun.org.apache.xml.internal.security.utils.Constants;
 import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Text;
 
 /**
  * DOM-based abstract implementation of SignatureMethod for RSA-PSS.
@@ -125,10 +133,12 @@
         LOG.debug("Setting RSAPSSParameterSpec to: {}", params.toString());
     }
 
+    @Override
     public final AlgorithmParameterSpec getParameterSpec() {
         return params;
     }
 
+    @Override
     void marshalParams(Element parent, String prefix)
         throws MarshalException
     {
@@ -203,6 +213,7 @@
         }
     }
 
+    @Override
     SignatureMethodParameterSpec unmarshalParams(Element paramsElem)
         throws MarshalException
     {
@@ -250,6 +261,7 @@
         return DEFAULT_PSS_SPEC;
     }
 
+    @Override
     boolean verify(Key key, SignedInfo si, byte[] sig,
                    XMLValidateContext context)
         throws InvalidKeyException, SignatureException, XMLSignatureException
@@ -291,6 +303,7 @@
         }
     }
 
+    @Override
     byte[] sign(Key key, SignedInfo si, XMLSignContext context)
         throws InvalidKeyException, XMLSignatureException
     {
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMReference.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMReference.java
index d278808..6921534 100644
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMReference.java
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMReference.java
@@ -32,27 +32,51 @@
  */
 package org.jcp.xml.dsig.internal.dom;
 
-import javax.xml.crypto.*;
-import javax.xml.crypto.dsig.*;
-import javax.xml.crypto.dom.DOMCryptoContext;
-import javax.xml.crypto.dom.DOMURIReference;
-
-import java.io.*;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.net.URI;
 import java.net.URISyntaxException;
-import java.security.*;
-import java.util.*;
+import java.security.AccessController;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivilegedAction;
+import java.security.Provider;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
 
-import org.w3c.dom.Attr;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-
-import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
+import javax.xml.crypto.Data;
+import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.NodeSetData;
+import javax.xml.crypto.OctetStreamData;
+import javax.xml.crypto.URIDereferencer;
+import javax.xml.crypto.URIReferenceException;
+import javax.xml.crypto.XMLCryptoContext;
+import javax.xml.crypto.dom.DOMCryptoContext;
+import javax.xml.crypto.dom.DOMURIReference;
+import javax.xml.crypto.dsig.CanonicalizationMethod;
+import javax.xml.crypto.dsig.DigestMethod;
+import javax.xml.crypto.dsig.Reference;
+import javax.xml.crypto.dsig.Transform;
+import javax.xml.crypto.dsig.TransformException;
+import javax.xml.crypto.dsig.TransformService;
+import javax.xml.crypto.dsig.XMLSignContext;
+import javax.xml.crypto.dsig.XMLSignature;
+import javax.xml.crypto.dsig.XMLSignatureException;
+import javax.xml.crypto.dsig.XMLValidateContext;
 
 import org.jcp.xml.dsig.internal.DigesterOutputStream;
 import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
 import com.sun.org.apache.xml.internal.security.utils.UnsyncBufferedOutputStream;
+import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
 
 /**
  * DOM-based implementation of Reference.
@@ -270,30 +294,37 @@
         this.provider = provider;
     }
 
+    @Override
     public DigestMethod getDigestMethod() {
         return digestMethod;
     }
 
+    @Override
     public String getId() {
         return id;
     }
 
+    @Override
     public String getURI() {
         return uri;
     }
 
+    @Override
     public String getType() {
         return type;
     }
 
+    @Override
     public List<Transform> getTransforms() {
         return Collections.unmodifiableList(allTransforms);
     }
 
+    @Override
     public byte[] getDigestValue() {
         return digestValue == null ? null : digestValue.clone();
     }
 
+    @Override
     public byte[] getCalculatedDigestValue() {
         return calcDigestValue == null ? null
                                         : calcDigestValue.clone();
@@ -372,6 +403,7 @@
         LOG.debug("Reference digesting completed");
     }
 
+    @Override
     public boolean validate(XMLValidateContext validateContext)
         throws XMLSignatureException
     {
@@ -394,10 +426,12 @@
         return validationStatus;
     }
 
+    @Override
     public Data getDereferencedData() {
         return derefData;
     }
 
+    @Override
     public InputStream getDigestInputStream() {
         return dis;
     }
@@ -568,6 +602,7 @@
         }
     }
 
+    @Override
     public Node getHere() {
         return here;
     }
@@ -631,6 +666,7 @@
                 try {
                     final Set<Node> s = xsi.getNodeSet();
                     return new NodeSetData<Node>() {
+                        @Override
                         public Iterator<Node> iterator() { return s.iterator(); }
                     };
                 } catch (Exception e) {
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMRetrievalMethod.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMRetrievalMethod.java
index 3334380..e5c92e8 100644
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMRetrievalMethod.java
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMRetrievalMethod.java
@@ -176,14 +176,17 @@
         }
     }
 
+    @Override
     public String getURI() {
         return uri;
     }
 
+    @Override
     public String getType() {
         return type;
     }
 
+    @Override
     public List<Transform> getTransforms() {
         return transforms;
     }
@@ -219,10 +222,12 @@
         here = rmElem.getAttributeNodeNS(null, "URI");
     }
 
+    @Override
     public Node getHere() {
         return here;
     }
 
+    @Override
     public Data dereference(XMLCryptoContext context)
         throws URIReferenceException
     {
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureMethod.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureMethod.java
index 12f9233..5e44cca 100644
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureMethod.java
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureMethod.java
@@ -25,23 +25,36 @@
  */
 package org.jcp.xml.dsig.internal.dom;
 
-import javax.xml.crypto.*;
-import javax.xml.crypto.dsig.*;
-import javax.xml.crypto.dsig.spec.SignatureMethodParameterSpec;
-
 import java.io.IOException;
-import java.security.*;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.Provider;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.SignatureException;
 import java.security.interfaces.DSAKey;
 import java.security.interfaces.ECPrivateKey;
 import java.security.spec.AlgorithmParameterSpec;
 import java.security.spec.MGF1ParameterSpec;
 import java.security.spec.PSSParameterSpec;
 
-import org.w3c.dom.Element;
+import javax.xml.crypto.XMLCryptoContext;
+import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.dsig.SignatureMethod;
+import javax.xml.crypto.dsig.SignedInfo;
+import javax.xml.crypto.dsig.XMLSignContext;
+import javax.xml.crypto.dsig.XMLSignatureException;
+import javax.xml.crypto.dsig.XMLValidateContext;
+import javax.xml.crypto.dsig.spec.SignatureMethodParameterSpec;
 
+import org.jcp.xml.dsig.internal.SignerOutputStream;
 import com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureECDSA;
 import com.sun.org.apache.xml.internal.security.utils.JavaUtils;
-import org.jcp.xml.dsig.internal.SignerOutputStream;
+import org.w3c.dom.Element;
+
 import sun.security.util.KeyUtil;
 
 /**
@@ -82,6 +95,12 @@
     static final String DSA_SHA256 =
         "http://www.w3.org/2009/xmldsig11#dsa-sha256";
 
+    // see RFC 9231 for these algorithm definitions
+    static final String ED25519 =
+        "http://www.w3.org/2021/04/xmldsig-more#eddsa-ed25519";
+    static final String ED448 =
+        "http://www.w3.org/2021/04/xmldsig-more#eddsa-ed448";
+
     // see RFC 6931 for these algorithm definitions
     static final String ECDSA_RIPEMD160 =
         "http://www.w3.org/2007/05/xmldsig-more#ecdsa-ripemd160";
@@ -97,6 +116,14 @@
         "http://www.w3.org/2007/05/xmldsig-more#sha512-rsa-MGF1";
     static final String RSA_RIPEMD160_MGF1 =
         "http://www.w3.org/2007/05/xmldsig-more#ripemd160-rsa-MGF1";
+    static final String RSA_SHA3_224_MGF1 =
+        "http://www.w3.org/2007/05/xmldsig-more#sha3-224-rsa-MGF1";
+    static final String RSA_SHA3_256_MGF1 =
+        "http://www.w3.org/2007/05/xmldsig-more#sha3-256-rsa-MGF1";
+    static final String RSA_SHA3_384_MGF1 =
+        "http://www.w3.org/2007/05/xmldsig-more#sha3-384-rsa-MGF1";
+    static final String RSA_SHA3_512_MGF1 =
+        "http://www.w3.org/2007/05/xmldsig-more#sha3-512-rsa-MGF1";
 
     /**
      * Creates a {@code DOMSignatureMethod}.
@@ -188,6 +215,14 @@
             return new SHA384withRSAandMGF1(smElem);
         } else if (alg.equals(RSA_SHA512_MGF1)) {
             return new SHA512withRSAandMGF1(smElem);
+        } else if (alg.equals(RSA_SHA3_224_MGF1)) {
+            return new SHA3_224withRSAandMGF1(smElem);
+        } else if (alg.equals(RSA_SHA3_256_MGF1)) {
+            return new SHA3_256withRSAandMGF1(smElem);
+        } else if (alg.equals(RSA_SHA3_384_MGF1)) {
+            return new SHA3_384withRSAandMGF1(smElem);
+        } else if (alg.equals(RSA_SHA3_512_MGF1)) {
+            return new SHA3_512withRSAandMGF1(smElem);
         } else if (alg.equals(DOMRSAPSSSignatureMethod.RSA_PSS)) {
             return new DOMRSAPSSSignatureMethod.RSAPSS(smElem);
         } else if (alg.equals(RSA_RIPEMD160_MGF1)) {
@@ -220,12 +255,17 @@
             return new DOMHMACSignatureMethod.SHA512(smElem);
         } else if (alg.equals(DOMHMACSignatureMethod.HMAC_RIPEMD160)) {
             return new DOMHMACSignatureMethod.RIPEMD160(smElem);
+        } else if (alg.equals(ED25519)) {
+            return new EDDSA_ED25519(smElem);
+        } else if (alg.equals(ED448)) {
+            return new EDDSA_ED448(smElem);
         } else {
             throw new MarshalException
                 ("unsupported SignatureMethod algorithm: " + alg);
         }
     }
 
+    @Override
     public final AlgorithmParameterSpec getParameterSpec() {
         return params;
     }
@@ -247,6 +287,7 @@
             : Signature.getInstance(getJCAAlgorithm(), p);
     }
 
+    @Override
     boolean verify(Key key, SignedInfo si, byte[] sig,
                    XMLValidateContext context)
         throws InvalidKeyException, SignatureException, XMLSignatureException
@@ -313,6 +354,7 @@
         }
     }
 
+    @Override
     byte[] sign(Key key, SignedInfo si, XMLSignContext context)
         throws InvalidKeyException, XMLSignatureException
     {
@@ -372,6 +414,11 @@
         byte[] preVerifyFormat(Key key, byte[] sig) {
             return sig;
         }
+
+        @Override
+        Type getAlgorithmType() {
+            return Type.RSA;
+        }
     }
 
     abstract static class AbstractRSAPSSSignatureMethod
@@ -386,7 +433,7 @@
             super(dmElem);
         }
 
-        abstract public PSSParameterSpec getPSSParameterSpec();
+        public abstract PSSParameterSpec getPSSParameterSpec();
 
         @Override
         Signature getSignature(Provider p)
@@ -402,9 +449,7 @@
                 }
                 return s;
             } catch (NoSuchAlgorithmException nsae) {
-                return (p == null)
-                        ? Signature.getInstance(getJCAAlgorithm())
-                        : Signature.getInstance(getJCAAlgorithm(), p);
+                return super.getSignature(p);
             }
         }
     }
@@ -498,6 +543,11 @@
                 return sig;
             }
         }
+
+        @Override
+        Type getAlgorithmType() {
+            return Type.DSA;
+        }
     }
 
     abstract static class AbstractECDSASignatureMethod
@@ -539,6 +589,48 @@
                 return sig;
             }
         }
+
+        @Override
+        Type getAlgorithmType() {
+            return Type.ECDSA;
+        }
+    }
+
+    abstract static class AbstractEDDSASignatureMethod
+            extends DOMSignatureMethod {
+
+
+        AbstractEDDSASignatureMethod(AlgorithmParameterSpec params)
+                throws InvalidAlgorithmParameterException {
+            super(params);
+        }
+
+        AbstractEDDSASignatureMethod(Element dmElem) throws MarshalException {
+            super(dmElem);
+        }
+
+        /**
+         * Returns {@code sig}. No extra formatting is necessary for EDDSA
+         * See the RFC8032
+         */
+        @Override
+        byte[] postSignFormat(Key key, byte[] sig) {
+            return sig;
+        }
+
+        /**
+         * Returns {@code sig}. No extra formatting is necessary for EDDSA
+         * See the RFC8032
+         */
+        @Override
+        byte[] preVerifyFormat(Key key, byte[] sig) {
+            return sig;
+        }
+
+        @Override
+        Type getAlgorithmType() {
+            return Type.EDDSA;
+        }
     }
 
     static final class SHA1withRSA extends AbstractRSASignatureMethod {
@@ -557,10 +649,6 @@
         String getJCAAlgorithm() {
             return "SHA1withRSA";
         }
-        @Override
-        Type getAlgorithmType() {
-            return Type.RSA;
-        }
     }
 
     static final class SHA224withRSA extends AbstractRSASignatureMethod {
@@ -571,15 +659,14 @@
         SHA224withRSA(Element dmElem) throws MarshalException {
             super(dmElem);
         }
+        @Override
         public String getAlgorithm() {
             return RSA_SHA224;
         }
+        @Override
         String getJCAAlgorithm() {
             return "SHA224withRSA";
         }
-        Type getAlgorithmType() {
-            return Type.RSA;
-        }
     }
 
     static final class SHA256withRSA extends AbstractRSASignatureMethod {
@@ -590,15 +677,14 @@
         SHA256withRSA(Element dmElem) throws MarshalException {
             super(dmElem);
         }
+        @Override
         public String getAlgorithm() {
             return RSA_SHA256;
         }
+        @Override
         String getJCAAlgorithm() {
             return "SHA256withRSA";
         }
-        Type getAlgorithmType() {
-            return Type.RSA;
-        }
     }
 
     static final class SHA384withRSA extends AbstractRSASignatureMethod {
@@ -609,15 +695,14 @@
         SHA384withRSA(Element dmElem) throws MarshalException {
             super(dmElem);
         }
+        @Override
         public String getAlgorithm() {
             return RSA_SHA384;
         }
+        @Override
         String getJCAAlgorithm() {
             return "SHA384withRSA";
         }
-        Type getAlgorithmType() {
-            return Type.RSA;
-        }
     }
 
     static final class SHA512withRSA extends AbstractRSASignatureMethod {
@@ -628,15 +713,14 @@
         SHA512withRSA(Element dmElem) throws MarshalException {
             super(dmElem);
         }
+        @Override
         public String getAlgorithm() {
             return RSA_SHA512;
         }
+        @Override
         String getJCAAlgorithm() {
             return "SHA512withRSA";
         }
-        Type getAlgorithmType() {
-            return Type.RSA;
-        }
     }
 
     static final class RIPEMD160withRSA extends AbstractRSASignatureMethod {
@@ -655,15 +739,11 @@
         String getJCAAlgorithm() {
             return "RIPEMD160withRSA";
         }
-        @Override
-        Type getAlgorithmType() {
-            return Type.RSA;
-        }
     }
 
     static final class SHA1withRSAandMGF1 extends AbstractRSAPSSSignatureMethod {
 
-        private static PSSParameterSpec spec
+        private static final PSSParameterSpec SHA1_MGF1_PARAMS
                 = new PSSParameterSpec("SHA-1", "MGF1", MGF1ParameterSpec.SHA1,
                 20, PSSParameterSpec.TRAILER_FIELD_BC);
 
@@ -680,21 +760,17 @@
         }
         @Override
         public PSSParameterSpec getPSSParameterSpec() {
-            return spec;
+            return SHA1_MGF1_PARAMS;
         }
         @Override
         String getJCAAlgorithm() {
             return "SHA1withRSAandMGF1";
         }
-        @Override
-        Type getAlgorithmType() {
-            return Type.RSA;
-        }
     }
 
     static final class SHA224withRSAandMGF1 extends AbstractRSAPSSSignatureMethod {
 
-        private static PSSParameterSpec spec
+        private static final PSSParameterSpec SHA224_MGF1_PARAMS
                 = new PSSParameterSpec("SHA-224", "MGF1", MGF1ParameterSpec.SHA224,
                 28, PSSParameterSpec.TRAILER_FIELD_BC);
 
@@ -711,21 +787,17 @@
         }
         @Override
         public PSSParameterSpec getPSSParameterSpec() {
-            return spec;
+            return SHA224_MGF1_PARAMS;
         }
         @Override
         String getJCAAlgorithm() {
             return "SHA224withRSAandMGF1";
         }
-        @Override
-        Type getAlgorithmType() {
-            return Type.RSA;
-        }
     }
 
     static final class SHA256withRSAandMGF1 extends AbstractRSAPSSSignatureMethod {
 
-        private static PSSParameterSpec spec
+        private static final PSSParameterSpec SHA256_MGF1_PARAMS
                 = new PSSParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256,
                 32, PSSParameterSpec.TRAILER_FIELD_BC);
 
@@ -742,21 +814,17 @@
         }
         @Override
         public PSSParameterSpec getPSSParameterSpec() {
-            return spec;
+            return SHA256_MGF1_PARAMS;
         }
         @Override
         String getJCAAlgorithm() {
             return "SHA256withRSAandMGF1";
         }
-        @Override
-        Type getAlgorithmType() {
-            return Type.RSA;
-        }
     }
 
     static final class SHA384withRSAandMGF1 extends AbstractRSAPSSSignatureMethod {
 
-        private static PSSParameterSpec spec
+        private static final PSSParameterSpec SHA384_MGF1_PARAMS
                 = new PSSParameterSpec("SHA-384", "MGF1", MGF1ParameterSpec.SHA384,
                 48, PSSParameterSpec.TRAILER_FIELD_BC);
 
@@ -773,21 +841,17 @@
         }
         @Override
         public PSSParameterSpec getPSSParameterSpec() {
-            return spec;
+            return SHA384_MGF1_PARAMS;
         }
         @Override
         String getJCAAlgorithm() {
             return "SHA384withRSAandMGF1";
         }
-        @Override
-        Type getAlgorithmType() {
-            return Type.RSA;
-        }
     }
 
     static final class SHA512withRSAandMGF1 extends AbstractRSAPSSSignatureMethod {
 
-        private static PSSParameterSpec spec
+        private static final PSSParameterSpec SHA512_MGF1_PARAMS
                 = new PSSParameterSpec("SHA-512", "MGF1", MGF1ParameterSpec.SHA512,
                 64, PSSParameterSpec.TRAILER_FIELD_BC);
 
@@ -804,15 +868,123 @@
         }
         @Override
         public PSSParameterSpec getPSSParameterSpec() {
-            return spec;
+            return SHA512_MGF1_PARAMS;
         }
         @Override
         String getJCAAlgorithm() {
             return "SHA512withRSAandMGF1";
         }
+    }
+
+    static final class SHA3_224withRSAandMGF1 extends AbstractRSAPSSSignatureMethod {
+
+        private static final PSSParameterSpec SHA3_224_MGF1_PARAMS
+                = new PSSParameterSpec("SHA3-224", "MGF1",
+                new MGF1ParameterSpec("SHA3-224"), 28,
+                PSSParameterSpec.TRAILER_FIELD_BC);
+
+        SHA3_224withRSAandMGF1(AlgorithmParameterSpec params)
+            throws InvalidAlgorithmParameterException {
+            super(params);
+        }
+        SHA3_224withRSAandMGF1(Element dmElem) throws MarshalException {
+            super(dmElem);
+        }
         @Override
-        Type getAlgorithmType() {
-            return Type.RSA;
+        public String getAlgorithm() {
+            return RSA_SHA3_224_MGF1;
+        }
+        @Override
+        public PSSParameterSpec getPSSParameterSpec() {
+            return SHA3_224_MGF1_PARAMS;
+        }
+        @Override
+        String getJCAAlgorithm() {
+            return "SHA3-224withRSAandMGF1";
+        }
+    }
+
+    static final class SHA3_256withRSAandMGF1 extends AbstractRSAPSSSignatureMethod {
+
+        private static final PSSParameterSpec SHA3_256_MGF1_PARAMS
+                = new PSSParameterSpec("SHA3-256", "MGF1",
+                new MGF1ParameterSpec("SHA3-256"), 32,
+                PSSParameterSpec.TRAILER_FIELD_BC);
+
+        SHA3_256withRSAandMGF1(AlgorithmParameterSpec params)
+            throws InvalidAlgorithmParameterException {
+            super(params);
+        }
+        SHA3_256withRSAandMGF1(Element dmElem) throws MarshalException {
+            super(dmElem);
+        }
+        @Override
+        public String getAlgorithm() {
+            return RSA_SHA3_256_MGF1;
+        }
+        @Override
+        public PSSParameterSpec getPSSParameterSpec() {
+            return SHA3_256_MGF1_PARAMS;
+        }
+        @Override
+        String getJCAAlgorithm() {
+            return "SHA3-256withRSAandMGF1";
+        }
+    }
+
+    static final class SHA3_384withRSAandMGF1 extends AbstractRSAPSSSignatureMethod {
+
+        private static final PSSParameterSpec SHA3_384_MGF1_PARAMS
+                = new PSSParameterSpec("SHA3-384", "MGF1",
+                new MGF1ParameterSpec("SHA3-384"), 48,
+                PSSParameterSpec.TRAILER_FIELD_BC);
+
+        SHA3_384withRSAandMGF1(AlgorithmParameterSpec params)
+            throws InvalidAlgorithmParameterException {
+            super(params);
+        }
+        SHA3_384withRSAandMGF1(Element dmElem) throws MarshalException {
+            super(dmElem);
+        }
+        @Override
+        public String getAlgorithm() {
+            return RSA_SHA3_384_MGF1;
+        }
+        @Override
+        public PSSParameterSpec getPSSParameterSpec() {
+            return SHA3_384_MGF1_PARAMS;
+        }
+        @Override
+        String getJCAAlgorithm() {
+            return "SHA3-384withRSAandMGF1";
+        }
+    }
+
+    static final class SHA3_512withRSAandMGF1 extends AbstractRSAPSSSignatureMethod {
+
+        private static final PSSParameterSpec SHA3_512_MGF1_PARAMS
+                = new PSSParameterSpec("SHA3-512", "MGF1",
+                new MGF1ParameterSpec("SHA3-512"), 64,
+                PSSParameterSpec.TRAILER_FIELD_BC);
+
+        SHA3_512withRSAandMGF1(AlgorithmParameterSpec params)
+            throws InvalidAlgorithmParameterException {
+            super(params);
+        }
+        SHA3_512withRSAandMGF1(Element dmElem) throws MarshalException {
+            super(dmElem);
+        }
+        @Override
+        public String getAlgorithm() {
+            return RSA_SHA3_512_MGF1;
+        }
+        @Override
+        public PSSParameterSpec getPSSParameterSpec() {
+            return SHA3_512_MGF1_PARAMS;
+        }
+        @Override
+        String getJCAAlgorithm() {
+            return "SHA3-512withRSAandMGF1";
         }
     }
 
@@ -832,10 +1004,6 @@
         String getJCAAlgorithm() {
             return "RIPEMD160withRSAandMGF1";
         }
-        @Override
-        Type getAlgorithmType() {
-            return Type.RSA;
-        }
     }
 
     static final class SHA1withDSA extends AbstractDSASignatureMethod {
@@ -846,18 +1014,18 @@
         SHA1withDSA(Element dmElem) throws MarshalException {
             super(dmElem);
         }
+        @Override
         public String getAlgorithm() {
             return SignatureMethod.DSA_SHA1;
         }
+        @Override
         String getJCAAlgorithm() {
             return "SHA1withDSAinP1363Format";
         }
+        @Override
         String getJCAFallbackAlgorithm() {
             return "SHA1withDSA";
         }
-        Type getAlgorithmType() {
-            return Type.DSA;
-        }
     }
 
     static final class SHA256withDSA extends AbstractDSASignatureMethod {
@@ -868,18 +1036,18 @@
         SHA256withDSA(Element dmElem) throws MarshalException {
             super(dmElem);
         }
+        @Override
         public String getAlgorithm() {
             return DSA_SHA256;
         }
+        @Override
         String getJCAAlgorithm() {
             return "SHA256withDSAinP1363Format";
         }
+        @Override
         String getJCAFallbackAlgorithm() {
             return "SHA256withDSA";
         }
-        Type getAlgorithmType() {
-            return Type.DSA;
-        }
     }
 
     static final class SHA1withECDSA extends AbstractECDSASignatureMethod {
@@ -890,18 +1058,18 @@
         SHA1withECDSA(Element dmElem) throws MarshalException {
             super(dmElem);
         }
+        @Override
         public String getAlgorithm() {
             return ECDSA_SHA1;
         }
+        @Override
         String getJCAAlgorithm() {
             return "SHA1withECDSAinP1363Format";
         }
+        @Override
         String getJCAFallbackAlgorithm() {
             return "SHA1withECDSA";
         }
-        Type getAlgorithmType() {
-            return Type.ECDSA;
-        }
     }
 
     static final class SHA224withECDSA extends AbstractECDSASignatureMethod {
@@ -920,13 +1088,10 @@
         String getJCAAlgorithm() {
             return "SHA224withECDSAinP1363Format";
         }
+        @Override
         String getJCAFallbackAlgorithm() {
             return "SHA224withECDSA";
         }
-        @Override
-        Type getAlgorithmType() {
-            return Type.ECDSA;
-        }
     }
 
     static final class SHA256withECDSA extends AbstractECDSASignatureMethod {
@@ -937,18 +1102,18 @@
         SHA256withECDSA(Element dmElem) throws MarshalException {
             super(dmElem);
         }
+        @Override
         public String getAlgorithm() {
             return ECDSA_SHA256;
         }
+        @Override
         String getJCAAlgorithm() {
             return "SHA256withECDSAinP1363Format";
         }
+        @Override
         String getJCAFallbackAlgorithm() {
             return "SHA256withECDSA";
         }
-        Type getAlgorithmType() {
-            return Type.ECDSA;
-        }
     }
 
     static final class SHA384withECDSA extends AbstractECDSASignatureMethod {
@@ -959,18 +1124,18 @@
         SHA384withECDSA(Element dmElem) throws MarshalException {
             super(dmElem);
         }
+        @Override
         public String getAlgorithm() {
             return ECDSA_SHA384;
         }
+        @Override
         String getJCAAlgorithm() {
             return "SHA384withECDSAinP1363Format";
         }
+        @Override
         String getJCAFallbackAlgorithm() {
             return "SHA384withECDSA";
         }
-        Type getAlgorithmType() {
-            return Type.ECDSA;
-        }
     }
 
     static final class SHA512withECDSA extends AbstractECDSASignatureMethod {
@@ -981,18 +1146,18 @@
         SHA512withECDSA(Element dmElem) throws MarshalException {
             super(dmElem);
         }
+        @Override
         public String getAlgorithm() {
             return ECDSA_SHA512;
         }
+        @Override
         String getJCAAlgorithm() {
             return "SHA512withECDSAinP1363Format";
         }
+        @Override
         String getJCAFallbackAlgorithm() {
             return "SHA512withECDSA";
         }
-        Type getAlgorithmType() {
-            return Type.ECDSA;
-        }
     }
 
     static final class RIPEMD160withECDSA extends AbstractECDSASignatureMethod {
@@ -1011,13 +1176,52 @@
         String getJCAAlgorithm() {
             return "RIPEMD160withECDSAinP1363Format"; // Is this real?
         }
+        @Override
         String getJCAFallbackAlgorithm() {
             return "RIPEMD160withECDSA";
         }
+    }
+
+    static final class EDDSA_ED25519 extends AbstractEDDSASignatureMethod {
+
+        EDDSA_ED25519(AlgorithmParameterSpec params)
+                throws InvalidAlgorithmParameterException {
+            super(params);
+        }
+
+        EDDSA_ED25519(Element dmElem) throws MarshalException {
+            super(dmElem);
+        }
+
         @Override
-        Type getAlgorithmType() {
-            return Type.ECDSA;
+        public String getAlgorithm() {
+            return ED25519;
+        }
+
+        @Override
+        String getJCAAlgorithm() {
+            return "Ed25519";
         }
     }
 
+    static final class EDDSA_ED448 extends AbstractEDDSASignatureMethod {
+        EDDSA_ED448(AlgorithmParameterSpec params)
+                throws InvalidAlgorithmParameterException {
+            super(params);
+        }
+
+        EDDSA_ED448(Element dmElem) throws MarshalException {
+            super(dmElem);
+        }
+
+        @Override
+        public String getAlgorithm() {
+            return ED448;
+        }
+
+        @Override
+        String getJCAAlgorithm() {
+            return "Ed448";
+        }
+    }
 }
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureProperties.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureProperties.java
index efa9d3f..ba72b27 100644
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureProperties.java
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureProperties.java
@@ -25,11 +25,15 @@
  */
 package org.jcp.xml.dsig.internal.dom;
 
-import javax.xml.crypto.*;
-import javax.xml.crypto.dom.DOMCryptoContext;
-import javax.xml.crypto.dsig.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 
-import java.util.*;
+import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.dom.DOMCryptoContext;
+import javax.xml.crypto.dsig.SignatureProperties;
+import javax.xml.crypto.dsig.SignatureProperty;
+import javax.xml.crypto.dsig.XMLSignature;
 
 import org.w3c.dom.Attr;
 import org.w3c.dom.Document;
@@ -117,10 +121,12 @@
         }
     }
 
+    @Override
     public List<SignatureProperty> getProperties() {
         return properties;
     }
 
+    @Override
     public String getId() {
         return id;
     }
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureProperty.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureProperty.java
index 136847b..61994cd 100644
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureProperty.java
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignatureProperty.java
@@ -25,11 +25,15 @@
  */
 package org.jcp.xml.dsig.internal.dom;
 
-import javax.xml.crypto.*;
-import javax.xml.crypto.dom.DOMCryptoContext;
-import javax.xml.crypto.dsig.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
 
-import java.util.*;
+import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.XMLStructure;
+import javax.xml.crypto.dom.DOMCryptoContext;
+import javax.xml.crypto.dsig.SignatureProperty;
+import javax.xml.crypto.dsig.XMLSignature;
 
 import org.w3c.dom.Attr;
 import org.w3c.dom.Document;
@@ -117,14 +121,17 @@
         }
     }
 
+    @Override
     public List<XMLStructure> getContent() {
         return content;
     }
 
+    @Override
     public String getId() {
         return id;
     }
 
+    @Override
     public String getTarget() {
         return target;
     }
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignedInfo.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignedInfo.java
index f4f8bfd..170b179 100644
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignedInfo.java
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSignedInfo.java
@@ -25,28 +25,38 @@
  */
 package org.jcp.xml.dsig.internal.dom;
 
-import javax.xml.crypto.*;
-import javax.xml.crypto.dom.DOMCryptoContext;
-import javax.xml.crypto.dsig.*;
-import javax.xml.crypto.dsig.spec.RSAPSSParameterSpec;
-
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
+import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.io.IOException;
 import java.security.Provider;
 import java.security.spec.AlgorithmParameterSpec;
 import java.security.spec.MGF1ParameterSpec;
 import java.security.spec.PSSParameterSpec;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.XMLCryptoContext;
+import javax.xml.crypto.dom.DOMCryptoContext;
+import javax.xml.crypto.dsig.CanonicalizationMethod;
+import javax.xml.crypto.dsig.Reference;
+import javax.xml.crypto.dsig.SignatureMethod;
+import javax.xml.crypto.dsig.SignedInfo;
+import javax.xml.crypto.dsig.TransformException;
+import javax.xml.crypto.dsig.XMLSignature;
+import javax.xml.crypto.dsig.XMLSignatureException;
+import javax.xml.crypto.dsig.spec.RSAPSSParameterSpec;
 
 import com.sun.org.apache.xml.internal.security.algorithms.implementations.SignatureBaseRSA;
+import com.sun.org.apache.xml.internal.security.utils.UnsyncBufferedOutputStream;
+import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
-import com.sun.org.apache.xml.internal.security.utils.UnsyncBufferedOutputStream;
-import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
+
 
 /**
  * DOM-based implementation of SignedInfo.
@@ -57,9 +67,9 @@
     private static final com.sun.org.slf4j.internal.Logger LOG =
         com.sun.org.slf4j.internal.LoggerFactory.getLogger(DOMSignedInfo.class);
 
-    private List<Reference> references;
-    private CanonicalizationMethod canonicalizationMethod;
-    private SignatureMethod signatureMethod;
+    private final List<Reference> references;
+    private final CanonicalizationMethod canonicalizationMethod;
+    private final SignatureMethod signatureMethod;
     private String id;
     private Document ownerDoc;
     private Element localSiElem;
@@ -86,17 +96,13 @@
         }
         this.canonicalizationMethod = cm;
         this.signatureMethod = sm;
-        this.references = Collections.unmodifiableList(
-            new ArrayList<>(references));
+        this.references = Collections.unmodifiableList(new ArrayList<>(references));
         if (this.references.isEmpty()) {
-            throw new IllegalArgumentException("list of references must " +
-                "contain at least one entry");
+            throw new IllegalArgumentException("list of references must contain at least one entry");
         }
-        for (int i = 0, size = this.references.size(); i < size; i++) {
-            Object obj = this.references.get(i);
+        for (Object obj : this.references) {
             if (!(obj instanceof Reference)) {
-                throw new ClassCastException("list of references contains " +
-                    "an illegal type");
+                throw new ClassCastException("list of references contains an illegal " + obj.getClass());
             }
         }
     }
@@ -210,22 +216,27 @@
         references = Collections.unmodifiableList(refList);
     }
 
+    @Override
     public CanonicalizationMethod getCanonicalizationMethod() {
         return canonicalizationMethod;
     }
 
+    @Override
     public SignatureMethod getSignatureMethod() {
         return signatureMethod;
     }
 
+    @Override
     public String getId() {
         return id;
     }
 
+    @Override
     public List<Reference> getReferences() {
         return references;
     }
 
+    @Override
     public InputStream getCanonicalizedData() {
         return canonData;
     }
@@ -249,8 +260,8 @@
             if (LOG.isDebugEnabled()) {
                 LOG.debug("Canonicalized SignedInfo:");
                 StringBuilder sb = new StringBuilder(signedInfoBytes.length);
-                for (int i = 0; i < signedInfoBytes.length; i++) {
-                    sb.append((char)signedInfoBytes[i]);
+                for (byte signedInfoByte : signedInfoBytes) {
+                    sb.append((char) signedInfoByte);
                 }
                 LOG.debug(sb.toString());
                 LOG.debug("Data to be signed/verified:" + XMLUtils.encodeToString(signedInfoBytes));
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMStructure.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMStructure.java
index e7ddd00..77818ea 100644
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMStructure.java
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMStructure.java
@@ -25,12 +25,13 @@
  */
 package org.jcp.xml.dsig.internal.dom;
 
+import java.util.List;
+
 import javax.xml.crypto.MarshalException;
 import javax.xml.crypto.XMLStructure;
 import javax.xml.crypto.dom.DOMCryptoContext;
-import org.w3c.dom.Node;
 
-import java.util.List;
+import org.w3c.dom.Node;
 
 /**
  * DOM-based abstract implementation of XMLStructure.
@@ -38,6 +39,7 @@
  */
 public abstract class DOMStructure implements XMLStructure {
 
+    @Override
     public final boolean isFeatureSupported(String feature) {
         if (feature == null) {
             throw new NullPointerException();
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSubTreeData.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSubTreeData.java
index 404942e..dab41a9 100644
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSubTreeData.java
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMSubTreeData.java
@@ -25,12 +25,14 @@
  */
 package org.jcp.xml.dsig.internal.dom;
 
-import javax.xml.crypto.NodeSetData;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 import java.util.ListIterator;
 import java.util.NoSuchElementException;
+
+import javax.xml.crypto.NodeSetData;
+
 import org.w3c.dom.NamedNodeMap;
 import org.w3c.dom.Node;
 
@@ -79,6 +81,7 @@
             this.withComments = !excludeComments;
         }
 
+        @Override
         public boolean hasNext() {
             if (nodeSet == null) {
                 nodeSet = dereferenceSameDocumentURI(root);
@@ -87,6 +90,7 @@
             return li.hasNext();
         }
 
+        @Override
         public Node next() {
             if (nodeSet == null) {
                 nodeSet = dereferenceSameDocumentURI(root);
@@ -99,6 +103,7 @@
             }
         }
 
+        @Override
         public void remove() {
             throw new UnsupportedOperationException();
         }
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMTransform.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMTransform.java
index fd6a892..0e6fce6 100644
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMTransform.java
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMTransform.java
@@ -98,10 +98,12 @@
         }
     }
 
+    @Override
     public final AlgorithmParameterSpec getParameterSpec() {
         return spi.getParameterSpec();
     }
 
+    @Override
     public final String getAlgorithm() {
         return spi.getAlgorithm();
     }
@@ -145,6 +147,7 @@
      * @throws XMLSignatureException if an unexpected error occurs while
      *    executing the transform
      */
+    @Override
     public Data transform(Data data, XMLCryptoContext xc)
         throws TransformException
     {
@@ -164,6 +167,7 @@
      * @throws XMLSignatureException if an unexpected error occurs while
      *    executing the transform
      */
+    @Override
     public Data transform(Data data, XMLCryptoContext xc, OutputStream os)
         throws TransformException
     {
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMURIDereferencer.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMURIDereferencer.java
index e72642b..212ffc9 100644
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMURIDereferencer.java
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMURIDereferencer.java
@@ -25,18 +25,23 @@
  */
 package org.jcp.xml.dsig.internal.dom;
 
+import javax.xml.crypto.Data;
+import javax.xml.crypto.URIDereferencer;
+import javax.xml.crypto.URIReference;
+import javax.xml.crypto.URIReferenceException;
+import javax.xml.crypto.XMLCryptoContext;
+import javax.xml.crypto.dom.DOMCryptoContext;
+import javax.xml.crypto.dom.DOMURIReference;
+
+import com.sun.org.apache.xml.internal.security.Init;
+import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
+import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
+import com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolver;
+import com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolverContext;
 import org.w3c.dom.Attr;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 
-import com.sun.org.apache.xml.internal.security.Init;
-import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
-import com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolver;
-import com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolverContext;
-import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
-
-import javax.xml.crypto.*;
-import javax.xml.crypto.dom.*;
 import java.net.URI;
 
 /**
@@ -53,6 +58,7 @@
         Init.init();
     }
 
+    @Override
     public Data dereference(URIReference uriRef, XMLCryptoContext context)
         throws URIReferenceException {
 
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMX509Data.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMX509Data.java
index bf8de88..2da7628 100644
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMX509Data.java
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMX509Data.java
@@ -46,12 +46,11 @@
 import javax.xml.crypto.dsig.keyinfo.X509Data;
 import javax.xml.crypto.dsig.keyinfo.X509IssuerSerial;
 
+import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 
-import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
-
 /**
  * DOM-based implementation of X509Data.
  *
@@ -134,6 +133,7 @@
         this.content = Collections.unmodifiableList(newContent);
     }
 
+    @Override
     public List<Object> getContent() {
         return content;
     }
@@ -147,8 +147,7 @@
                                                 XMLSignature.XMLNS, dsPrefix);
 
         // append children and preserve order
-        for (int i = 0, size = content.size(); i < size; i++) {
-            Object object = content.get(i);
+        for (Object object : content) {
             if (object instanceof X509Certificate) {
                 marshalCert((X509Certificate)object,xdElem,ownerDoc,dsPrefix);
             } else if (object instanceof XMLStructure) {
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMX509IssuerSerial.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMX509IssuerSerial.java
index 959b786..c200884 100644
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMX509IssuerSerial.java
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMX509IssuerSerial.java
@@ -25,14 +25,14 @@
  */
 package org.jcp.xml.dsig.internal.dom;
 
+import java.math.BigInteger;
+
+import javax.security.auth.x500.X500Principal;
 import javax.xml.crypto.MarshalException;
 import javax.xml.crypto.dom.DOMCryptoContext;
 import javax.xml.crypto.dsig.XMLSignature;
 import javax.xml.crypto.dsig.keyinfo.X509IssuerSerial;
 
-import java.math.BigInteger;
-
-import javax.security.auth.x500.X500Principal;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
@@ -88,10 +88,12 @@
         serialNumber = new BigInteger(sNElem.getFirstChild().getNodeValue());
     }
 
+    @Override
     public String getIssuerName() {
         return issuerName;
     }
 
+    @Override
     public BigInteger getSerialNumber() {
         return serialNumber;
     }
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLObject.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLObject.java
index 925a6b8..bf36537 100644
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLObject.java
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLObject.java
@@ -25,12 +25,17 @@
  */
 package org.jcp.xml.dsig.internal.dom;
 
-import javax.xml.crypto.*;
-import javax.xml.crypto.dom.DOMCryptoContext;
-import javax.xml.crypto.dsig.*;
-
 import java.security.Provider;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.XMLCryptoContext;
+import javax.xml.crypto.XMLStructure;
+import javax.xml.crypto.dom.DOMCryptoContext;
+import javax.xml.crypto.dsig.XMLObject;
+import javax.xml.crypto.dsig.XMLSignature;
 
 import org.w3c.dom.Attr;
 import org.w3c.dom.Document;
@@ -145,18 +150,22 @@
         this.objectElem = objElem;
     }
 
+    @Override
     public List<XMLStructure> getContent() {
         return content;
     }
 
+    @Override
     public String getId() {
         return id;
     }
 
+    @Override
     public String getMimeType() {
         return mimeType;
     }
 
+    @Override
     public String getEncoding() {
         return encoding;
     }
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLSignature.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLSignature.java
index 746a1e5..30b35b4 100644
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLSignature.java
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLSignature.java
@@ -32,29 +32,42 @@
  */
 package org.jcp.xml.dsig.internal.dom;
 
-import javax.xml.crypto.*;
-import javax.xml.crypto.dom.*;
-import javax.xml.crypto.dsig.*;
-import javax.xml.crypto.dsig.dom.DOMSignContext;
-import javax.xml.crypto.dsig.dom.DOMValidateContext;
-import javax.xml.crypto.dsig.keyinfo.KeyInfo;
-
 import java.security.InvalidKeyException;
 import java.security.Key;
 import java.security.Provider;
-import java.util.Collections;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import javax.xml.crypto.KeySelector;
+import javax.xml.crypto.KeySelectorException;
+import javax.xml.crypto.KeySelectorResult;
+import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.XMLCryptoContext;
+import javax.xml.crypto.XMLStructure;
+import javax.xml.crypto.dom.DOMCryptoContext;
+import javax.xml.crypto.dsig.Manifest;
+import javax.xml.crypto.dsig.Reference;
+import javax.xml.crypto.dsig.SignatureMethod;
+import javax.xml.crypto.dsig.SignedInfo;
+import javax.xml.crypto.dsig.Transform;
+import javax.xml.crypto.dsig.XMLObject;
+import javax.xml.crypto.dsig.XMLSignContext;
+import javax.xml.crypto.dsig.XMLSignature;
+import javax.xml.crypto.dsig.XMLSignatureException;
+import javax.xml.crypto.dsig.XMLValidateContext;
+import javax.xml.crypto.dsig.dom.DOMSignContext;
+import javax.xml.crypto.dsig.dom.DOMValidateContext;
+import javax.xml.crypto.dsig.keyinfo.KeyInfo;
+
+import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
 import org.w3c.dom.Attr;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 
-import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
-
 /**
  * DOM-based implementation of XMLSignature.
  *
@@ -64,11 +77,11 @@
 
     private static final com.sun.org.slf4j.internal.Logger LOG =
         com.sun.org.slf4j.internal.LoggerFactory.getLogger(DOMXMLSignature.class);
-    private String id;
-    private SignatureValue sv;
+    private final String id;
+    private final SignatureValue sv;
     private KeyInfo ki;
     private List<XMLObject> objects;
-    private SignedInfo si;
+    private final SignedInfo si;
     private Document ownerDoc = null;
     private Element localSigElem = null;
     private Element sigElem = null;
@@ -174,26 +187,32 @@
         }
     }
 
+    @Override
     public String getId() {
         return id;
     }
 
+    @Override
     public KeyInfo getKeyInfo() {
         return ki;
     }
 
+    @Override
     public SignedInfo getSignedInfo() {
         return si;
     }
 
+    @Override
     public List<XMLObject> getObjects() {
         return objects;
     }
 
+    @Override
     public SignatureValue getSignatureValue() {
         return sv;
     }
 
+    @Override
     public KeySelectorResult getKeySelectorResult() {
         return ksr;
     }
@@ -234,8 +253,8 @@
         }
 
         // create and append Object elements if necessary
-        for (int i = 0, size = objects.size(); i < size; i++) {
-            ((DOMXMLObject)objects.get(i)).marshal(sigElem, dsPrefix, context);
+        for (XMLObject object : objects) {
+            ((DOMXMLObject)object).marshal(sigElem, dsPrefix, context);
         }
 
         // append Id attribute
@@ -460,13 +479,12 @@
             if (parsedId != null && signatureIdMap.containsKey(parsedId)) {
                 XMLStructure xs = signatureIdMap.get(parsedId);
                 if (xs instanceof DOMReference) {
-                    digestReference((DOMReference)xs, signContext);
+                    digestReference((DOMReference) xs, signContext);
                 } else if (xs instanceof Manifest) {
-                    Manifest man = (Manifest)xs;
+                    Manifest man = (Manifest) xs;
                     List<Reference> manRefs = DOMManifest.getManifestReferences(man);
-                    for (int i = 0, size = manRefs.size(); i < size; i++) {
-                        digestReference((DOMReference)manRefs.get(i),
-                                        signContext);
+                    for (Reference manRef : manRefs) {
+                        digestReference((DOMReference) manRef, signContext);
                     }
                 }
             }
@@ -518,10 +536,12 @@
             this.sigValueElem = sigValueElem;
         }
 
+        @Override
         public String getId() {
             return id;
         }
 
+        @Override
         public byte[] getValue() {
             return (value == null) ? null : value.clone();
         }
@@ -605,6 +625,7 @@
             return result;
         }
 
+        @Override
         public void marshal(Node parent, String dsPrefix,
                             DOMCryptoContext context)
             throws MarshalException
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLSignatureFactory.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLSignatureFactory.java
index 19f842f..119bf16 100644
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLSignatureFactory.java
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXMLSignatureFactory.java
@@ -25,17 +25,37 @@
  */
 package org.jcp.xml.dsig.internal.dom;
 
-import javax.xml.crypto.*;
-import javax.xml.crypto.dom.DOMCryptoContext;
-import javax.xml.crypto.dsig.*;
-import javax.xml.crypto.dsig.dom.DOMValidateContext;
-import javax.xml.crypto.dsig.keyinfo.*;
-import javax.xml.crypto.dsig.spec.*;
-
 import java.security.InvalidAlgorithmParameterException;
 import java.security.NoSuchAlgorithmException;
 import java.util.List;
 
+import javax.xml.crypto.Data;
+import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.URIDereferencer;
+import javax.xml.crypto.XMLCryptoContext;
+import javax.xml.crypto.XMLStructure;
+import javax.xml.crypto.dom.DOMCryptoContext;
+import javax.xml.crypto.dsig.CanonicalizationMethod;
+import javax.xml.crypto.dsig.DigestMethod;
+import javax.xml.crypto.dsig.Manifest;
+import javax.xml.crypto.dsig.Reference;
+import javax.xml.crypto.dsig.SignatureMethod;
+import javax.xml.crypto.dsig.SignatureProperties;
+import javax.xml.crypto.dsig.SignatureProperty;
+import javax.xml.crypto.dsig.SignedInfo;
+import javax.xml.crypto.dsig.Transform;
+import javax.xml.crypto.dsig.TransformService;
+import javax.xml.crypto.dsig.XMLObject;
+import javax.xml.crypto.dsig.XMLSignature;
+import javax.xml.crypto.dsig.XMLSignatureFactory;
+import javax.xml.crypto.dsig.XMLValidateContext;
+import javax.xml.crypto.dsig.dom.DOMValidateContext;
+import javax.xml.crypto.dsig.keyinfo.KeyInfo;
+import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
+import javax.xml.crypto.dsig.spec.DigestMethodParameterSpec;
+import javax.xml.crypto.dsig.spec.SignatureMethodParameterSpec;
+import javax.xml.crypto.dsig.spec.TransformParameterSpec;
+
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
@@ -51,20 +71,24 @@
      */
     public DOMXMLSignatureFactory() {}
 
+    @Override
     public XMLSignature newXMLSignature(SignedInfo si, KeyInfo ki) {
         return new DOMXMLSignature(si, ki, null, null, null);
     }
 
+    @Override
     @SuppressWarnings({ "unchecked", "rawtypes" })
     public XMLSignature newXMLSignature(SignedInfo si, KeyInfo ki,
         List objects, String id, String signatureValueId) {
         return new DOMXMLSignature(si, ki, objects, id, signatureValueId);
     }
 
+    @Override
     public Reference newReference(String uri, DigestMethod dm) {
         return newReference(uri, dm, null, null, null);
     }
 
+    @Override
     @SuppressWarnings({ "unchecked", "rawtypes" })
     public Reference newReference(String uri, DigestMethod dm, List transforms,
         String type, String id) {
@@ -89,6 +113,7 @@
             (uri, type, dm, appliedTransforms, result, transforms, id, getProvider());
     }
 
+    @Override
     @SuppressWarnings({ "unchecked", "rawtypes" })
     public Reference newReference(String uri, DigestMethod dm, List transforms,
         String type, String id, byte[] digestValue) {
@@ -99,12 +124,14 @@
             (uri, type, dm, null, null, transforms, id, digestValue, getProvider());
     }
 
+    @Override
     @SuppressWarnings({ "rawtypes" })
     public SignedInfo newSignedInfo(CanonicalizationMethod cm,
         SignatureMethod sm, List references) {
         return newSignedInfo(cm, sm, references, null);
     }
 
+    @Override
     @SuppressWarnings({ "unchecked", "rawtypes" })
     public SignedInfo newSignedInfo(CanonicalizationMethod cm,
         SignatureMethod sm, List references, String id) {
@@ -112,33 +139,39 @@
     }
 
     // Object factory methods
+    @Override
     @SuppressWarnings({ "unchecked", "rawtypes" })
     public XMLObject newXMLObject(List content, String id, String mimeType,
         String encoding) {
         return new DOMXMLObject(content, id, mimeType, encoding);
     }
 
+    @Override
     @SuppressWarnings({ "rawtypes" })
     public Manifest newManifest(List references) {
         return newManifest(references, null);
     }
 
+    @Override
     @SuppressWarnings({ "unchecked", "rawtypes" })
     public Manifest newManifest(List references, String id) {
         return new DOMManifest(references, id);
     }
 
+    @Override
     @SuppressWarnings({ "unchecked", "rawtypes" })
     public SignatureProperties newSignatureProperties(List props, String id) {
         return new DOMSignatureProperties(props, id);
     }
 
+    @Override
     @SuppressWarnings({ "unchecked", "rawtypes" })
     public SignatureProperty newSignatureProperty
         (List info, String target, String id) {
         return new DOMSignatureProperty(info, target, id);
     }
 
+    @Override
     public XMLSignature unmarshalXMLSignature(XMLValidateContext context)
         throws MarshalException {
 
@@ -148,6 +181,7 @@
         return unmarshal(((DOMValidateContext) context).getNode(), context);
     }
 
+    @Override
     public XMLSignature unmarshalXMLSignature(XMLStructure xmlStructure)
         throws MarshalException {
 
@@ -201,6 +235,7 @@
         }
     }
 
+    @Override
     public boolean isFeatureSupported(String feature) {
         if (feature == null) {
             throw new NullPointerException();
@@ -209,6 +244,7 @@
         }
     }
 
+    @Override
     public DigestMethod newDigestMethod(String algorithm,
         DigestMethodParameterSpec params) throws NoSuchAlgorithmException,
         InvalidAlgorithmParameterException {
@@ -242,6 +278,7 @@
         }
     }
 
+    @Override
     public SignatureMethod newSignatureMethod(String algorithm,
         SignatureMethodParameterSpec params) throws NoSuchAlgorithmException,
         InvalidAlgorithmParameterException {
@@ -270,6 +307,14 @@
             return new DOMSignatureMethod.SHA384withRSAandMGF1(params);
         } else if (algorithm.equals(DOMSignatureMethod.RSA_SHA512_MGF1)) {
             return new DOMSignatureMethod.SHA512withRSAandMGF1(params);
+        } else if (algorithm.equals(DOMSignatureMethod.RSA_SHA3_224_MGF1)) {
+            return new DOMSignatureMethod.SHA3_224withRSAandMGF1(params);
+        } else if (algorithm.equals(DOMSignatureMethod.RSA_SHA3_256_MGF1)) {
+            return new DOMSignatureMethod.SHA3_256withRSAandMGF1(params);
+        } else if (algorithm.equals(DOMSignatureMethod.RSA_SHA3_384_MGF1)) {
+            return new DOMSignatureMethod.SHA3_384withRSAandMGF1(params);
+        } else if (algorithm.equals(DOMSignatureMethod.RSA_SHA3_512_MGF1)) {
+            return new DOMSignatureMethod.SHA3_512withRSAandMGF1(params);
         } else if (algorithm.equals(DOMRSAPSSSignatureMethod.RSA_PSS)) {
             return new DOMRSAPSSSignatureMethod.RSAPSS(params);
         } else if (algorithm.equals(DOMSignatureMethod.RSA_RIPEMD160_MGF1)) {
@@ -302,11 +347,16 @@
             return new DOMSignatureMethod.SHA512withECDSA(params);
         } else if (algorithm.equals(DOMSignatureMethod.ECDSA_RIPEMD160)) {
             return new DOMSignatureMethod.RIPEMD160withECDSA(params);
+        } else if (algorithm.equals(DOMSignatureMethod.ED25519)) {
+            return new DOMSignatureMethod.EDDSA_ED25519(params);
+        } else if (algorithm.equals(DOMSignatureMethod.ED448)) {
+            return new DOMSignatureMethod.EDDSA_ED448(params);
         }else {
             throw new NoSuchAlgorithmException("unsupported algorithm");
         }
     }
 
+    @Override
     public Transform newTransform(String algorithm,
         TransformParameterSpec params) throws NoSuchAlgorithmException,
         InvalidAlgorithmParameterException {
@@ -326,6 +376,7 @@
         return new DOMTransform(spi);
     }
 
+    @Override
     public Transform newTransform(String algorithm,
         XMLStructure params) throws NoSuchAlgorithmException,
         InvalidAlgorithmParameterException {
@@ -348,6 +399,7 @@
         return new DOMTransform(spi);
     }
 
+    @Override
     public CanonicalizationMethod newCanonicalizationMethod(String algorithm,
         C14NMethodParameterSpec params) throws NoSuchAlgorithmException,
         InvalidAlgorithmParameterException {
@@ -366,6 +418,7 @@
         return new DOMCanonicalizationMethod(spi);
     }
 
+    @Override
     public CanonicalizationMethod newCanonicalizationMethod(String algorithm,
         XMLStructure params) throws NoSuchAlgorithmException,
         InvalidAlgorithmParameterException {
@@ -388,6 +441,7 @@
         return new DOMCanonicalizationMethod(spi);
     }
 
+    @Override
     public URIDereferencer getURIDereferencer() {
         return DOMURIDereferencer.INSTANCE;
     }
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXPathFilter2Transform.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXPathFilter2Transform.java
index 51cbfbd..364ec49 100644
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXPathFilter2Transform.java
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXPathFilter2Transform.java
@@ -58,6 +58,7 @@
  */
 public final class DOMXPathFilter2Transform extends ApacheTransform {
 
+    @Override
     public void init(TransformParameterSpec params)
         throws InvalidAlgorithmParameterException
     {
@@ -70,6 +71,7 @@
         this.params = params;
     }
 
+    @Override
     public void init(XMLStructure parent, XMLCryptoContext context)
         throws InvalidAlgorithmParameterException
     {
@@ -125,6 +127,7 @@
         this.params = new XPathFilter2ParameterSpec(list);
     }
 
+    @Override
     public void marshalParams(XMLStructure parent, XMLCryptoContext context)
         throws MarshalException
     {
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXPathTransform.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXPathTransform.java
index b250c1f..a4970ff 100644
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXPathTransform.java
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXPathTransform.java
@@ -61,6 +61,7 @@
         this.params = params;
     }
 
+    @Override
     public void init(XMLStructure parent, XMLCryptoContext context)
         throws InvalidAlgorithmParameterException
     {
@@ -89,6 +90,7 @@
         }
     }
 
+    @Override
     public void marshalParams(XMLStructure parent, XMLCryptoContext context)
         throws MarshalException
     {
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXSLTTransform.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXSLTTransform.java
index 2551f94..467157f 100644
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXSLTTransform.java
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/DOMXSLTTransform.java
@@ -26,13 +26,16 @@
 package org.jcp.xml.dsig.internal.dom;
 
 import java.security.InvalidAlgorithmParameterException;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
 
-import javax.xml.crypto.*;
+import javax.xml.crypto.MarshalException;
+import javax.xml.crypto.XMLCryptoContext;
+import javax.xml.crypto.XMLStructure;
 import javax.xml.crypto.dsig.spec.TransformParameterSpec;
 import javax.xml.crypto.dsig.spec.XSLTTransformParameterSpec;
 
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
 /**
  * DOM-based implementation of XSLT Transform.
  * (Uses Apache XML-Sec Transform implementation)
@@ -52,6 +55,7 @@
         this.params = params;
     }
 
+    @Override
     public void init(XMLStructure parent, XMLCryptoContext context)
         throws InvalidAlgorithmParameterException {
 
@@ -64,6 +68,7 @@
             (new javax.xml.crypto.dom.DOMStructure(sheet));
     }
 
+    @Override
     public void marshalParams(XMLStructure parent, XMLCryptoContext context)
         throws MarshalException {
         super.marshalParams(parent, context);
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/Utils.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/Utils.java
index bcf28d0..1f89c79 100644
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/Utils.java
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/Utils.java
@@ -28,8 +28,12 @@
 import java.io.ByteArrayOutputStream;
 import java.io.InputStream;
 import java.io.IOException;
-import java.util.*;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
 import javax.xml.crypto.XMLCryptoContext;
+
 import org.w3c.dom.NamedNodeMap;
 import org.w3c.dom.Node;
 
diff --git a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/XMLDSigRI.java b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/XMLDSigRI.java
index 65bb25f..2982291 100644
--- a/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/XMLDSigRI.java
+++ b/src/java.xml.crypto/share/classes/org/jcp/xml/dsig/internal/dom/XMLDSigRI.java
@@ -32,10 +32,18 @@
  */
 package org.jcp.xml.dsig.internal.dom;
 
-import java.util.*;
-import java.security.*;
+import java.security.AccessController;
+import java.security.InvalidParameterException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivilegedAction;
+import java.security.Provider;
+import java.security.ProviderException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
 
-import javax.xml.crypto.dsig.*;
+import javax.xml.crypto.dsig.CanonicalizationMethod;
+import javax.xml.crypto.dsig.Transform;
 
 /**
  * The XMLDSig RI Provider.
@@ -134,7 +142,7 @@
     @SuppressWarnings("removal")
     public XMLDSigRI() {
         // This is the JDK XMLDSig provider, synced from
-        // Apache Santuario XML Security for Java, version 2.3.0
+        // Apache Santuario XML Security for Java, version 3.0.3
         super("XMLDSig", VER, INFO);
 
         final Provider p = this;
diff --git a/src/java.xml.crypto/share/legal/santuario.md b/src/java.xml.crypto/share/legal/santuario.md
index fa87128..768f0c7 100644
--- a/src/java.xml.crypto/share/legal/santuario.md
+++ b/src/java.xml.crypto/share/legal/santuario.md
@@ -1,24 +1,7 @@
-## Apache Santuario v2.3.0
-
-### Apache Santuario Notice
-<pre>
-
-  Apache Santuario - XML Security for Java
-  Copyright 1999-2021 The Apache Software Foundation
-
-  This product includes software developed at
-  The Apache Software Foundation (http://www.apache.org/).
-
-  It was originally based on software copyright (c) 2001, Institute for
-  Data Communications Systems, <http://www.nue.et-inf.uni-siegen.de/>.
-
-  The development of this software was partly funded by the European
-  Commission in the <WebSig> project in the ISIS Programme.
-
-</pre>
+## Apache Santuario v3.0.3
 
 ### Apache 2.0 License
-<pre>
+```
 
                               Apache License
                         Version 2.0, January 2004
@@ -222,4 +205,23 @@
 See the License for the specific language governing permissions and
 limitations under the License.
 
-</pre>
+```
+
+### Apache Santuario Notice
+```
+
+Apache Santuario - XML Security for Java
+Copyright 1999-2023 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+It was originally based on software copyright (c) 2001, Institute for
+Data Communications Systems, <http://www.nue.et-inf.uni-siegen.de/>.
+
+The development of this software was partly funded by the European
+Commission in the <WebSig> project in the ISIS Programme.
+
+This product contains software that is
+copyright (c) 2021, Oracle and/or its affiliates.
+```
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/dv/DatatypeException.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/dv/DatatypeException.java
index 4e99689..6b3539d 100644
--- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/dv/DatatypeException.java
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/dv/DatatypeException.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -35,7 +35,7 @@
  *
  * @author Sandy Gao, IBM
  *
- * @LastModified: Sep 2017
+ * @LastModified: Mar 2022
  */
 public class DatatypeException extends Exception {
 
@@ -107,4 +107,10 @@
 
         return msg;
     }
+
+    @Override
+    public Throwable fillInStackTrace() {
+        // This is an internal exception; the stack trace is irrelevant.
+        return this;
+    }
 }
diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaValidator.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaValidator.java
index 5bc7563..4520ca3 100644
--- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaValidator.java
+++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaValidator.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2023, Oracle and/or its affiliates. All rights reserved.
  */
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -112,7 +112,7 @@
  * @author Elena Litani IBM
  * @author Andy Clark IBM
  * @author Neeraj Bajaj, Sun Microsystems, inc.
- * @LastModified: May 2021
+ * @LastModified: Apr 2023
  */
 public class XMLSchemaValidator
     implements XMLComponent, XMLDocumentFilter, FieldActivator, RevalidationHandler, XSElementDeclHelper {
@@ -3217,10 +3217,6 @@
             // {required} is true matches one of the attribute information items in the element
             // information item's [attributes] as per clause 3.1 above.
             if (currUse.fUse == SchemaSymbols.USE_REQUIRED) {
-                if (!isSpecified)
-                    reportSchemaError(
-                        "cvc-complex-type.4",
-                        new Object[] { element.rawname, currDecl.fName });
                 if (!isSpecified) {
                     if (currDecl.fTargetNamespace != null) {
                        reportSchemaError(
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java
index 1b8b707..2a8807b 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1270,7 +1270,10 @@
             options.isSet(PROCESSOR_PATH) ||
             options.isSet(PROCESSOR_MODULE_PATH) ||
             options.isSet(PROC, "only") ||
+            options.isSet(PROC, "full") ||
+            options.isSet(A) ||
             options.isSet(XPRINT);
+        // Skipping -XprintRounds and -XprintProcessorInfo
     }
 
     public void setDeferredDiagnosticHandler(Log.DeferredDiagnosticHandler deferredDiagnosticHandler) {
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Option.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Option.java
index 033539c..41121bc 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Option.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Option.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -83,6 +83,11 @@
  * {@code handleOption} then calls {@link #process process} providing a suitable
  * {@link OptionHelper} to provide access the compiler state.
  *
+ *
+ * <p>Maintenance note: when adding new annotation processing related
+ * options, the list of options regarded as requesting explicit
+ * annotation processing in JavaCompiler should be updated.
+ *
  * <p><b>This is NOT part of any supported API.
  * If you write code that depends on this, you do so at your own
  * risk.  This code and its internal interfaces are subject to change
@@ -285,7 +290,7 @@
         }
     },
 
-    PROC("-proc:", "opt.proc.none.only", STANDARD, BASIC,  ONEOF, "none", "only"),
+    PROC("-proc:", "opt.proc.none.only", STANDARD, BASIC, ONEOF, "none", "only", "full"),
 
     PROCESSOR("-processor", "opt.arg.class.list", "opt.processor", STANDARD, BASIC),
 
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/sjavac/client/SjavacClient.java b/src/jdk.compiler/share/classes/com/sun/tools/sjavac/client/SjavacClient.java
index a9491d6..06963ac 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/sjavac/client/SjavacClient.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/sjavac/client/SjavacClient.java
@@ -69,9 +69,9 @@
     // Accept 120 seconds of inactivity before quitting.
     private static final int KEEPALIVE = 120;
     private static final int POOLSIZE = Runtime.getRuntime().availableProcessors();
-    // Wait 2 seconds for response, before giving up on javac server.
-    private static final int CONNECTION_TIMEOUT = 2000;
-    private static final int MAX_CONNECT_ATTEMPTS = 3;
+    // Wait 4 seconds for response, before giving up on javac server.
+    private static final int CONNECTION_TIMEOUT = 4000;
+    private static final int MAX_CONNECT_ATTEMPTS = 10;
     private static final int WAIT_BETWEEN_CONNECT_ATTEMPTS = 2000;
 
     public SjavacClient(Options options) {
@@ -184,7 +184,7 @@
                 Log.error("Connection attempt failed: " + ex.getMessage());
                 if (attempt >= MAX_CONNECT_ATTEMPTS) {
                     Log.error("Giving up");
-                    throw new IOException("Could not connect to server", ex);
+                    throw new IOException("Could not connect to server after " + MAX_CONNECT_ATTEMPTS + " attempts with timeout " + CONNECTION_TIMEOUT, ex);
                 }
             }
             Thread.sleep(WAIT_BETWEEN_CONNECT_ATTEMPTS);
diff --git a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_crypt.c b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_crypt.c
index 759aa20..6d8cca4 100644
--- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_crypt.c
+++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_crypt.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
  */
 
 /* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
@@ -155,7 +155,10 @@
     } else {
       outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL);
       if (outBufP == NULL) {
-          goto cleanup;
+        if (directIn == 0) {
+          (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
+        }
+        return 0;
       }
     }
 
@@ -166,15 +169,13 @@
                                     (CK_BYTE_PTR)(outBufP + jOutOfs),
                                     &ckEncryptedLen);
 
-    ckAssertReturnValueOK(env, rv);
-
-cleanup:
-    if (directIn == 0 && inBufP != NULL) {
+    if (directIn == 0) {
         (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
     }
-    if (directOut == 0 && outBufP != NULL) {
+    if (directOut == 0) {
         (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, 0);
     }
+    ckAssertReturnValueOK(env, rv);
     return ckEncryptedLen;
 }
 #endif
@@ -221,7 +222,10 @@
     } else {
       outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL);
       if (outBufP == NULL) {
-          goto cleanup;
+        if (directIn == 0) {
+          (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
+        }
+        return 0;
       }
     }
 
@@ -232,15 +236,13 @@
                                           (CK_BYTE_PTR)(outBufP + jOutOfs),
                                           &ckEncryptedPartLen);
 
-    ckAssertReturnValueOK(env, rv);
-
-cleanup:
-    if (directIn == 0 && inBufP != NULL) {
+    if (directIn == 0) {
         (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
     }
-    if (directOut == 0 && outBufP != NULL) {
+    if (directOut == 0) {
         (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, 0);
     }
+    ckAssertReturnValueOK(env, rv);
     return ckEncryptedPartLen;
 }
 #endif
@@ -391,7 +393,10 @@
     } else {
       outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL);
       if (outBufP == NULL) {
-          goto cleanup;
+        if (directIn == 0) {
+          (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
+        }
+        return 0;
       }
     }
     ckOutLen = jOutLen;
@@ -401,15 +406,13 @@
                                     (CK_BYTE_PTR)(outBufP + jOutOfs),
                                     &ckOutLen);
 
-    ckAssertReturnValueOK(env, rv);
-
-cleanup:
-    if (directIn == 0 && inBufP != NULL) {
+    if (directIn == 0) {
         (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
     }
-    if (directOut == 0 && outBufP != NULL) {
+    if (directOut == 0) {
         (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, 0);
     }
+    ckAssertReturnValueOK(env, rv);
     return ckOutLen;
 }
 #endif
@@ -456,7 +459,10 @@
     } else {
       outBufP = (*env)->GetPrimitiveArrayCritical(env, jOut, NULL);
       if (outBufP == NULL) {
-          goto cleanup;
+        if (directIn == 0) {
+          (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
+        }
+        return 0;
       }
     }
 
@@ -465,15 +471,14 @@
                                           (CK_BYTE_PTR)(inBufP + jInOfs), jInLen,
                                           (CK_BYTE_PTR)(outBufP + jOutOfs),
                                           &ckDecryptedPartLen);
-    ckAssertReturnValueOK(env, rv);
 
-cleanup:
-    if (directIn == 0 && inBufP != NULL) {
+    if (directIn == 0) {
         (*env)->ReleasePrimitiveArrayCritical(env, jIn, inBufP, JNI_ABORT);
     }
-    if (directOut == 0 && outBufP != NULL) {
+    if (directOut == 0) {
         (*env)->ReleasePrimitiveArrayCritical(env, jOut, outBufP, 0);
     }
+    ckAssertReturnValueOK(env, rv);
     return ckDecryptedPartLen;
 }
 
diff --git a/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CKey.java b/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CKey.java
index fe0fac5..801d2ad 100644
--- a/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CKey.java
+++ b/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CKey.java
@@ -75,10 +75,14 @@
 
     protected final String algorithm;
 
-    protected CKey(String algorithm, NativeHandles handles, int keyLength) {
+    private final boolean isPublic;
+
+    protected CKey(String algorithm, NativeHandles handles, int keyLength,
+            boolean isPublic) {
         this.algorithm = algorithm;
         this.handles = handles;
         this.keyLength = keyLength;
+        this.isPublic = isPublic;
     }
 
     // Native method to cleanup the key handle.
@@ -101,6 +105,18 @@
         return algorithm;
     }
 
+    public String toString() {
+        String typeStr;
+        if (handles.hCryptKey != 0) {
+            typeStr = getKeyType(handles.hCryptKey) + ", container=" +
+                    getContainerName(handles.hCryptProv);
+        } else {
+            typeStr = "CNG";
+        }
+        return algorithm + " " + (isPublic ? "PublicKey" : "PrivateKey") +
+                " [size=" + keyLength + " bits, type=" + typeStr + "]";
+    }
+
     protected native static String getContainerName(long hCryptProv);
 
     protected native static String getKeyType(long hCryptKey);
diff --git a/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CPrivateKey.java b/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CPrivateKey.java
index 91a7775..c388261 100644
--- a/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CPrivateKey.java
+++ b/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CPrivateKey.java
@@ -42,7 +42,7 @@
     private static final long serialVersionUID = 8113152807912338063L;
 
     private CPrivateKey(String alg, NativeHandles handles, int keyLength) {
-        super(alg, handles, keyLength);
+        super(alg, handles, keyLength, false);
     }
 
     // Called by native code inside security.cpp
@@ -65,16 +65,6 @@
         return null;
     }
 
-    public String toString() {
-        if (handles.hCryptKey != 0) {
-            return algorithm + "PrivateKey [size=" + keyLength + " bits, type=" +
-                    getKeyType(handles.hCryptKey) + ", container=" +
-                    getContainerName(handles.hCryptProv) + "]";
-        } else {
-            return algorithm + "PrivateKey [size=" + keyLength + " bits, type=CNG]";
-        }
-    }
-
     // This class is not serializable
     @java.io.Serial
     private void writeObject(java.io.ObjectOutputStream out)
diff --git a/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CPublicKey.java b/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CPublicKey.java
index efbd74c..7f02aa5 100644
--- a/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CPublicKey.java
+++ b/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CPublicKey.java
@@ -113,9 +113,8 @@
         }
 
         public String toString() {
-            StringBuffer sb = new StringBuffer();
-            sb.append(algorithm).append("PublicKey [size=").append(keyLength)
-                    .append("]\n  ECPoint: ").append(getW())
+            StringBuffer sb = new StringBuffer(super.toString());
+            sb.append("\n ECPoint: ").append(getW())
                     .append("\n  params: ").append(getParams());
             return sb.toString();
         }
@@ -134,16 +133,8 @@
         }
 
         public String toString() {
-            StringBuffer sb = new StringBuffer();
-            sb.append(algorithm).append("PublicKey [size=").append(keyLength)
-                    .append(" bits, type=");
-            if (handles.hCryptKey != 0) {
-                sb.append(getKeyType(handles.hCryptKey))
-                        .append(", container=").append(getContainerName(handles.hCryptProv));
-            } else {
-                sb.append("CNG");
-            }
-            sb.append("]\n  modulus: ").append(getModulus())
+            StringBuffer sb = new StringBuffer(super.toString());
+            sb.append("\n  modulus: ").append(getModulus())
                     .append("\n  public exponent: ").append(getPublicExponent());
             return sb.toString();
         }
@@ -214,7 +205,7 @@
 
     protected CPublicKey(
             String alg, NativeHandles handles, int keyLength) {
-        super(alg, handles, keyLength);
+        super(alg, handles, keyLength, true);
     }
 
     @Override
diff --git a/src/jdk.hotspot.agent/linux/native/libsaproc/ps_proc.c b/src/jdk.hotspot.agent/linux/native/libsaproc/ps_proc.c
index b5fec83..1101b99 100644
--- a/src/jdk.hotspot.agent/linux/native/libsaproc/ps_proc.c
+++ b/src/jdk.hotspot.agent/linux/native/libsaproc/ps_proc.c
@@ -125,10 +125,6 @@
 static bool process_get_lwp_regs(struct ps_prochandle* ph, pid_t pid, struct user_regs_struct *user) {
   // we have already attached to all thread 'pid's, just use ptrace call
   // to get regset now. Note that we don't cache regset upfront for processes.
-// Linux on x86 and sparc are different.  On x86 ptrace(PTRACE_GETREGS, ...)
-// uses pointer from 4th argument and ignores 3rd argument.  On sparc it uses
-// pointer from 3rd argument and ignores 4th argument
-#define ptrace_getregs(request, pid, addr, data) ptrace(request, pid, data, addr)
 
 #if defined(_LP64) && defined(PTRACE_GETREGS64)
 #define PTRACE_GETREGS_REQ PTRACE_GETREGS64
@@ -138,22 +134,22 @@
 #define PTRACE_GETREGS_REQ PT_GETREGS
 #endif
 
-#ifdef PTRACE_GETREGS_REQ
- if (ptrace_getregs(PTRACE_GETREGS_REQ, pid, user, NULL) < 0) {
+#if defined(PTRACE_GETREGSET)
+  struct iovec iov;
+  iov.iov_base = user;
+  iov.iov_len = sizeof(*user);
+  if (ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, (void*) &iov) < 0) {
+    print_debug("ptrace(PTRACE_GETREGSET, ...) failed for lwp %d\n", pid);
+    return false;
+  }
+  return true;
+#elif defined(PTRACE_GETREGS_REQ)
+ if (ptrace(PTRACE_GETREGS_REQ, pid, NULL, user) < 0) {
    print_debug("ptrace(PTRACE_GETREGS, ...) failed for lwp(%d) errno(%d) \"%s\"\n", pid,
                errno, strerror(errno));
    return false;
  }
  return true;
-#elif defined(PTRACE_GETREGSET)
- struct iovec iov;
- iov.iov_base = user;
- iov.iov_len = sizeof(*user);
- if (ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, (void*) &iov) < 0) {
-   print_debug("ptrace(PTRACE_GETREGSET, ...) failed for lwp %d\n", pid);
-   return false;
- }
- return true;
 #else
  print_debug("ptrace(PTRACE_GETREGS, ...) not supported\n");
  return false;
diff --git a/src/jdk.jartool/share/classes/sun/tools/jar/Main.java b/src/jdk.jartool/share/classes/sun/tools/jar/Main.java
index 3436c01..e97347c 100644
--- a/src/jdk.jartool/share/classes/sun/tools/jar/Main.java
+++ b/src/jdk.jartool/share/classes/sun/tools/jar/Main.java
@@ -293,6 +293,9 @@
                     }
                 }
                 expand();
+                if (!ok) {
+                    return false;
+                }
                 if (!moduleInfos.isEmpty()) {
                     // All actual file entries (excl manifest and module-info.class)
                     Set<String> jentries = new HashSet<>();
@@ -339,6 +342,9 @@
                     tmpFile = createTemporaryFile("tmpjar", ".jar");
                 }
                 expand();
+                if (!ok) {
+                    return false;
+                }
                 try (FileInputStream in = (fname != null) ? new FileInputStream(inputFile)
                         : new FileInputStream(FileDescriptor.in);
                      FileOutputStream out = new FileOutputStream(tmpFile);
diff --git a/src/jdk.jdwp.agent/share/native/libjdwp/debugInit.c b/src/jdk.jdwp.agent/share/native/libjdwp/debugInit.c
index 1ea0241..757a1c1 100644
--- a/src/jdk.jdwp.agent/share/native/libjdwp/debugInit.c
+++ b/src/jdk.jdwp.agent/share/native/libjdwp/debugInit.c
@@ -879,6 +879,9 @@
  "transport=<name>                 transport spec                    none\n"
  "address=<listen/attach address>  transport spec                    \"\"\n"
  "server=y|n                       listen for debugger?              n\n"
+ "allow=<IP|IP-list>               If server=y, allows connections only from the IP addresses/subnets specified.\n"
+ "                                 A list of multiple IP address/subnet entries must be separated by \'+\'.\n"
+ "                                                                   * (allows connection from any address)\n"
  "launch=<command line>            run debugger on event             none\n"
  "onthrow=<exception name>         debug on throw                    none\n"
  "onuncaught=y|n                   debug on any uncaught?            n\n"
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/JVM.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/JVM.java
index 8f0e8f1..3bda427 100644
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/JVM.java
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/JVM.java
@@ -266,13 +266,13 @@
     public native void setMemorySize(long size) throws IllegalArgumentException;
 
     /**
-     * Set interval for method samples, in milliseconds.
+     * Set period for method samples, in milliseconds.
      *
-     * Setting interval to 0 turns off the method sampler.
+     * Setting period to 0 turns off the method sampler.
      *
-     * @param intervalMillis the sampling interval
+     * @param periodMillis the sampling period
      */
-    public native void setMethodSamplingInterval(long type, long intervalMillis);
+    public native void setMethodSamplingPeriod(long type, long periodMillis);
 
     /**
      * Sets the file where data should be written.
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformEventType.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformEventType.java
index f20c978..f827864 100644
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformEventType.java
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformEventType.java
@@ -206,7 +206,7 @@
         if (isJVM) {
             if (isMethodSampling) {
                 long p = enabled ? period : 0;
-                JVM.getJVM().setMethodSamplingInterval(getId(), p);
+                JVM.getJVM().setMethodSamplingPeriod(getId(), p);
             } else {
                 JVM.getJVM().setEnabled(getId(), enabled);
             }
@@ -216,7 +216,7 @@
     public void setPeriod(long periodMillis, boolean beginChunk, boolean endChunk) {
         if (isMethodSampling) {
             long p = enabled ? periodMillis : 0;
-            JVM.getJVM().setMethodSamplingInterval(getId(), p);
+            JVM.getJVM().setMethodSamplingPeriod(getId(), p);
         }
         this.beginChunk = beginChunk;
         this.endChunk = endChunk;
diff --git a/src/jdk.management/share/classes/com/sun/management/ThreadMXBean.java b/src/jdk.management/share/classes/com/sun/management/ThreadMXBean.java
index 7023fab..b8518ae 100644
--- a/src/jdk.management/share/classes/com/sun/management/ThreadMXBean.java
+++ b/src/jdk.management/share/classes/com/sun/management/ThreadMXBean.java
@@ -108,6 +108,42 @@
     public long[] getThreadUserTime(long[] ids);
 
     /**
+     * Returns an approximation of the total amount of memory, in bytes, allocated
+     * in heap memory by all threads since the Java virtual machine started.
+     * The returned value is an approximation because some Java virtual machine
+     * implementations may use object allocation mechanisms that result in a
+     * delay between the time an object is allocated and the time its size is
+     * recorded.
+     *
+     * @implSpec The default implementation throws {@code UnsupportedOperationException}
+     * if the Java virtual machine implementation does not support thread
+     * memory allocation measurement, and otherwise acts as though thread
+     * memory allocation measurement is disabled.
+     *
+     * @return an approximation of the total memory allocated, in bytes, in
+     * heap memory since the Java virtual machine was started,
+     * if thread memory allocation measurement is enabled;
+     * {@code -1} otherwise.
+     *
+     * @throws UnsupportedOperationException if the Java virtual
+     *         machine implementation does not support thread memory allocation
+     *         measurement.
+     *
+     * @see #isThreadAllocatedMemorySupported
+     * @see #isThreadAllocatedMemoryEnabled
+     * @see #setThreadAllocatedMemoryEnabled
+     *
+     * @since 17.0.11
+     */
+    public default long getTotalThreadAllocatedBytes() {
+        if (!isThreadAllocatedMemorySupported()) {
+            throw new UnsupportedOperationException(
+                "Thread allocated memory measurement is not supported.");
+        }
+        return -1;
+    }
+
+    /**
      * Returns an approximation of the total amount of memory, in bytes,
      * allocated in heap memory for the current thread.
      * The returned value is an approximation because some Java virtual machine
diff --git a/src/jdk.management/share/classes/com/sun/management/internal/HotSpotThreadImpl.java b/src/jdk.management/share/classes/com/sun/management/internal/HotSpotThreadImpl.java
index 732ade8..16c3312 100644
--- a/src/jdk.management/share/classes/com/sun/management/internal/HotSpotThreadImpl.java
+++ b/src/jdk.management/share/classes/com/sun/management/internal/HotSpotThreadImpl.java
@@ -58,6 +58,11 @@
     }
 
     @Override
+    public long getTotalThreadAllocatedBytes() {
+        return super.getTotalThreadAllocatedBytes();
+    }
+
+    @Override
     public long getCurrentThreadAllocatedBytes() {
         return super.getCurrentThreadAllocatedBytes();
     }
diff --git a/test/hotspot/gtest/gtestMain.cpp b/test/hotspot/gtest/gtestMain.cpp
index ae50e96..44ab6a3 100644
--- a/test/hotspot/gtest/gtestMain.cpp
+++ b/test/hotspot/gtest/gtestMain.cpp
@@ -92,6 +92,7 @@
   JNIEnv* env;
 
   int ret = JNI_CreateJavaVM(jvm_ptr, (void**)&env, &args);
+  delete[] options;
   if (ret == JNI_OK) {
     // CreateJavaVM leaves WXExec context, while gtests
     // calls internal functions assuming running in WXWwrite.
diff --git a/test/hotspot/gtest/metaprogramming/test_primitiveConversions.cpp b/test/hotspot/gtest/metaprogramming/test_primitiveConversions.cpp
index f143e28..e9c70b1 100644
--- a/test/hotspot/gtest/metaprogramming/test_primitiveConversions.cpp
+++ b/test/hotspot/gtest/metaprogramming/test_primitiveConversions.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -171,3 +171,20 @@
   EXPECT_EQ(cpfive, PrimitiveConversions::cast<const int*>(PrimitiveConversions::cast<SIP>(cpfive)));
   EXPECT_EQ(cpfive, PrimitiveConversions::cast<const int*>(PrimitiveConversions::cast<UIP>(cpfive)));
 }
+
+TEST(PrimitiveConversionsTranslateTest, unscoped_enum) {
+  enum TestEnum : int { A, B, C };
+
+  EXPECT_TRUE(PrimitiveConversions::Translate<TestEnum>::value);
+  EXPECT_EQ(PrimitiveConversions::Translate<TestEnum>::decay(B), 1);
+  EXPECT_EQ(PrimitiveConversions::Translate<TestEnum>::recover(1), B);
+}
+
+TEST(PrimitiveConversionsTranslateTest, scoped_enum) {
+  enum class TestEnum { A, B, C };
+
+  EXPECT_TRUE(PrimitiveConversions::Translate<TestEnum>::value);
+  EXPECT_EQ(PrimitiveConversions::Translate<TestEnum>::decay(TestEnum::B), 1);
+  EXPECT_EQ(PrimitiveConversions::Translate<TestEnum>::recover(1), TestEnum::B);
+}
+
diff --git a/test/hotspot/gtest/metaspace/metaspaceGtestSparseArray.hpp b/test/hotspot/gtest/metaspace/metaspaceGtestSparseArray.hpp
index 91d3b84..4c8ad94 100644
--- a/test/hotspot/gtest/metaspace/metaspaceGtestSparseArray.hpp
+++ b/test/hotspot/gtest/metaspace/metaspaceGtestSparseArray.hpp
@@ -99,6 +99,10 @@
     }
   }
 
+  ~SparseArray() {
+    FREE_C_HEAP_ARRAY(T, _slots);
+  }
+
   T at(int i)              { return _slots[i]; }
   const T at(int i) const  { return _slots[i]; }
   void set_at(int i, T e)  { _slots[i] = e; }
diff --git a/test/hotspot/gtest/metaspace/test_freeblocks.cpp b/test/hotspot/gtest/metaspace/test_freeblocks.cpp
index e51759d..1ad14d7 100644
--- a/test/hotspot/gtest/metaspace/test_freeblocks.cpp
+++ b/test/hotspot/gtest/metaspace/test_freeblocks.cpp
@@ -79,7 +79,7 @@
     return false;
   }
 
-  void deallocate_top() {
+  bool deallocate_top() {
 
     allocation_t* a = _allocations;
     if (a != NULL) {
@@ -88,7 +88,13 @@
       _freeblocks.add_block(a->p, a->word_size);
       delete a;
       DEBUG_ONLY(_freeblocks.verify();)
+      return true;
     }
+    return false;
+  }
+
+  void deallocate_all() {
+    while (deallocate_top());
   }
 
   bool allocate() {
@@ -182,6 +188,10 @@
     CHECK_CONTENT(_freeblocks, 1, 1024);
   }
 
+  ~FreeBlocksTest() {
+    deallocate_all();
+  }
+
   static void test_small_allocations() {
     FreeBlocksTest test(10);
     test.test_loop();
diff --git a/test/hotspot/gtest/metaspace/test_virtualspacenode.cpp b/test/hotspot/gtest/metaspace/test_virtualspacenode.cpp
index f265411..e0dcbe5 100644
--- a/test/hotspot/gtest/metaspace/test_virtualspacenode.cpp
+++ b/test/hotspot/gtest/metaspace/test_virtualspacenode.cpp
@@ -532,6 +532,9 @@
   ASSERT_EQ(node->committed_words(), scomm.get());
   DEBUG_ONLY(node->verify_locked();)
 
+  delete node;
+  ASSERT_EQ(scomm.get(), (size_t)0);
+  ASSERT_EQ(sres.get(), (size_t)0);
 }
 
 // Note: we unfortunately need TEST_VM even though the system tested
diff --git a/test/hotspot/gtest/runtime/test_atomic.cpp b/test/hotspot/gtest/runtime/test_atomic.cpp
new file mode 100644
index 0000000..173cf4b
--- /dev/null
+++ b/test/hotspot/gtest/runtime/test_atomic.cpp
@@ -0,0 +1,356 @@
+/*
+ * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "runtime/atomic.hpp"
+#include "unittest.hpp"
+
+// These tests of Atomic only verify functionality.  They don't verify atomicity.
+
+template<typename T>
+struct AtomicAddTestSupport {
+  volatile T _test_value;
+
+  AtomicAddTestSupport() : _test_value{} {}
+
+  void test_add() {
+    T zero = 0;
+    T five = 5;
+    Atomic::store(&_test_value, zero);
+    T value = Atomic::add(&_test_value, five);
+    EXPECT_EQ(five, value);
+    EXPECT_EQ(five, Atomic::load(&_test_value));
+  }
+
+  void test_fetch_add() {
+    T zero = 0;
+    T five = 5;
+    Atomic::store(&_test_value, zero);
+    T value = Atomic::fetch_and_add(&_test_value, five);
+    EXPECT_EQ(zero, value);
+    EXPECT_EQ(five, Atomic::load(&_test_value));
+  }
+};
+
+TEST(AtomicAddTest, int32) {
+  using Support = AtomicAddTestSupport<int32_t>;
+  Support().test_add();
+  Support().test_fetch_add();
+}
+
+// 64bit Atomic::add is only supported on 64bit platforms.
+#ifdef _LP64
+TEST(AtomicAddTest, int64) {
+  using Support = AtomicAddTestSupport<int64_t>;
+  Support().test_add();
+  Support().test_fetch_add();
+}
+#endif // _LP64
+
+TEST(AtomicAddTest, ptr) {
+  uint _test_values[10] = {};
+  uint* volatile _test_value{};
+
+  uint* zero = &_test_values[0];
+  uint* five = &_test_values[5];
+  uint* six  = &_test_values[6];
+
+  Atomic::store(&_test_value, zero);
+  uint* value = Atomic::add(&_test_value, 5);
+  EXPECT_EQ(five, value);
+  EXPECT_EQ(five, Atomic::load(&_test_value));
+
+  Atomic::store(&_test_value, zero);
+  value = Atomic::fetch_and_add(&_test_value, 6);
+  EXPECT_EQ(zero, value);
+  EXPECT_EQ(six, Atomic::load(&_test_value));
+};
+
+template<typename T>
+struct AtomicXchgTestSupport {
+  volatile T _test_value;
+
+  AtomicXchgTestSupport() : _test_value{} {}
+
+  void test() {
+    T zero = 0;
+    T five = 5;
+    Atomic::store(&_test_value, zero);
+    T res = Atomic::xchg(&_test_value, five);
+    EXPECT_EQ(zero, res);
+    EXPECT_EQ(five, Atomic::load(&_test_value));
+  }
+};
+
+TEST(AtomicXchgTest, int32) {
+  using Support = AtomicXchgTestSupport<int32_t>;
+  Support().test();
+}
+
+// 64bit Atomic::xchg is only supported on 64bit platforms.
+#ifdef _LP64
+TEST(AtomicXchgTest, int64) {
+  using Support = AtomicXchgTestSupport<int64_t>;
+  Support().test();
+}
+#endif // _LP64
+
+template<typename T>
+struct AtomicCmpxchgTestSupport {
+  volatile T _test_value;
+
+  AtomicCmpxchgTestSupport() : _test_value{} {}
+
+  void test() {
+    T zero = 0;
+    T five = 5;
+    T ten = 10;
+    Atomic::store(&_test_value, zero);
+    T res = Atomic::cmpxchg(&_test_value, five, ten);
+    EXPECT_EQ(zero, res);
+    EXPECT_EQ(zero, Atomic::load(&_test_value));
+    res = Atomic::cmpxchg(&_test_value, zero, ten);
+    EXPECT_EQ(zero, res);
+    EXPECT_EQ(ten, Atomic::load(&_test_value));
+  }
+};
+
+TEST(AtomicCmpxchgTest, int32) {
+  using Support = AtomicCmpxchgTestSupport<int32_t>;
+  Support().test();
+}
+
+TEST(AtomicCmpxchgTest, int64) {
+  using Support = AtomicCmpxchgTestSupport<int64_t>;
+  Support().test();
+}
+
+struct AtomicCmpxchg1ByteStressSupport {
+  char _default_val;
+  int  _base;
+  char _array[7+32+7];
+
+  AtomicCmpxchg1ByteStressSupport() : _default_val(0x7a), _base(7), _array{} {}
+
+  void validate(char val, char val2, int index) {
+    for (int i = 0; i < 7; i++) {
+      EXPECT_EQ(_array[i], _default_val);
+    }
+    for (int i = 7; i < (7+32); i++) {
+      if (i == index) {
+        EXPECT_EQ(_array[i], val2);
+      } else {
+        EXPECT_EQ(_array[i], val);
+      }
+    }
+    for (int i = 0; i < 7; i++) {
+      EXPECT_EQ(_array[i], _default_val);
+    }
+  }
+
+  void test_index(int index) {
+    char one = 1;
+    Atomic::cmpxchg(&_array[index], _default_val, one);
+    validate(_default_val, one, index);
+
+    Atomic::cmpxchg(&_array[index], one, _default_val);
+    validate(_default_val, _default_val, index);
+  }
+
+  void test() {
+    memset(_array, _default_val, sizeof(_array));
+    for (int i = _base; i < (_base+32); i++) {
+      test_index(i);
+    }
+  }
+};
+
+TEST(AtomicCmpxchg1Byte, stress) {
+  AtomicCmpxchg1ByteStressSupport support;
+  support.test();
+}
+
+template<typename T>
+struct AtomicEnumTestSupport {
+  volatile T _test_value;
+
+  AtomicEnumTestSupport() : _test_value{} {}
+
+  void test_store_load(T value) {
+    EXPECT_NE(value, Atomic::load(&_test_value));
+    Atomic::store(&_test_value, value);
+    EXPECT_EQ(value, Atomic::load(&_test_value));
+  }
+
+  void test_cmpxchg(T value1, T value2) {
+    EXPECT_NE(value1, Atomic::load(&_test_value));
+    Atomic::store(&_test_value, value1);
+    EXPECT_EQ(value1, Atomic::cmpxchg(&_test_value, value2, value2));
+    EXPECT_EQ(value1, Atomic::load(&_test_value));
+    EXPECT_EQ(value1, Atomic::cmpxchg(&_test_value, value1, value2));
+    EXPECT_EQ(value2, Atomic::load(&_test_value));
+  }
+
+  void test_xchg(T value1, T value2) {
+    EXPECT_NE(value1, Atomic::load(&_test_value));
+    Atomic::store(&_test_value, value1);
+    EXPECT_EQ(value1, Atomic::xchg(&_test_value, value2));
+    EXPECT_EQ(value2, Atomic::load(&_test_value));
+  }
+};
+
+namespace AtomicEnumTestUnscoped {       // Scope the enumerators.
+  enum TestEnum { A, B, C };
+}
+
+TEST(AtomicEnumTest, unscoped_enum) {
+  using namespace AtomicEnumTestUnscoped;
+  using Support = AtomicEnumTestSupport<TestEnum>;
+
+  Support().test_store_load(B);
+  Support().test_cmpxchg(B, C);
+  Support().test_xchg(B, C);
+}
+
+enum class AtomicEnumTestScoped { A, B, C };
+
+TEST(AtomicEnumTest, scoped_enum) {
+  const AtomicEnumTestScoped B = AtomicEnumTestScoped::B;
+  const AtomicEnumTestScoped C = AtomicEnumTestScoped::C;
+  using Support = AtomicEnumTestSupport<AtomicEnumTestScoped>;
+
+  Support().test_store_load(B);
+  Support().test_cmpxchg(B, C);
+  Support().test_xchg(B, C);
+}
+
+template<typename T>
+struct AtomicBitopsTestSupport {
+  volatile T _test_value;
+
+  // At least one byte differs between _old_value and _old_value op _change_value.
+  static const T _old_value =    static_cast<T>(UCONST64(0x7f5300007f530044));
+  static const T _change_value = static_cast<T>(UCONST64(0x3800530038005322));
+
+  AtomicBitopsTestSupport() : _test_value(0) {}
+
+  void fetch_then_and() {
+    Atomic::store(&_test_value, _old_value);
+    T expected = _old_value & _change_value;
+    EXPECT_NE(_old_value, expected);
+    T result = Atomic::fetch_then_and(&_test_value, _change_value);
+    EXPECT_EQ(_old_value, result);
+    EXPECT_EQ(expected, Atomic::load(&_test_value));
+  }
+
+  void fetch_then_or() {
+    Atomic::store(&_test_value, _old_value);
+    T expected = _old_value | _change_value;
+    EXPECT_NE(_old_value, expected);
+    T result = Atomic::fetch_then_or(&_test_value, _change_value);
+    EXPECT_EQ(_old_value, result);
+    EXPECT_EQ(expected, Atomic::load(&_test_value));
+  }
+
+  void fetch_then_xor() {
+    Atomic::store(&_test_value, _old_value);
+    T expected = _old_value ^ _change_value;
+    EXPECT_NE(_old_value, expected);
+    T result = Atomic::fetch_then_xor(&_test_value, _change_value);
+    EXPECT_EQ(_old_value, result);
+    EXPECT_EQ(expected, Atomic::load(&_test_value));
+  }
+
+  void and_then_fetch() {
+    Atomic::store(&_test_value, _old_value);
+    T expected = _old_value & _change_value;
+    EXPECT_NE(_old_value, expected);
+    T result = Atomic::and_then_fetch(&_test_value, _change_value);
+    EXPECT_EQ(expected, result);
+    EXPECT_EQ(expected, Atomic::load(&_test_value));
+  }
+
+  void or_then_fetch() {
+    Atomic::store(&_test_value, _old_value);
+    T expected = _old_value | _change_value;
+    EXPECT_NE(_old_value, expected);
+    T result = Atomic::or_then_fetch(&_test_value, _change_value);
+    EXPECT_EQ(expected, result);
+    EXPECT_EQ(expected, Atomic::load(&_test_value));
+  }
+
+  void xor_then_fetch() {
+    Atomic::store(&_test_value, _old_value);
+    T expected = _old_value ^ _change_value;
+    EXPECT_NE(_old_value, expected);
+    T result = Atomic::xor_then_fetch(&_test_value, _change_value);
+    EXPECT_EQ(expected, result);
+    EXPECT_EQ(expected, Atomic::load(&_test_value));
+  }
+
+#define TEST_BITOP(name) { SCOPED_TRACE(XSTR(name)); name(); }
+
+  void operator()() {
+    TEST_BITOP(fetch_then_and)
+    TEST_BITOP(fetch_then_or)
+    TEST_BITOP(fetch_then_xor)
+    TEST_BITOP(and_then_fetch)
+    TEST_BITOP(or_then_fetch)
+    TEST_BITOP(xor_then_fetch)
+  }
+
+#undef TEST_BITOP
+};
+
+template<typename T>
+const T AtomicBitopsTestSupport<T>::_old_value;
+
+template<typename T>
+const T AtomicBitopsTestSupport<T>::_change_value;
+
+TEST(AtomicBitopsTest, int8) {
+  AtomicBitopsTestSupport<int8_t>()();
+}
+
+TEST(AtomicBitopsTest, uint8) {
+  AtomicBitopsTestSupport<uint8_t>()();
+}
+
+TEST(AtomicBitopsTest, int32) {
+  AtomicBitopsTestSupport<int32_t>()();
+}
+
+TEST(AtomicBitopsTest, uint32) {
+  AtomicBitopsTestSupport<uint32_t>()();
+}
+
+#ifdef _LP64
+TEST(AtomicBitopsTest, int64) {
+  AtomicBitopsTestSupport<int64_t>()();
+}
+
+TEST(AtomicBitopsTest, uint64) {
+  AtomicBitopsTestSupport<uint64_t>()();
+}
+#endif // _LP64
diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt
index 4291f6b..de2d126 100644
--- a/test/hotspot/jtreg/ProblemList.txt
+++ b/test/hotspot/jtreg/ProblemList.txt
@@ -138,7 +138,6 @@
 
 #############################################################################
 
-vmTestbase/nsk/monitoring/ThreadMXBean/ThreadInfo/Deadlock/JavaDeadlock001/TestDescription.java 8060733 generic-all
 
 vmTestbase/nsk/jdi/HiddenClass/events/events001.java                 8257705 generic-all
 vmTestbase/nsk/jdi/ThreadReference/stop/stop001/TestDescription.java 7034630 generic-all
@@ -152,6 +151,7 @@
 vmTestbase/nsk/jvmti/scenarios/jni_interception/JI05/ji05t001/TestDescription.java 8219652 aix-ppc64
 vmTestbase/nsk/jvmti/scenarios/jni_interception/JI06/ji06t001/TestDescription.java 8219652 aix-ppc64
 vmTestbase/nsk/jvmti/SetJNIFunctionTable/setjniftab001/TestDescription.java 8219652 aix-ppc64
+vmTestbase/nsk/jvmti/scenarios/capability/CM03/cm03t001/TestDescription.java 8073470 linux-all
 
 vmTestbase/gc/lock/jni/jnilock002/TestDescription.java 8192647 generic-all
 
diff --git a/test/hotspot/jtreg/TEST.groups b/test/hotspot/jtreg/TEST.groups
index 74fb226..f856444 100644
--- a/test/hotspot/jtreg/TEST.groups
+++ b/test/hotspot/jtreg/TEST.groups
@@ -21,6 +21,11 @@
 # questions.
 #
 
+# All tests
+
+all = \
+  :hotspot_all
+
 hotspot_all = \
   /
 
@@ -28,6 +33,8 @@
   / \
   -applications
 
+# Component test groups
+
 hotspot_compiler = \
   compiler
 
@@ -71,6 +78,13 @@
 hotspot_containers = \
   containers
 
+# Test sets for running inside container environment
+hotspot_containers_extended = \
+  runtime \
+  serviceability \
+  vmTestbase/nsk/jvmti \
+  vmTestbase/nsk/monitoring
+
 hotspot_vector_1 = \
   compiler/c2/cr6340864 \
   compiler/codegen \
diff --git a/test/hotspot/jtreg/TEST.quick-groups b/test/hotspot/jtreg/TEST.quick-groups
index e509b85..bf16315 100644
--- a/test/hotspot/jtreg/TEST.quick-groups
+++ b/test/hotspot/jtreg/TEST.quick-groups
@@ -1557,9 +1557,9 @@
   vmTestbase/gc/gctests/StringInternGC/StringInternGC.java \
   vmTestbase/gc/gctests/ReferencesGC/ReferencesGC.java \
   vmTestbase/gc/lock/jni/jnilock001/TestDescription.java \
-  vmTestbase/gc/lock/jniref/jnireflock04/TestDescription.java \
-  vmTestbase/gc/lock/jvmti/alloc/jvmtialloclock02/TestDescription.java \
-  vmTestbase/gc/lock/malloc/malloclock03/TestDescription.java
+  vmTestbase/gc/lock/jniref/jnireflock01/TestDescription.java \
+  vmTestbase/gc/lock/jvmti/alloc/jvmtialloclock01/TestDescription.java \
+  vmTestbase/gc/lock/malloc/malloclock01/TestDescription.java
 
 vmTestbase_vm_compiler_quick = \
   vmTestbase/vm/compiler/jbe/constprop/constprop01/constprop01.java \
diff --git a/test/hotspot/jtreg/applications/jcstress/JcstressRunner.java b/test/hotspot/jtreg/applications/jcstress/JcstressRunner.java
index e5d3df3..37ce9e7 100644
--- a/test/hotspot/jtreg/applications/jcstress/JcstressRunner.java
+++ b/test/hotspot/jtreg/applications/jcstress/JcstressRunner.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -42,11 +42,15 @@
  * jcstress tests wrapper
  */
 @Artifact(organization = "org.openjdk.jcstress", name = "jcstress-tests-all",
-        revision = "0.5", extension = "jar", unpack = false)
+        revision = "0.16", extension = "jar", unpack = false)
 public class JcstressRunner {
 
     public static final String MAIN_CLASS = "org.openjdk.jcstress.Main";
 
+    // Allow to configure jcstress mode parameter.
+    // Test mode preset: sanity, quick, default, tough, stress.
+    public static final String MODE_PROPERTY = "jcstress.mode";
+
     public static Path pathToArtifact() {
         Map<String, Path> artifacts;
         try {
@@ -55,7 +59,7 @@
             throw new Error("TESTBUG: Can not resolve artifacts for "
                             + JcstressRunner.class.getName(), e);
         }
-        return artifacts.get("org.openjdk.jcstress.jcstress-tests-all-0.5")
+        return artifacts.get("org.openjdk.jcstress.jcstress-tests-all-0.16")
                         .toAbsolutePath();
     }
 
@@ -104,11 +108,29 @@
 
         extraFlags.add("--jvmArgs");
         extraFlags.add("-Djava.io.tmpdir=" + System.getProperty("user.dir"));
+
+        // The "default" preset might take days for some tests
+        // so use quick testing by default.
+        String mode = "quick";
         for (String jvmArg : Utils.getTestJavaOpts()) {
+            if(jvmArg.startsWith("-D" + MODE_PROPERTY)) {
+                String[] pair = jvmArg.split("=", 2);
+                mode = pair[1];
+                continue;
+            }
             extraFlags.add("--jvmArgs");
             extraFlags.add(jvmArg);
         }
 
+        extraFlags.add("-m");
+        extraFlags.add(mode);
+
+        extraFlags.add("-sc");
+        extraFlags.add("false");
+
+        extraFlags.add("-af");
+        extraFlags.add("GLOBAL");
+
         String[] result = new String[extraFlags.size() + args.length];
         extraFlags.toArray(result);
         System.arraycopy(args, 0, result, extraFlags.size(), args.length);
diff --git a/test/hotspot/jtreg/applications/jcstress/TestGenerator.java b/test/hotspot/jtreg/applications/jcstress/TestGenerator.java
index fc7a95f..97cd6a9 100644
--- a/test/hotspot/jtreg/applications/jcstress/TestGenerator.java
+++ b/test/hotspot/jtreg/applications/jcstress/TestGenerator.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -122,7 +122,7 @@
         BufferedReader reader = Files.newBufferedReader(output);
 
         reader.lines()
-                .skip(4) // skip first 4 lines: name, -{80}, revision and empty line
+                .filter(s -> s.startsWith("org.openjdk.jcstress.tests"))
                 .map(s -> s.split("\\.")[4]) // group by the package name following "org.openjdk.jcstress.tests."
                 .distinct()
                 .filter(s -> !s.startsWith("sample")) // skip sample test
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnireflock04/TestDescription.java b/test/hotspot/jtreg/applications/jcstress/collections.java
similarity index 71%
copy from test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnireflock04/TestDescription.java
copy to test/hotspot/jtreg/applications/jcstress/collections.java
index 8e61aa3..176f004 100644
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnireflock04/TestDescription.java
+++ b/test/hotspot/jtreg/applications/jcstress/collections.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -21,16 +21,11 @@
  * questions.
  */
 
+/* DO NOT MODIFY THIS FILE. GENERATED BY applications.jcstress.TestGenerator */
 
-/*
- * @test
- * @key stress randomness
- *
- * @summary converted from VM Testbase gc/lock/jniref/jnireflock04.
- * VM Testbase keywords: [gc, stress, stressopt, nonconcurrent, quick]
- *
- * @library /vmTestbase
- *          /test/lib
- * @run main/othervm/native -XX:-UseGCOverheadLimit gc.lock.LockerTest -gp1 class -lockers jniRef
+/**
+ * @test collections
+ * @library /test/lib /
+ * @run driver/timeout=21600 applications.jcstress.JcstressRunner -v -t org.openjdk.jcstress.tests.collections\.
  */
 
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnireflock04/TestDescription.java b/test/hotspot/jtreg/applications/jcstress/mxbeans.java
similarity index 71%
rename from test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnireflock04/TestDescription.java
rename to test/hotspot/jtreg/applications/jcstress/mxbeans.java
index 8e61aa3..64f5e76 100644
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnireflock04/TestDescription.java
+++ b/test/hotspot/jtreg/applications/jcstress/mxbeans.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -21,16 +21,11 @@
  * questions.
  */
 
+/* DO NOT MODIFY THIS FILE. GENERATED BY applications.jcstress.TestGenerator */
 
-/*
- * @test
- * @key stress randomness
- *
- * @summary converted from VM Testbase gc/lock/jniref/jnireflock04.
- * VM Testbase keywords: [gc, stress, stressopt, nonconcurrent, quick]
- *
- * @library /vmTestbase
- *          /test/lib
- * @run main/othervm/native -XX:-UseGCOverheadLimit gc.lock.LockerTest -gp1 class -lockers jniRef
+/**
+ * @test mxbeans
+ * @library /test/lib /
+ * @run driver/timeout=21600 applications.jcstress.JcstressRunner -v -t org.openjdk.jcstress.tests.mxbeans\.
  */
 
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnireflock04/TestDescription.java b/test/hotspot/jtreg/applications/jcstress/oota.java
similarity index 71%
copy from test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnireflock04/TestDescription.java
copy to test/hotspot/jtreg/applications/jcstress/oota.java
index 8e61aa3..c558006 100644
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnireflock04/TestDescription.java
+++ b/test/hotspot/jtreg/applications/jcstress/oota.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -21,16 +21,11 @@
  * questions.
  */
 
+/* DO NOT MODIFY THIS FILE. GENERATED BY applications.jcstress.TestGenerator */
 
-/*
- * @test
- * @key stress randomness
- *
- * @summary converted from VM Testbase gc/lock/jniref/jnireflock04.
- * VM Testbase keywords: [gc, stress, stressopt, nonconcurrent, quick]
- *
- * @library /vmTestbase
- *          /test/lib
- * @run main/othervm/native -XX:-UseGCOverheadLimit gc.lock.LockerTest -gp1 class -lockers jniRef
+/**
+ * @test oota
+ * @library /test/lib /
+ * @run driver/timeout=21600 applications.jcstress.JcstressRunner -v -t org.openjdk.jcstress.tests.oota\.
  */
 
diff --git a/test/hotspot/jtreg/compiler/allocation/TestNewMaxLengthArray.java b/test/hotspot/jtreg/compiler/allocation/TestNewMaxLengthArray.java
new file mode 100644
index 0000000..cd2d7c4
--- /dev/null
+++ b/test/hotspot/jtreg/compiler/allocation/TestNewMaxLengthArray.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8316414
+ * @summary C2: large byte array clone triggers "failed: malformed control flow" assertion failure on linux-x86
+ * @run main/othervm  -Xcomp -XX:CompileOnly=TestNewMaxLengthArray::createAndClone TestNewMaxLengthArray
+ */
+
+public class TestNewMaxLengthArray {
+
+    // Maximum length of a byte array on a 32-bits platform using default object
+    // alignment (8 bytes).
+    static final int MAX_BYTE_ARRAY_LENGTH = 0x7ffffffc;
+
+    public static byte[] createAndClone() {
+        byte[] array = new byte[MAX_BYTE_ARRAY_LENGTH];
+        return array.clone();
+    }
+
+    public static void main(String[] a) {
+        try {
+            createAndClone();
+        } catch (OutOfMemoryError oome) {
+        }
+    }
+}
diff --git a/test/hotspot/jtreg/compiler/c1/TestLargeMonitorOffset.java b/test/hotspot/jtreg/compiler/c1/TestLargeMonitorOffset.java
new file mode 100644
index 0000000..d5cdb6b
--- /dev/null
+++ b/test/hotspot/jtreg/compiler/c1/TestLargeMonitorOffset.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8310844
+ * @summary Verify that monitors with large offset in the OSR buffer are handled properly.
+ * @run main/othervm -Xbatch -XX:CompileCommand=compileonly,TestLargeMonitorOffset::* TestLargeMonitorOffset
+ */
+
+public class TestLargeMonitorOffset {
+
+    public static void test() {
+        long l1,   l2,   l3,   l4,   l5,   l6,   l7,   l8,   l9,   l10,
+             l11,  l12,  l13,  l14,  l15,  l16,  l17,  l18,  l19,  l20,
+             l21,  l22,  l23,  l24,  l25,  l26,  l27,  l28,  l29,  l30,
+             l31,  l32,  l33,  l34,  l35,  l36,  l37,  l38,  l39,  l40,
+             l41,  l42,  l43,  l44,  l45,  l46,  l47,  l48,  l49,  l50,
+             l51,  l52,  l53,  l54,  l55,  l56,  l57,  l58,  l59,  l60,
+             l61,  l62,  l63,  l64,  l65,  l66,  l67,  l68,  l69,  l70,
+             l71,  l72,  l73,  l74,  l75,  l76,  l77,  l78,  l79,  l80,
+             l81,  l82,  l83,  l84,  l85,  l86,  l87,  l88,  l89,  l90,
+             l91,  l92,  l93,  l94,  l95,  l96,  l97,  l98,  l99,  l100,
+             l101, l102, l103, l104, l105, l106, l107, l108, l109, l110,
+             l111, l112, l113, l114, l115, l116, l117, l118, l119, l120,
+             l121, l122, l123, l124, l125, l126, l127, l128, l129, l130,
+             l131, l132, l133, l134, l135, l136, l137, l138, l139, l140,
+             l141, l142, l143, l144, l145, l146, l147, l148, l149, l150,
+             l151, l152, l153, l154, l155, l156, l157, l158, l159, l160,
+             l161, l162, l163, l164, l165, l166, l167, l168, l169, l170,
+             l171, l172, l173, l174, l175, l176, l177, l178, l179, l180,
+             l181, l182, l183, l184, l185, l186, l187, l188, l189, l190,
+             l191, l192, l193, l194, l195, l196, l197, l198, l199, l200,
+             l201, l202, l203, l204, l205, l206, l207, l208, l209, l210,
+             l211, l212, l213, l214, l215, l216, l217, l218, l219, l220,
+             l221, l222, l223, l224, l225, l226, l227, l228, l229, l230,
+             l231, l232, l233, l234, l235, l236, l237, l238, l239, l240,
+             l241, l242, l243, l244, l245, l246, l247, l248, l249, l250,
+             l251, l252, l253, l254, l255, l256, l257, l258, l259, l260,
+             l261, l262, l263, l264, l265, l266, l267, l268, l269, l270,
+             l271, l272, l273, l274, l275, l276, l277, l278, l279, l280,
+             l281, l282, l283, l284, l285, l286, l287, l288, l289, l290,
+             l291, l292, l293, l294, l295, l296, l297, l298, l299, l300,
+             l301, l302, l303, l304, l305, l306, l307, l308, l309, l310,
+             l311, l312, l313, l314, l315, l316, l317, l318, l319, l320,
+             l321, l322, l323, l324, l325, l326, l327, l328, l329, l330,
+             l331, l332, l333, l334, l335, l336, l337, l338, l339, l340,
+             l341, l342, l343, l344, l345, l346, l347, l348, l349, l350,
+             l351, l352, l353, l354, l355, l356, l357, l358, l359, l360,
+             l361, l362, l363, l364, l365, l366, l367, l368, l369, l370,
+             l371, l372, l373, l374, l375, l376, l377, l378, l379, l380,
+             l381, l382, l383, l384, l385, l386, l387, l388, l389, l390,
+             l391, l392, l393, l394, l395, l396, l397, l398, l399, l400,
+             l401, l402, l403, l404, l405, l406, l407, l408, l409, l410,
+             l411, l412, l413, l414, l415, l416, l417, l418, l419, l420,
+             l421, l422, l423, l424, l425, l426, l427, l428, l429, l430,
+             l431, l432, l433, l434, l435, l436, l437, l438, l439, l440,
+             l441, l442, l443, l444, l445, l446, l447, l448, l449, l450,
+             l451, l452, l453, l454, l455, l456, l457, l458, l459, l460,
+             l461, l462, l463, l464, l465, l466, l467, l468, l469, l470,
+             l471, l472, l473, l474, l475, l476, l477, l478, l479, l480,
+             l481, l482, l483, l484, l485, l486, l487, l488, l489, l490,
+             l491, l492, l493, l494, l495, l496, l497, l498, l499, l500,
+             l501, l502, l503, l504, l505, l506, l507, l508, l509, l510,
+             l511, l512, l513, l514, l515, l516, l517, l518, l519, l520,
+             l521, l522, l523, l524, l525, l526, l527, l528, l529, l530,
+             l531, l532, l533, l534, l535, l536, l537, l538, l539, l540,
+             l541, l542, l543, l544, l545, l546, l547, l548, l549, l550,
+             l551, l552, l553, l554, l555, l556, l557, l558, l559, l560,
+             l561, l562, l563, l564, l565, l566, l567, l568, l569, l570,
+             l571, l572, l573, l574, l575, l576, l577, l578, l579, l580,
+             l581, l582, l583, l584, l585, l586, l587, l588, l589, l590,
+             l591, l592, l593, l594, l595, l596, l597, l598, l599, l600,
+             l601, l602, l603, l604, l605, l606, l607, l608, l609, l610,
+             l611, l612, l613, l614, l615, l616, l617, l618, l619, l620,
+             l621, l622, l623, l624, l625, l626, l627, l628, l629, l630,
+             l631, l632, l633, l634, l635, l636, l637, l638, l639, l640,
+             l641, l642, l643, l644, l645, l646, l647, l648, l649, l650,
+             l651, l652, l653, l654, l655, l656, l657, l658, l659, l660,
+             l661, l662, l663, l664, l665, l666, l667, l668, l669, l670,
+             l671, l672, l673, l674, l675, l676, l677, l678, l679, l680,
+             l681, l682, l683, l684, l685, l686, l687, l688, l689, l690,
+             l691, l692, l693, l694, l695, l696, l697, l698, l699, l700,
+             l701, l702, l703, l704, l705, l706, l707, l708, l709, l710,
+             l711, l712, l713, l714, l715, l716, l717, l718, l719, l720,
+             l721, l722, l723, l724, l725, l726, l727, l728, l729, l730,
+             l731, l732, l733, l734, l735, l736, l737, l738, l739, l740,
+             l741, l742, l743, l744, l745, l746, l747, l748, l749, l750,
+             l751, l752, l753, l754, l755, l756, l757, l758, l759, l760,
+             l761, l762, l763, l764, l765, l766, l767, l768, l769, l770,
+             l771, l772, l773, l774, l775, l776, l777, l778, l779, l780,
+             l781, l782, l783, l784, l785, l786, l787, l788, l789, l790,
+             l791, l792, l793, l794, l795, l796, l797, l798, l799, l800,
+             l801, l802, l803, l804, l805, l806, l807, l808, l809, l810,
+             l811, l812, l813, l814, l815, l816, l817, l818, l819, l820,
+             l821, l822, l823, l824, l825, l826, l827, l828, l829, l830,
+             l831, l832, l833, l834, l835, l836, l837, l838, l839, l840,
+             l841, l842, l843, l844, l845, l846, l847, l848, l849, l850,
+             l851, l852, l853, l854, l855, l856, l857, l858, l859, l860,
+             l861, l862, l863, l864, l865, l866, l867, l868, l869, l870,
+             l871, l872, l873, l874, l875, l876, l877, l878, l879, l880,
+             l881, l882, l883, l884, l885, l886, l887, l888, l889, l890,
+             l891, l892, l893, l894, l895, l896, l897, l898, l899, l900,
+             l901, l902, l903, l904, l905, l906, l907, l908, l909, l910,
+             l911, l912, l913, l914, l915, l916, l917, l918, l919, l920,
+             l921, l922, l923, l924, l925, l926, l927, l928, l929, l930,
+             l931, l932, l933, l934, l935, l936, l937, l938, l939, l940,
+             l941, l942, l943, l944, l945, l946, l947, l948, l949, l950,
+             l951, l952, l953, l954, l955, l956, l957, l958, l959, l960,
+             l961, l962, l963, l964, l965, l966, l967, l968, l969, l970,
+             l971, l972, l973, l974, l975, l976, l977, l978, l979, l980,
+             l981, l982, l983, l984, l985, l986, l987, l988, l989, l990,
+             l991, l992, l993, l994, l995, l996, l997, l998, l999, l1000;
+
+        synchronized (TestLargeMonitorOffset.class) {
+            // Trigger OSR compilation with monitor in the OSR buffer
+            for (int i = 0; i < 1_000_000; ++i) {
+
+            }
+        }
+    }
+
+    public static void main(String[] args) {
+        test();
+    }
+}
diff --git a/test/hotspot/jtreg/compiler/integerArithmetic/TestNegAnd.java b/test/hotspot/jtreg/compiler/integerArithmetic/TestNegAnd.java
new file mode 100644
index 0000000..4323d5d
--- /dev/null
+++ b/test/hotspot/jtreg/compiler/integerArithmetic/TestNegAnd.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2021, Red Hat, Inc. All rights reserved.
+ * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @key randomness
+ * @bug 8274060
+ * @summary Test broken transformation (-a) & (-b) = a & b does not happen
+ *
+ * @library /test/lib
+ *
+ * @run main/othervm -XX:-TieredCompilation -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:CompileCommand=dontinline,TestNegAnd::test* TestNegAnd
+ *
+ */
+
+import java.util.Random;
+import jdk.test.lib.Utils;
+import jdk.test.lib.Asserts;
+
+public class TestNegAnd {
+    private static final Random random = Utils.getRandomInstance();
+    // Enough cycles to ensure test methods are JIT-ed
+    private static final int TEST_COUNT = 20_000;
+
+    private static int testInt(int a, int b) {
+        return (-a) & (-b);
+    }
+    private static long testLong(long a, long b) {
+        return (-a) & (-b);
+    }
+
+    private static void runIntTests() {
+        for (int index = 0; index < TEST_COUNT; index ++) {
+            int a = random.nextInt();
+            int b = random.nextInt();
+            int expected = (-a) & (-b);
+            int res = testInt(a, b);
+            Asserts.assertEQ(res, expected);
+        }
+    }
+
+    private static void runLongTests() {
+        for (int index = 0; index < TEST_COUNT; index ++) {
+            long a = random.nextLong();
+            long b = random.nextLong();
+            long expected = (-a) & (-b);
+            long res = testLong(a, b);
+            Asserts.assertEQ(res, expected);
+        }
+    }
+
+    public static void main(String[] args) {
+        runIntTests();
+        runLongTests();
+    }
+}
diff --git a/test/hotspot/jtreg/compiler/integerArithmetic/TestNegMultiply.java b/test/hotspot/jtreg/compiler/integerArithmetic/TestNegMultiply.java
new file mode 100644
index 0000000..4e84ad8
--- /dev/null
+++ b/test/hotspot/jtreg/compiler/integerArithmetic/TestNegMultiply.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2021, Red Hat, Inc. All rights reserved.
+ * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @key randomness
+ * @bug 8273454
+ * @summary Test transformation (-a)*(-b) = a*b
+ *
+ * @library /test/lib
+ *
+ * @run main/othervm -XX:-TieredCompilation -XX:-BackgroundCompilation -XX:-UseOnStackReplacement -XX:CompileCommand=dontinline,TestNegMultiply::test* TestNegMultiply
+ *
+ */
+
+import java.util.Random;
+import jdk.test.lib.Utils;
+import jdk.test.lib.Asserts;
+
+public class TestNegMultiply {
+    private static final Random random = Utils.getRandomInstance();
+    // Enough cycles to ensure test methods are JIT-ed
+    private static final int TEST_COUNT = 20_000;
+
+    private static int testInt(int a, int b) {
+        return (-a) * (-b);
+    }
+    private static long testLong(long a, long b) {
+        return (-a) * (-b);
+    }
+    private static float testFloat(float a, float b) {
+        return (-a) * (-b);
+    }
+    private static double testDouble(double a, double b) {
+        return (-a) * (-b);
+    }
+
+    private static void runIntTests() {
+        for (int index = 0; index < TEST_COUNT; index ++) {
+            int a = random.nextInt();
+            int b = random.nextInt();
+            int expected = (-a) * (-b);
+            int res = testInt(a, b);
+            Asserts.assertEQ(res, expected);
+        }
+    }
+
+    private static void runLongTests() {
+        for (int index = 0; index < TEST_COUNT; index ++) {
+            long a = random.nextLong();
+            long b = random.nextLong();
+            long expected = (-a) * (-b);
+            long res = testLong(a, b);
+            Asserts.assertEQ(res, expected);
+        }
+    }
+
+    private static void runFloatTests() {
+        for (int index = 0; index < TEST_COUNT; index ++) {
+            float a = random.nextFloat();
+            float b = random.nextFloat();
+            float expected = (-a) * (-b);
+            float res = testFloat(a, b);
+            Asserts.assertEQ(res, expected);
+        }
+    }
+
+    private static void runDoubleTests() {
+        for (int index = 0; index < TEST_COUNT; index ++) {
+            double a = random.nextDouble();
+            double b = random.nextDouble();
+            double expected = (-a) * (-b);
+            double res = testDouble(a, b);
+            Asserts.assertEQ(res, expected);
+        }
+    }
+
+    public static void main(String[] args) {
+        runIntTests();
+        runLongTests();
+        runFloatTests();
+        runDoubleTests();
+    }
+}
diff --git a/test/hotspot/jtreg/compiler/intrinsics/base64/TestBase64.java b/test/hotspot/jtreg/compiler/intrinsics/base64/TestBase64.java
index 5d2651c..0d3c956 100644
--- a/test/hotspot/jtreg/compiler/intrinsics/base64/TestBase64.java
+++ b/test/hotspot/jtreg/compiler/intrinsics/base64/TestBase64.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -46,10 +46,13 @@
 import java.util.Base64;
 import java.util.Base64.Decoder;
 import java.util.Base64.Encoder;
+import java.util.HexFormat;
 import java.util.Objects;
 import java.util.Random;
 import java.util.Arrays;
 
+import static java.lang.String.format;
+
 import compiler.whitebox.CompilerWhiteBoxTest;
 import jdk.test.whitebox.code.Compiler;
 import jtreg.SkippedException;
@@ -69,6 +72,8 @@
 
         warmup();
 
+        length_checks();
+
         test0(FileType.ASCII, Base64Type.BASIC, Base64.getEncoder(), Base64.getDecoder(),"plain.txt", "baseEncode.txt", iters);
         test0(FileType.ASCII, Base64Type.URLSAFE, Base64.getUrlEncoder(), Base64.getUrlDecoder(),"plain.txt", "urlEncode.txt", iters);
         test0(FileType.ASCII, Base64Type.MIME, Base64.getMimeEncoder(), Base64.getMimeDecoder(),"plain.txt", "mimeEncode.txt", iters);
@@ -302,4 +307,118 @@
             throw new InternalError("Internal test error: getBadBase64Char called with unknown Base64Type value");
         }
     }
+
+    static final int POSITIONS = 30_000;
+    static final int BASE_LENGTH = 256;
+    static final HexFormat HEX_FORMAT = HexFormat.of().withUpperCase().withDelimiter(" ");
+
+    static int[] plainOffsets = new int[POSITIONS + 1];
+    static byte[] plainBytes;
+    static int[] base64Offsets = new int[POSITIONS + 1];
+    static byte[] base64Bytes;
+
+    static {
+        // Set up ByteBuffer with characters to be encoded
+        int plainLength = 0;
+        for (int i = 0; i < plainOffsets.length; i++) {
+            plainOffsets[i] = plainLength;
+            int positionLength = (BASE_LENGTH + i) % 2048;
+            plainLength += positionLength;
+        }
+        // Put one of each possible byte value into ByteBuffer
+        plainBytes = new byte[plainLength];
+        for (int i = 0; i < plainBytes.length; i++) {
+            plainBytes[i] = (byte) i;
+        }
+
+        // Grab various slices of the ByteBuffer and encode them
+        ByteBuffer plainBuffer = ByteBuffer.wrap(plainBytes);
+        int base64Length = 0;
+        for (int i = 0; i < POSITIONS; i++) {
+            base64Offsets[i] = base64Length;
+            int offset = plainOffsets[i];
+            int length = plainOffsets[i + 1] - offset;
+            ByteBuffer plainSlice = plainBuffer.slice(offset, length);
+            base64Length += Base64.getEncoder().encode(plainSlice).remaining();
+        }
+
+        // Decode the slices created above and ensure lengths match
+        base64Offsets[base64Offsets.length - 1] = base64Length;
+        base64Bytes = new byte[base64Length];
+        for (int i = 0; i < POSITIONS; i++) {
+            int plainOffset = plainOffsets[i];
+            ByteBuffer plainSlice = plainBuffer.slice(plainOffset, plainOffsets[i + 1] - plainOffset);
+            ByteBuffer encodedBytes = Base64.getEncoder().encode(plainSlice);
+            int base64Offset = base64Offsets[i];
+            int expectedLength = base64Offsets[i + 1] - base64Offset;
+            if (expectedLength != encodedBytes.remaining()) {
+                throw new IllegalStateException(format("Unexpected length: %s <> %s", encodedBytes.remaining(), expectedLength));
+            }
+            encodedBytes.get(base64Bytes, base64Offset, expectedLength);
+        }
+    }
+
+    public static void length_checks() {
+        decodeAndCheck();
+        encodeDecode();
+        System.out.println("Test complete, no invalid decodes detected");
+    }
+
+    // Use ByteBuffer to cause decode() to use the base + offset form of decode
+    // Checks for bug reported in JDK-8321599 where padding characters appear
+    // within the beginning of the ByteBuffer *before* the offset.  This caused
+    // the decoded string length to be off by 1 or 2 bytes.
+    static void decodeAndCheck() {
+        for (int i = 0; i < POSITIONS; i++) {
+            ByteBuffer encodedBytes = base64BytesAtPosition(i);
+            ByteBuffer decodedBytes = Base64.getDecoder().decode(encodedBytes);
+
+            if (!decodedBytes.equals(plainBytesAtPosition(i))) {
+                String base64String = base64StringAtPosition(i);
+                String plainHexString = plainHexStringAtPosition(i);
+                String decodedHexString = HEX_FORMAT.formatHex(decodedBytes.array(), decodedBytes.arrayOffset() + decodedBytes.position(), decodedBytes.arrayOffset() + decodedBytes.limit());
+                throw new IllegalStateException(format("Mismatch for %s\n\nExpected:\n%s\n\nActual:\n%s", base64String, plainHexString, decodedHexString));
+            }
+        }
+    }
+
+    // Encode strings of lengths 1-1K, decode, and ensure length and contents correct.
+    // This checks that padding characters are properly handled by decode.
+    static void encodeDecode() {
+        String allAs = "A(=)".repeat(128);
+        for (int i = 1; i <= 512; i++) {
+            String encStr = Base64.getEncoder().encodeToString(allAs.substring(0, i).getBytes());
+            String decStr = new String(Base64.getDecoder().decode(encStr));
+
+            if ((decStr.length() != allAs.substring(0, i).length()) ||
+                (!Objects.equals(decStr, allAs.substring(0, i)))
+               ) {
+                throw new IllegalStateException(format("Mismatch: Expected: %s\n          Actual: %s\n", allAs.substring(0, i), decStr));
+            }
+        }
+    }
+
+    static ByteBuffer plainBytesAtPosition(int position) {
+        int offset = plainOffsets[position];
+        int length = plainOffsets[position + 1] - offset;
+        return ByteBuffer.wrap(plainBytes, offset, length);
+    }
+
+    static String plainHexStringAtPosition(int position) {
+        int offset = plainOffsets[position];
+        int length = plainOffsets[position + 1] - offset;
+        return HEX_FORMAT.formatHex(plainBytes, offset, offset + length);
+    }
+
+    static String base64StringAtPosition(int position) {
+        int offset = base64Offsets[position];
+        int length = base64Offsets[position + 1] - offset;
+        return new String(base64Bytes, offset, length, StandardCharsets.UTF_8);
+    }
+
+    static ByteBuffer base64BytesAtPosition(int position) {
+        int offset = base64Offsets[position];
+        int length = base64Offsets[position + 1] - offset;
+        return ByteBuffer.wrap(base64Bytes, offset, length);
+    }
 }
diff --git a/test/hotspot/jtreg/compiler/intrinsics/bigInteger/TestMulAdd.java b/test/hotspot/jtreg/compiler/intrinsics/bigInteger/TestMulAdd.java
index 416cc37..f72cc8c 100644
--- a/test/hotspot/jtreg/compiler/intrinsics/bigInteger/TestMulAdd.java
+++ b/test/hotspot/jtreg/compiler/intrinsics/bigInteger/TestMulAdd.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,11 +31,11 @@
  * @run main/othervm/timeout=600 -XX:-TieredCompilation -Xbatch
  *      -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions -XX:-UseSquareToLenIntrinsic -XX:-UseMultiplyToLenIntrinsic
  *      -XX:CompileCommand=dontinline,compiler.intrinsics.bigInteger.TestMulAdd::main
- *      -XX:CompileCommand=option,compiler.intrinsics.bigInteger.TestMulAdd::base_multiply,ccstr,DisableIntrinsic,_mulAdd
- *      -XX:CompileCommand=option,java.math.BigInteger::multiply,ccstr,DisableIntrinsic,_mulAdd
- *      -XX:CompileCommand=option,java.math.BigInteger::square,ccstr,DisableIntrinsic,_mulAdd
- *      -XX:CompileCommand=option,java.math.BigInteger::squareToLen,ccstr,DisableIntrinsic,_mulAdd
- *      -XX:CompileCommand=option,java.math.BigInteger::mulAdd,ccstr,DisableIntrinsic,_mulAdd
+ *      -XX:CompileCommand=option,compiler.intrinsics.bigInteger.TestMulAdd::base_multiply,ccstrlist,DisableIntrinsic,_mulAdd
+ *      -XX:CompileCommand=option,java.math.BigInteger::multiply,ccstrlist,DisableIntrinsic,_mulAdd
+ *      -XX:CompileCommand=option,java.math.BigInteger::square,ccstrlist,DisableIntrinsic,_mulAdd
+ *      -XX:CompileCommand=option,java.math.BigInteger::squareToLen,ccstrlist,DisableIntrinsic,_mulAdd
+ *      -XX:CompileCommand=option,java.math.BigInteger::mulAdd,ccstrlist,DisableIntrinsic,_mulAdd
  *      -XX:CompileCommand=inline,java.math.BigInteger::multiply
  *      -XX:CompileCommand=inline,java.math.BigInteger::square
  *      -XX:CompileCommand=inline,java.math.BigInteger::squareToLen
diff --git a/test/hotspot/jtreg/compiler/intrinsics/bigInteger/TestMultiplyToLen.java b/test/hotspot/jtreg/compiler/intrinsics/bigInteger/TestMultiplyToLen.java
index e0d8c38..439fb9b 100644
--- a/test/hotspot/jtreg/compiler/intrinsics/bigInteger/TestMultiplyToLen.java
+++ b/test/hotspot/jtreg/compiler/intrinsics/bigInteger/TestMultiplyToLen.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,8 +30,8 @@
  * @library /test/lib
  * @run main/othervm/timeout=600 -XX:-TieredCompilation -Xbatch
  *      -XX:CompileCommand=exclude,compiler.intrinsics.bigInteger.TestMultiplyToLen::main
- *      -XX:CompileCommand=option,compiler.intrinsics.bigInteger.TestMultiplyToLen::base_multiply,ccstr,DisableIntrinsic,_multiplyToLen
- *      -XX:CompileCommand=option,java.math.BigInteger::multiply,ccstr,DisableIntrinsic,_multiplyToLen
+ *      -XX:CompileCommand=option,compiler.intrinsics.bigInteger.TestMultiplyToLen::base_multiply,ccstrlist,DisableIntrinsic,_multiplyToLen
+ *      -XX:CompileCommand=option,java.math.BigInteger::multiply,ccstrlist,DisableIntrinsic,_multiplyToLen
  *      -XX:CompileCommand=inline,java.math.BigInteger::multiply
  *      compiler.intrinsics.bigInteger.TestMultiplyToLen
  */
diff --git a/test/hotspot/jtreg/compiler/intrinsics/bigInteger/TestShift.java b/test/hotspot/jtreg/compiler/intrinsics/bigInteger/TestShift.java
index d3833f1..fe27ceb 100644
--- a/test/hotspot/jtreg/compiler/intrinsics/bigInteger/TestShift.java
+++ b/test/hotspot/jtreg/compiler/intrinsics/bigInteger/TestShift.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,16 +31,16 @@
  *
  * @run main/othervm/timeout=600 -XX:-TieredCompilation -Xbatch
  *      -XX:CompileCommand=exclude,compiler.intrinsics.bigInteger.TestShift::main
- *      -XX:CompileCommand=option,compiler.intrinsics.bigInteger.TestShift::base_left_shift,ccstr,DisableIntrinsic,_bigIntegerLeftShiftWorker
- *      -XX:CompileCommand=option,compiler.intrinsics.bigInteger.TestShift::base_right_shift,ccstr,DisableIntrinsic,_bigIntegerRightShiftWorker
+ *      -XX:CompileCommand=option,compiler.intrinsics.bigInteger.TestShift::base_left_shift,ccstrlist,DisableIntrinsic,_bigIntegerLeftShiftWorker
+ *      -XX:CompileCommand=option,compiler.intrinsics.bigInteger.TestShift::base_right_shift,ccstrlist,DisableIntrinsic,_bigIntegerRightShiftWorker
  *      -XX:CompileCommand=inline,java.math.BigInteger::shiftLeft
  *      -XX:CompileCommand=inline,java.math.BigInteger::shiftRight
  *      compiler.intrinsics.bigInteger.TestShift
  *
  * @run main/othervm/timeout=600
  *      -XX:CompileCommand=exclude,compiler.intrinsics.bigInteger.TestShift::main
- *      -XX:CompileCommand=option,compiler.intrinsics.bigInteger.TestShift::base_left_shift,ccstr,DisableIntrinsic,_bigIntegerLeftShiftWorker
- *      -XX:CompileCommand=option,compiler.intrinsics.bigInteger.TestShift::base_right_shift,ccstr,DisableIntrinsic,_bigIntegerRightShiftWorker
+ *      -XX:CompileCommand=option,compiler.intrinsics.bigInteger.TestShift::base_left_shift,ccstrlist,DisableIntrinsic,_bigIntegerLeftShiftWorker
+ *      -XX:CompileCommand=option,compiler.intrinsics.bigInteger.TestShift::base_right_shift,ccstrlist,DisableIntrinsic,_bigIntegerRightShiftWorker
  *      -XX:CompileCommand=inline,java.math.BigInteger::shiftLeft
  *      -XX:CompileCommand=inline,java.math.BigInteger::shiftRight
  *      compiler.intrinsics.bigInteger.TestShift
diff --git a/test/hotspot/jtreg/compiler/intrinsics/bigInteger/TestSquareToLen.java b/test/hotspot/jtreg/compiler/intrinsics/bigInteger/TestSquareToLen.java
index 7ac2664..a6c8ead 100644
--- a/test/hotspot/jtreg/compiler/intrinsics/bigInteger/TestSquareToLen.java
+++ b/test/hotspot/jtreg/compiler/intrinsics/bigInteger/TestSquareToLen.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,10 +30,10 @@
  *
  * @run main/othervm/timeout=600 -XX:-TieredCompilation -Xbatch
  *      -XX:CompileCommand=exclude,compiler.intrinsics.bigInteger.TestSquareToLen::main
- *      -XX:CompileCommand=option,compiler.intrinsics.bigInteger.TestSquareToLen::base_multiply,ccstr,DisableIntrinsic,_squareToLen
- *      -XX:CompileCommand=option,java.math.BigInteger::multiply,ccstr,DisableIntrinsic,_squareToLen
- *      -XX:CompileCommand=option,java.math.BigInteger::square,ccstr,DisableIntrinsic,_squareToLen
- *      -XX:CompileCommand=option,java.math.BigInteger::squareToLen,ccstr,DisableIntrinsic,_squareToLen
+ *      -XX:CompileCommand=option,compiler.intrinsics.bigInteger.TestSquareToLen::base_multiply,ccstrlist,DisableIntrinsic,_squareToLen
+ *      -XX:CompileCommand=option,java.math.BigInteger::multiply,ccstrlist,DisableIntrinsic,_squareToLen
+ *      -XX:CompileCommand=option,java.math.BigInteger::square,ccstrlist,DisableIntrinsic,_squareToLen
+ *      -XX:CompileCommand=option,java.math.BigInteger::squareToLen,ccstrlist,DisableIntrinsic,_squareToLen
  *      -XX:CompileCommand=inline,java.math.BigInteger::multiply
  *      -XX:CompileCommand=inline,java.math.BigInteger::square
  *      -XX:CompileCommand=inline,java.math.BigInteger::squareToLen
diff --git a/test/hotspot/jtreg/compiler/intrinsics/string/TestStringIntrinsicRangeChecks.java b/test/hotspot/jtreg/compiler/intrinsics/string/TestStringIntrinsicRangeChecks.java
index 76bfda0..a7d2cfe 100644
--- a/test/hotspot/jtreg/compiler/intrinsics/string/TestStringIntrinsicRangeChecks.java
+++ b/test/hotspot/jtreg/compiler/intrinsics/string/TestStringIntrinsicRangeChecks.java
@@ -27,7 +27,7 @@
  * @summary Verifies that string intrinsics throw array out of bounds exceptions.
  * @library /compiler/patches /test/lib
  * @build java.base/java.lang.Helper
- * @run main/othervm -Xbatch -XX:CompileThreshold=100 compiler.intrinsics.string.TestStringIntrinsicRangeChecks
+ * @run main/othervm/timeout=300 -Xbatch -XX:CompileThreshold=100 compiler.intrinsics.string.TestStringIntrinsicRangeChecks
  */
 package compiler.intrinsics.string;
 
diff --git a/test/hotspot/jtreg/compiler/jsr292/methodHandleExceptions/TestAMEnotNPE.java b/test/hotspot/jtreg/compiler/jsr292/methodHandleExceptions/TestAMEnotNPE.java
index 4131db0..b6dc8c3 100644
--- a/test/hotspot/jtreg/compiler/jsr292/methodHandleExceptions/TestAMEnotNPE.java
+++ b/test/hotspot/jtreg/compiler/jsr292/methodHandleExceptions/TestAMEnotNPE.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,8 +30,12 @@
  *
  * @build p.*
  * @run main/othervm compiler.jsr292.methodHandleExceptions.TestAMEnotNPE
- * @run main/othervm -Xint compiler.jsr292.methodHandleExceptions.TestAMEnotNPE
- * @run main/othervm -Xcomp compiler.jsr292.methodHandleExceptions.TestAMEnotNPE
+ * @run main/othervm -Xint
+ *                   compiler.jsr292.methodHandleExceptions.TestAMEnotNPE
+ * @run main/othervm -Xcomp
+ *                   -XX:CompileCommand=compileonly,p.*::*
+ *                   -XX:CompileCommand=compileonly,q.*::*
+ *                   compiler.jsr292.methodHandleExceptions.TestAMEnotNPE
  */
 
 // Since this test was written the specification for interface method selection has been
diff --git a/test/hotspot/jtreg/compiler/loopopts/TestBadControlAfterPreMainPost.java b/test/hotspot/jtreg/compiler/loopopts/TestBadControlAfterPreMainPost.java
new file mode 100644
index 0000000..e3d0b56
--- /dev/null
+++ b/test/hotspot/jtreg/compiler/loopopts/TestBadControlAfterPreMainPost.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2023, Red Hat, Inc. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * bug 8315920
+ * @summary C2: "control input must dominate current control" assert failure
+ * @requires vm.compiler2.enabled
+ * @run main/othervm -XX:-BackgroundCompilation -XX:-UseLoopPredicate -XX:-DoEscapeAnalysis TestBadControlAfterPreMainPost
+ */
+
+public class TestBadControlAfterPreMainPost {
+    private static volatile int volatileField;
+
+    public static void main(String[] args) {
+        int[] array2 = new int[100];
+        for (int i = 0; i < 20_000; i++) {
+            test(1, array2);
+        }
+    }
+
+    private static int test(int j, int[] array2) {
+        int[] array = new int[10];
+        array[j] = 42;
+        float f = 1;
+        for (int i = 0; i < 100; i++) {
+            for (int k = 0; k < 10; k++) {
+            }
+            f = f * 2;
+        }
+        int v = array[0];
+        int i = 0;
+        do {
+            synchronized (new Object()) {
+            }
+            array2[i + v] = 42;
+            i++;
+        } while (i < 100);
+        return (int)f;
+    }
+}
diff --git a/test/hotspot/jtreg/compiler/loopopts/TestPeelingRemoveDominatedTest.java b/test/hotspot/jtreg/compiler/loopopts/TestPeelingRemoveDominatedTest.java
index 800adb3..2877bfe 100644
--- a/test/hotspot/jtreg/compiler/loopopts/TestPeelingRemoveDominatedTest.java
+++ b/test/hotspot/jtreg/compiler/loopopts/TestPeelingRemoveDominatedTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,7 +29,7 @@
  * @summary PhaseIdealLoop::peeled_dom_test_elim wrongly moves a non-dominated test out of a loop together with control dependent data nodes.
  *          This results in a crash due to an out of bounds read of an array.
  * @run main/othervm -XX:+UnlockDiagnosticVMOptions -Xcomp -XX:-TieredCompilation -XX:+StressGCM
- *                   -XX:CompileCommand=compileonly,compiler.loopopts.TestPeelingRemoveDominatedTest compiler.loopopts.TestPeelingRemoveDominatedTest
+ *                   -XX:CompileCommand=compileonly,compiler.loopopts.TestPeelingRemoveDominatedTest::* compiler.loopopts.TestPeelingRemoveDominatedTest
  */
 
 package compiler.loopopts;
diff --git a/test/hotspot/jtreg/compiler/loopopts/superword/TestMovingLoadBeforeStore.java b/test/hotspot/jtreg/compiler/loopopts/superword/TestMovingLoadBeforeStore.java
new file mode 100644
index 0000000..71d9050
--- /dev/null
+++ b/test/hotspot/jtreg/compiler/loopopts/superword/TestMovingLoadBeforeStore.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+/**
+ * @test
+ * @requires vm.compiler2.enabled
+ * @bug 8316679
+ * @summary In SuperWord::output, LoadVector can be moved before StoreVector, but only if it is proven to be safe.
+ * @key randomness
+ * @library /test/lib
+ * @run main/othervm -XX:CompileCommand=compileonly,compiler.loopopts.superword.TestMovingLoadBeforeStore::test*
+ *                   -Xbatch -XX:LoopUnrollLimit=100
+ *                   -XX:+UnlockDiagnosticVMOptions -XX:+StressLCM
+ *                   compiler.loopopts.superword.TestMovingLoadBeforeStore
+ */
+
+package compiler.loopopts.superword;
+import java.util.Random;
+import jdk.test.lib.Utils;
+
+public class TestMovingLoadBeforeStore {
+    static int RANGE = 1024*64;
+
+    private static final Random random = Utils.getRandomInstance();
+
+    public static void main(String[] strArr) {
+        byte a[] = new byte[RANGE];
+        for (int i = 0; i < 100; i++) {
+            for (int j = 0; j < a.length; j++) {
+                a[j] = (byte)random.nextInt();
+            }
+            byte[] a_ref = a.clone();
+            byte[] a_res = a.clone();
+            ref1(a_ref, a_ref, i % 2);
+            test1(a_res, a_res, i % 2);
+            verify("a in test1", a_ref, a_res, a);
+        }
+    }
+
+    static void verify(String name, byte[] ref, byte[] res, byte[] orig) {
+        boolean fail = false;
+        for (int j = 0; j < ref.length; j++) {
+            if (ref[j] != res[j]) {
+                System.out.println("Wrong: " + j + ":" + ref[j] + " vs " + res[j] + " from " + orig[j]);
+                fail = true;
+            }
+        }
+        if (fail) {
+            throw new RuntimeException("wrong result for array " + name);
+        }
+    }
+
+    static void test1(byte[] a, byte[] b, int inv) {
+        for (int i = 0; i < RANGE-4; i+=4) {
+            a[i + 0]++;
+            a[i + 1]++;
+            a[i + 2]++;
+            a[i + 3]++;
+            b[inv + i + 0]++;
+            b[inv + i + 1]++;
+            b[inv + i + 2]++;
+            b[inv + i + 3]++;
+        }
+    }
+
+    static void ref1(byte[] a, byte[] b, int inv) {
+        for (int i = 0; i < RANGE-4; i+=4) {
+            a[i + 0]++;
+            a[i + 1]++;
+            a[i + 2]++;
+            a[i + 3]++;
+            b[inv + i + 0]++;
+            b[inv + i + 1]++;
+            b[inv + i + 2]++;
+            b[inv + i + 3]++;
+        }
+    }
+}
diff --git a/test/hotspot/jtreg/compiler/regalloc/TestNodeRegArrayOverflow.java b/test/hotspot/jtreg/compiler/regalloc/TestNodeRegArrayOverflow.java
new file mode 100644
index 0000000..281524c
--- /dev/null
+++ b/test/hotspot/jtreg/compiler/regalloc/TestNodeRegArrayOverflow.java
@@ -0,0 +1,599 @@
+/*
+ * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package compiler.regalloc;
+
+/**
+ * @test
+ * @bug 8317507
+ * @summary Test that C2's PhaseRegAlloc::_node_regs (a post-register-allocation
+ *          mapping from machine nodes to assigned registers) does not overflow
+ *          in the face of a program with a high-density of CISC spilling
+ *          candidate nodes.
+ * @run main/othervm -Xcomp -XX:CompileOnly=compiler.regalloc.TestNodeRegArrayOverflow::testWithCompilerUnrolling
+                     -XX:CompileCommand=dontinline,compiler.regalloc.TestNodeRegArrayOverflow::dontInline
+                     compiler.regalloc.TestNodeRegArrayOverflow compiler
+ * @run main/othervm -Xcomp -XX:CompileOnly=compiler.regalloc.TestNodeRegArrayOverflow::testWithManualUnrolling
+                     -XX:CompileCommand=dontinline,compiler.regalloc.TestNodeRegArrayOverflow::dontInline
+                     compiler.regalloc.TestNodeRegArrayOverflow manual
+ */
+
+public class TestNodeRegArrayOverflow {
+
+    static int dontInline() {
+        return 0;
+    }
+
+    static float testWithCompilerUnrolling(float inc) {
+        int i = 0, j = 0;
+        // This non-inlined method call causes 'inc' to be spilled.
+        float f = dontInline();
+        // This two-level reduction loop is unrolled 512 times, which is
+        // requested by the SLP-specific unrolling analysis, but not vectorized.
+        // Because 'inc' is spilled, each of the unrolled AddF nodes is
+        // CISC-spill converted (PhaseChaitin::fixup_spills()). Before the fix,
+        // this causes the unique node index counter (Compile::_unique) to grow
+        // beyond the size of the node register array
+        // (PhaseRegAlloc::_node_regs), and leads to overflow when accessed for
+        // nodes that are created later (e.g. during the peephole phase).
+        while (i++ < 128) {
+            for (j = 0; j < 16; j++) {
+                f += inc;
+            }
+        }
+        return f;
+    }
+
+    // This test reproduces the same failure as 'testWithCompilerUnrolling'
+    // without relying on loop transformations.
+    static float testWithManualUnrolling(float inc) {
+        int i = 0, j = 0;
+        float f = dontInline();
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        f += inc;
+        return f;
+    }
+
+    public static void main(String[] args) {
+        switch (args[0]) {
+        case "compiler":
+            testWithCompilerUnrolling(0);
+            break;
+        case "manual":
+            testWithManualUnrolling(0);
+            break;
+        default:
+            throw new IllegalArgumentException("Invalid mode: " + args[0]);
+        }
+    }
+}
diff --git a/test/hotspot/jtreg/compiler/tiered/LevelTransitionTest.java b/test/hotspot/jtreg/compiler/tiered/LevelTransitionTest.java
index b18b304..336c9eb 100644
--- a/test/hotspot/jtreg/compiler/tiered/LevelTransitionTest.java
+++ b/test/hotspot/jtreg/compiler/tiered/LevelTransitionTest.java
@@ -204,7 +204,8 @@
         }
 
         private static class CompileMethodHolder {
-            private final int iter = 10;
+            // Make sure that loop backedge is never taken to prevent unexpected OSR compilations.
+            private final int iter = 1;
             private int field = 42;
 
             /**
diff --git a/test/hotspot/jtreg/containers/docker/TestMemoryWithCgroupV1.java b/test/hotspot/jtreg/containers/docker/TestMemoryWithCgroupV1.java
index aa3a902..b62f96e 100644
--- a/test/hotspot/jtreg/containers/docker/TestMemoryWithCgroupV1.java
+++ b/test/hotspot/jtreg/containers/docker/TestMemoryWithCgroupV1.java
@@ -77,6 +77,7 @@
         Common.logNewTestCase("Test print_container_info()");
 
         DockerRunOptions opts = Common.newOpts(imageName, "PrintContainerInfo").addJavaOpts("-XshowSettings:system");
+        opts.addDockerOpts("--cpus", "4"); // Avoid OOM kill on many-core systems
         opts.addDockerOpts("--memory", dockerMemLimit, "--memory-swappiness", "0", "--memory-swap", dockerSwapMemLimit);
         Common.addWhiteBoxOpts(opts);
 
@@ -104,6 +105,7 @@
             String swappiness, String expectedSwap) throws Exception {
         Common.logNewTestCase("Check OperatingSystemMXBean");
         DockerRunOptions opts = Common.newOpts(imageName, "CheckOperatingSystemMXBean")
+                .addDockerOpts("--cpus", "4") // Avoid OOM kill on many-core systems
                 .addDockerOpts(
                         "--memory", memoryAllocation,
                         "--memory-swappiness", swappiness,
diff --git a/test/hotspot/jtreg/gc/TestAllocateHeapAt.java b/test/hotspot/jtreg/gc/TestAllocateHeapAt.java
index ed3ddc2..0c80e14 100644
--- a/test/hotspot/jtreg/gc/TestAllocateHeapAt.java
+++ b/test/hotspot/jtreg/gc/TestAllocateHeapAt.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,11 +31,8 @@
  * @run driver gc.TestAllocateHeapAt
  */
 
-import jdk.test.lib.JDKToolFinder;
 import jdk.test.lib.process.ProcessTools;
 import jdk.test.lib.process.OutputAnalyzer;
-import java.util.ArrayList;
-import java.util.Collections;
 
 public class TestAllocateHeapAt {
   public static void main(String args[]) throws Exception {
diff --git a/test/hotspot/jtreg/gc/TestAllocateHeapAtMultiple.java b/test/hotspot/jtreg/gc/TestAllocateHeapAtMultiple.java
index 5956889..ddb2d95 100644
--- a/test/hotspot/jtreg/gc/TestAllocateHeapAtMultiple.java
+++ b/test/hotspot/jtreg/gc/TestAllocateHeapAtMultiple.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,7 +31,6 @@
  * @run driver/timeout=360 gc.TestAllocateHeapAtMultiple
  */
 
-import jdk.test.lib.JDKToolFinder;
 import jdk.test.lib.process.ProcessTools;
 import jdk.test.lib.process.OutputAnalyzer;
 import java.util.ArrayList;
diff --git a/test/hotspot/jtreg/gc/TestCardTablePageCommits.java b/test/hotspot/jtreg/gc/TestCardTablePageCommits.java
index 09678fd..ca14cfd 100644
--- a/test/hotspot/jtreg/gc/TestCardTablePageCommits.java
+++ b/test/hotspot/jtreg/gc/TestCardTablePageCommits.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,6 @@
 
 import jdk.test.lib.process.ProcessTools;
 import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.Platform;
 
 /*
  * @test TestCardTablePageCommits
diff --git a/test/hotspot/jtreg/gc/TestSmallHeap.java b/test/hotspot/jtreg/gc/TestSmallHeap.java
index 8bab198..f4d4486 100644
--- a/test/hotspot/jtreg/gc/TestSmallHeap.java
+++ b/test/hotspot/jtreg/gc/TestSmallHeap.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -61,8 +61,6 @@
 import jdk.test.lib.process.OutputAnalyzer;
 import jdk.test.lib.process.ProcessTools;
 
-import java.util.LinkedList;
-
 import jtreg.SkippedException;
 import jdk.test.whitebox.WhiteBox;
 import jdk.test.whitebox.gc.GC;
diff --git a/test/hotspot/jtreg/gc/arguments/TestAggressiveHeap.java b/test/hotspot/jtreg/gc/arguments/TestAggressiveHeap.java
index b929db3..8eda52a 100644
--- a/test/hotspot/jtreg/gc/arguments/TestAggressiveHeap.java
+++ b/test/hotspot/jtreg/gc/arguments/TestAggressiveHeap.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -39,7 +39,6 @@
 import javax.management.ObjectName;
 
 import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.process.ProcessTools;
 import jtreg.SkippedException;
 
 public class TestAggressiveHeap {
diff --git a/test/hotspot/jtreg/gc/arguments/TestArrayAllocatorMallocLimit.java b/test/hotspot/jtreg/gc/arguments/TestArrayAllocatorMallocLimit.java
index ca4d2d5..80f0ec4 100644
--- a/test/hotspot/jtreg/gc/arguments/TestArrayAllocatorMallocLimit.java
+++ b/test/hotspot/jtreg/gc/arguments/TestArrayAllocatorMallocLimit.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,7 +37,6 @@
 
 import jdk.test.lib.Asserts;
 import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.process.ProcessTools;
 import java.math.BigInteger;
 
 public class TestArrayAllocatorMallocLimit {
@@ -52,7 +51,7 @@
   private static final String printFlagsFinalPattern = " *size_t *" + flagName + " *:?= *(\\d+) *\\{experimental\\} *";
 
   public static void testDefaultValue()  throws Exception {
-    ProcessBuilder pb = GCArguments.createJavaProcessBuilder(
+    ProcessBuilder pb = GCArguments.createTestJvm(
       "-XX:+UnlockExperimentalVMOptions", "-XX:+PrintFlagsFinal", "-version");
 
     OutputAnalyzer output = new OutputAnalyzer(pb.start());
diff --git a/test/hotspot/jtreg/gc/arguments/TestCompressedClassFlags.java b/test/hotspot/jtreg/gc/arguments/TestCompressedClassFlags.java
index 8970892..5e5bf97 100644
--- a/test/hotspot/jtreg/gc/arguments/TestCompressedClassFlags.java
+++ b/test/hotspot/jtreg/gc/arguments/TestCompressedClassFlags.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,7 +24,6 @@
 package gc.arguments;
 
 import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.process.ProcessTools;
 import jdk.test.lib.Platform;
 
 /*
diff --git a/test/hotspot/jtreg/gc/arguments/TestG1ConcMarkStepDurationMillis.java b/test/hotspot/jtreg/gc/arguments/TestG1ConcMarkStepDurationMillis.java
index b505cdb..d5a273b 100644
--- a/test/hotspot/jtreg/gc/arguments/TestG1ConcMarkStepDurationMillis.java
+++ b/test/hotspot/jtreg/gc/arguments/TestG1ConcMarkStepDurationMillis.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -34,7 +34,6 @@
  * @run driver gc.arguments.TestG1ConcMarkStepDurationMillis
  */
 
-import jdk.test.lib.process.ProcessTools;
 import jdk.test.lib.process.OutputAnalyzer;
 import java.util.*;
 import java.util.regex.*;
diff --git a/test/hotspot/jtreg/gc/arguments/TestG1ConcRefinementThreads.java b/test/hotspot/jtreg/gc/arguments/TestG1ConcRefinementThreads.java
index 55a1f18..750dfef 100644
--- a/test/hotspot/jtreg/gc/arguments/TestG1ConcRefinementThreads.java
+++ b/test/hotspot/jtreg/gc/arguments/TestG1ConcRefinementThreads.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -36,7 +36,6 @@
  */
 
 import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.process.ProcessTools;
 import java.util.*;
 import java.util.regex.*;
 
diff --git a/test/hotspot/jtreg/gc/arguments/TestG1HeapRegionSize.java b/test/hotspot/jtreg/gc/arguments/TestG1HeapRegionSize.java
index bb8a047..9dadf41 100644
--- a/test/hotspot/jtreg/gc/arguments/TestG1HeapRegionSize.java
+++ b/test/hotspot/jtreg/gc/arguments/TestG1HeapRegionSize.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -42,7 +42,6 @@
 import java.util.Arrays;
 
 import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.process.ProcessTools;
 
 public class TestG1HeapRegionSize {
 
diff --git a/test/hotspot/jtreg/gc/arguments/TestG1PercentageOptions.java b/test/hotspot/jtreg/gc/arguments/TestG1PercentageOptions.java
index 651ace0..873f22b 100644
--- a/test/hotspot/jtreg/gc/arguments/TestG1PercentageOptions.java
+++ b/test/hotspot/jtreg/gc/arguments/TestG1PercentageOptions.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -36,7 +36,6 @@
  */
 
 import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.process.ProcessTools;
 
 public class TestG1PercentageOptions {
 
diff --git a/test/hotspot/jtreg/gc/arguments/TestHeapFreeRatio.java b/test/hotspot/jtreg/gc/arguments/TestHeapFreeRatio.java
index 3247a7c..3842c55 100644
--- a/test/hotspot/jtreg/gc/arguments/TestHeapFreeRatio.java
+++ b/test/hotspot/jtreg/gc/arguments/TestHeapFreeRatio.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -35,7 +35,6 @@
  */
 
 import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.process.ProcessTools;
 
 public class TestHeapFreeRatio {
 
diff --git a/test/hotspot/jtreg/gc/arguments/TestInitialTenuringThreshold.java b/test/hotspot/jtreg/gc/arguments/TestInitialTenuringThreshold.java
index 4f8c88b..784a69c 100644
--- a/test/hotspot/jtreg/gc/arguments/TestInitialTenuringThreshold.java
+++ b/test/hotspot/jtreg/gc/arguments/TestInitialTenuringThreshold.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,7 +37,6 @@
  */
 
 import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.process.ProcessTools;
 
 public class TestInitialTenuringThreshold {
 
diff --git a/test/hotspot/jtreg/gc/arguments/TestMaxHeapSizeTools.java b/test/hotspot/jtreg/gc/arguments/TestMaxHeapSizeTools.java
index 1b87349..70fe692 100644
--- a/test/hotspot/jtreg/gc/arguments/TestMaxHeapSizeTools.java
+++ b/test/hotspot/jtreg/gc/arguments/TestMaxHeapSizeTools.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,7 +28,6 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 
-import jdk.test.lib.process.ProcessTools;
 import jdk.test.lib.process.OutputAnalyzer;
 import jdk.test.whitebox.WhiteBox;
 
diff --git a/test/hotspot/jtreg/gc/arguments/TestMaxMinHeapFreeRatioFlags.java b/test/hotspot/jtreg/gc/arguments/TestMaxMinHeapFreeRatioFlags.java
index 591c0e4..3cf0034 100644
--- a/test/hotspot/jtreg/gc/arguments/TestMaxMinHeapFreeRatioFlags.java
+++ b/test/hotspot/jtreg/gc/arguments/TestMaxMinHeapFreeRatioFlags.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -38,7 +38,6 @@
 import java.util.Arrays;
 import java.util.Collections;
 import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.process.ProcessTools;
 import jdk.test.lib.Utils;
 import jdk.internal.misc.Unsafe;
 
diff --git a/test/hotspot/jtreg/gc/arguments/TestMaxNewSize.java b/test/hotspot/jtreg/gc/arguments/TestMaxNewSize.java
index 41ae945..0337630 100644
--- a/test/hotspot/jtreg/gc/arguments/TestMaxNewSize.java
+++ b/test/hotspot/jtreg/gc/arguments/TestMaxNewSize.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -74,7 +74,6 @@
 import java.util.Arrays;
 
 import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.process.ProcessTools;
 
 public class TestMaxNewSize {
 
diff --git a/test/hotspot/jtreg/gc/arguments/TestMaxRAMFlags.java b/test/hotspot/jtreg/gc/arguments/TestMaxRAMFlags.java
index db99552..c2802d1 100644
--- a/test/hotspot/jtreg/gc/arguments/TestMaxRAMFlags.java
+++ b/test/hotspot/jtreg/gc/arguments/TestMaxRAMFlags.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -46,7 +46,6 @@
 import java.util.Arrays;
 
 import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.process.ProcessTools;
 
 public class TestMaxRAMFlags {
 
diff --git a/test/hotspot/jtreg/gc/arguments/TestMinAndInitialSurvivorRatioFlags.java b/test/hotspot/jtreg/gc/arguments/TestMinAndInitialSurvivorRatioFlags.java
index 7e8ba31..4e18a4c 100644
--- a/test/hotspot/jtreg/gc/arguments/TestMinAndInitialSurvivorRatioFlags.java
+++ b/test/hotspot/jtreg/gc/arguments/TestMinAndInitialSurvivorRatioFlags.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -40,7 +40,6 @@
 import java.util.Collections;
 import java.util.LinkedList;
 import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.process.ProcessTools;
 import jdk.test.lib.Utils;
 import jdk.test.whitebox.WhiteBox;
 
diff --git a/test/hotspot/jtreg/gc/arguments/TestNewRatioFlag.java b/test/hotspot/jtreg/gc/arguments/TestNewRatioFlag.java
index 73cf5b2..49ce08e 100644
--- a/test/hotspot/jtreg/gc/arguments/TestNewRatioFlag.java
+++ b/test/hotspot/jtreg/gc/arguments/TestNewRatioFlag.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -40,7 +40,6 @@
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.LinkedList;
-import jdk.test.lib.process.ProcessTools;
 import jdk.test.lib.process.OutputAnalyzer;
 import jdk.test.lib.Utils;
 import jdk.test.whitebox.WhiteBox;
diff --git a/test/hotspot/jtreg/gc/arguments/TestNewSizeFlags.java b/test/hotspot/jtreg/gc/arguments/TestNewSizeFlags.java
index f51c11e..70a124e 100644
--- a/test/hotspot/jtreg/gc/arguments/TestNewSizeFlags.java
+++ b/test/hotspot/jtreg/gc/arguments/TestNewSizeFlags.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -43,7 +43,6 @@
 import java.util.Collections;
 import java.util.LinkedList;
 import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.process.ProcessTools;
 import jdk.test.lib.Utils;
 import jdk.test.whitebox.WhiteBox;
 
diff --git a/test/hotspot/jtreg/gc/arguments/TestNewSizeThreadIncrease.java b/test/hotspot/jtreg/gc/arguments/TestNewSizeThreadIncrease.java
index 1f340de..be69ff2 100644
--- a/test/hotspot/jtreg/gc/arguments/TestNewSizeThreadIncrease.java
+++ b/test/hotspot/jtreg/gc/arguments/TestNewSizeThreadIncrease.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -38,8 +38,6 @@
 
 import jdk.test.lib.Platform;
 import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.process.ProcessTools;
-
 
 // Range of NewSizeThreadIncrease is 0 ~ max_uintx.
 // Total of 5 threads will be created (1 GCTest thread and 4 TestThread).
diff --git a/test/hotspot/jtreg/gc/arguments/TestObjectTenuringFlags.java b/test/hotspot/jtreg/gc/arguments/TestObjectTenuringFlags.java
index 7baf3c8..0a2c8c1 100644
--- a/test/hotspot/jtreg/gc/arguments/TestObjectTenuringFlags.java
+++ b/test/hotspot/jtreg/gc/arguments/TestObjectTenuringFlags.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,7 +37,6 @@
  */
 
 import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.process.ProcessTools;
 
 import java.util.*;
 
diff --git a/test/hotspot/jtreg/gc/arguments/TestParallelGCThreads.java b/test/hotspot/jtreg/gc/arguments/TestParallelGCThreads.java
index aca3516..c964115 100644
--- a/test/hotspot/jtreg/gc/arguments/TestParallelGCThreads.java
+++ b/test/hotspot/jtreg/gc/arguments/TestParallelGCThreads.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -40,7 +40,6 @@
 import java.util.List;
 import jdk.test.lib.Asserts;
 import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.process.ProcessTools;
 import jtreg.SkippedException;
 import jdk.test.whitebox.gc.GC;
 
diff --git a/test/hotspot/jtreg/gc/arguments/TestSelectDefaultGC.java b/test/hotspot/jtreg/gc/arguments/TestSelectDefaultGC.java
index 0ec4718..dfa3bbf 100644
--- a/test/hotspot/jtreg/gc/arguments/TestSelectDefaultGC.java
+++ b/test/hotspot/jtreg/gc/arguments/TestSelectDefaultGC.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -36,7 +36,6 @@
  */
 
 import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.process.ProcessTools;
 
 public class TestSelectDefaultGC {
     public static void assertVMOption(OutputAnalyzer output, String option, boolean value) {
diff --git a/test/hotspot/jtreg/gc/arguments/TestSmallInitialHeapWithLargePageAndNUMA.java b/test/hotspot/jtreg/gc/arguments/TestSmallInitialHeapWithLargePageAndNUMA.java
index 9612247..df67832 100644
--- a/test/hotspot/jtreg/gc/arguments/TestSmallInitialHeapWithLargePageAndNUMA.java
+++ b/test/hotspot/jtreg/gc/arguments/TestSmallInitialHeapWithLargePageAndNUMA.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -38,7 +38,6 @@
  * @run main/othervm -Xbootclasspath/a:. -XX:+UseHugeTLBFS -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI gc.arguments.TestSmallInitialHeapWithLargePageAndNUMA
 */
 
-import jdk.test.lib.process.ProcessTools;
 import jdk.test.lib.process.OutputAnalyzer;
 import jdk.test.whitebox.WhiteBox;
 import jtreg.SkippedException;
diff --git a/test/hotspot/jtreg/gc/arguments/TestSurvivorRatioFlag.java b/test/hotspot/jtreg/gc/arguments/TestSurvivorRatioFlag.java
index 7cf50b3..1a2246b 100644
--- a/test/hotspot/jtreg/gc/arguments/TestSurvivorRatioFlag.java
+++ b/test/hotspot/jtreg/gc/arguments/TestSurvivorRatioFlag.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -41,7 +41,6 @@
 import java.util.Collections;
 import java.util.LinkedList;
 import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.process.ProcessTools;
 import jdk.test.lib.Utils;
 import jdk.test.whitebox.WhiteBox;
 
diff --git a/test/hotspot/jtreg/gc/arguments/TestUnrecognizedVMOptionsHandling.java b/test/hotspot/jtreg/gc/arguments/TestUnrecognizedVMOptionsHandling.java
index 53641ce..0e71b86 100644
--- a/test/hotspot/jtreg/gc/arguments/TestUnrecognizedVMOptionsHandling.java
+++ b/test/hotspot/jtreg/gc/arguments/TestUnrecognizedVMOptionsHandling.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -35,7 +35,6 @@
  */
 
 import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.process.ProcessTools;
 
 public class TestUnrecognizedVMOptionsHandling {
 
diff --git a/test/hotspot/jtreg/gc/arguments/TestUseCompressedOopsErgoTools.java b/test/hotspot/jtreg/gc/arguments/TestUseCompressedOopsErgoTools.java
index 234fbd7..8979b92 100644
--- a/test/hotspot/jtreg/gc/arguments/TestUseCompressedOopsErgoTools.java
+++ b/test/hotspot/jtreg/gc/arguments/TestUseCompressedOopsErgoTools.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,7 +32,6 @@
 import java.util.Arrays;
 
 import jdk.test.lib.Asserts;
-import jdk.test.lib.process.ProcessTools;
 import jdk.test.lib.process.OutputAnalyzer;
 import java.lang.management.ManagementFactory;
 import jdk.test.whitebox.WhiteBox;
diff --git a/test/hotspot/jtreg/gc/arguments/TestUseNUMAInterleaving.java b/test/hotspot/jtreg/gc/arguments/TestUseNUMAInterleaving.java
index 9a88db2..7f38575 100644
--- a/test/hotspot/jtreg/gc/arguments/TestUseNUMAInterleaving.java
+++ b/test/hotspot/jtreg/gc/arguments/TestUseNUMAInterleaving.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -35,7 +35,6 @@
  * @run driver gc.arguments.TestUseNUMAInterleaving
  */
 import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.process.ProcessTools;
 
 public class TestUseNUMAInterleaving {
 
diff --git a/test/hotspot/jtreg/gc/arguments/TestVerifyBeforeAndAfterGCFlags.java b/test/hotspot/jtreg/gc/arguments/TestVerifyBeforeAndAfterGCFlags.java
index 4ff145e..5b33dcd 100644
--- a/test/hotspot/jtreg/gc/arguments/TestVerifyBeforeAndAfterGCFlags.java
+++ b/test/hotspot/jtreg/gc/arguments/TestVerifyBeforeAndAfterGCFlags.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -42,7 +42,6 @@
 
 import jdk.test.lib.Utils;
 import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.process.ProcessTools;
 
 public class TestVerifyBeforeAndAfterGCFlags {
 
diff --git a/test/hotspot/jtreg/gc/cslocker/TestCSLocker.java b/test/hotspot/jtreg/gc/cslocker/TestCSLocker.java
index 43cfea8..1627ae8 100644
--- a/test/hotspot/jtreg/gc/cslocker/TestCSLocker.java
+++ b/test/hotspot/jtreg/gc/cslocker/TestCSLocker.java
@@ -48,10 +48,13 @@
         // start CS locker thread
         CSLocker csLocker = new CSLocker();
         csLocker.start();
+        // After the CSLocker thread has started, any operation such as an allocation,
+        // which could rely on the GC to make progress, will cause a deadlock that will
+        // make the test time out. That includes printing. Please don't use any such
+        // code until unlock() is called below.
 
         // check timeout to success deadlocking
-        while(System.currentTimeMillis() < startTime + timeout) {
-            System.out.println("sleeping...");
+        while (System.currentTimeMillis() < startTime + timeout) {
             sleep(1000);
         }
 
diff --git a/test/hotspot/jtreg/gc/epsilon/TestClasses.java b/test/hotspot/jtreg/gc/epsilon/TestClasses.java
index aa081ee..53e1bab 100644
--- a/test/hotspot/jtreg/gc/epsilon/TestClasses.java
+++ b/test/hotspot/jtreg/gc/epsilon/TestClasses.java
@@ -40,11 +40,6 @@
 import jdk.internal.org.objectweb.asm.ClassWriter;
 import jdk.internal.org.objectweb.asm.Opcodes;
 
-import java.util.*;
-import java.io.*;
-import java.nio.*;
-import java.nio.file.*;
-
 public class TestClasses {
 
   static final int CLASSES = 1024;
diff --git a/test/hotspot/jtreg/gc/g1/TestShrinkAuxiliaryData.java b/test/hotspot/jtreg/gc/g1/TestShrinkAuxiliaryData.java
index 6bf1c8f..1b38c2d 100644
--- a/test/hotspot/jtreg/gc/g1/TestShrinkAuxiliaryData.java
+++ b/test/hotspot/jtreg/gc/g1/TestShrinkAuxiliaryData.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,7 +30,6 @@
 import jdk.test.lib.process.OutputAnalyzer;
 import jtreg.SkippedException;
 
-import java.io.IOException;
 import java.lang.management.ManagementFactory;
 import java.lang.management.MemoryUsage;
 import java.text.DecimalFormat;
diff --git a/test/hotspot/jtreg/gc/g1/TestSkipRebuildRemsetPhase.java b/test/hotspot/jtreg/gc/g1/TestSkipRebuildRemsetPhase.java
index ba76bd5..860d3ce 100644
--- a/test/hotspot/jtreg/gc/g1/TestSkipRebuildRemsetPhase.java
+++ b/test/hotspot/jtreg/gc/g1/TestSkipRebuildRemsetPhase.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -34,12 +34,8 @@
  * @run driver gc.g1.TestSkipRebuildRemsetPhase
  */
 
-import java.util.regex.Pattern;
-import java.util.regex.Matcher;
-
 import jdk.test.lib.process.OutputAnalyzer;
 import jdk.test.lib.process.ProcessTools;
-import jdk.test.lib.Asserts;
 import jdk.test.whitebox.WhiteBox;
 
 public class TestSkipRebuildRemsetPhase {
diff --git a/test/hotspot/jtreg/gc/stress/gclocker/TestExcessGCLockerCollections.java b/test/hotspot/jtreg/gc/stress/gclocker/TestExcessGCLockerCollections.java
index 6bbcc6b..8b6326b 100644
--- a/test/hotspot/jtreg/gc/stress/gclocker/TestExcessGCLockerCollections.java
+++ b/test/hotspot/jtreg/gc/stress/gclocker/TestExcessGCLockerCollections.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -44,7 +44,6 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 
-import jdk.test.lib.Asserts;
 import jdk.test.lib.process.ProcessTools;
 import jdk.test.lib.process.OutputAnalyzer;
 
diff --git a/test/hotspot/jtreg/jbFdProblemList.txt b/test/hotspot/jtreg/jbFdProblemList.txt
index 0f4ab7a..d383a73 100644
--- a/test/hotspot/jtreg/jbFdProblemList.txt
+++ b/test/hotspot/jtreg/jbFdProblemList.txt
@@ -87,6 +87,5 @@
 #############################################################################
 
 vmTestbase/gc/gctests/LargeObjects/large002/TestDescription.java NOBUG linux-all timeout
-vmTestbase/gc/gctests/StringInternSyncWithGC/StringInternSyncWithGC.java NOBUG macosx-all timeout on macstudio
 
 vmTestbase/jit/misctests/fpustack/GraphApplet.java NOBUG windows-aarch64 timeout
diff --git a/test/hotspot/jtreg/jbProblemList.txt b/test/hotspot/jtreg/jbProblemList.txt
index b18acea..49d1e64 100644
--- a/test/hotspot/jtreg/jbProblemList.txt
+++ b/test/hotspot/jtreg/jbProblemList.txt
@@ -61,6 +61,7 @@
 gc/stress/TestReclaimStringsLeaksMemory.java initial_run windows-all
 
 gc/shenandoah/TestAllocHumongousFragment.java#aggressive 8309622 generic-all
+gc/shenandoah/TestAllocHumongousFragment.java#iu-aggressive 8309622 generic-all
 gc/shenandoah/TestAllocIntArrays.java#iu-aggressive 8309622 generic-all
 gc/shenandoah/TestAllocObjects.java#aggressive initial_run generic-all
 gc/shenandoah/TestAllocObjects.java#iu-aggressive initial_run generic-all
@@ -211,7 +212,9 @@
 vmTestbase/nsk/jdi/VirtualMachine/canGetBytecodes/cangetbytecodes001/TestDescription.java time_out_intermittent macosx-aarch64
 vmTestbase/nsk/jdi/VirtualMachine/canGetCurrentContendedMonitor/cangccm001/TestDescription.java time_out_intermittent macosx-aarch64
 vmTestbase/nsk/jdi/VirtualMachine/canGetMonitorInfo/cangetmonitorinfo001/TestDescription.java JBR-6361 macosx-aarch64
+vmTestbase/nsk/jdi/VirtualMachine/canGetOwnedMonitorInfo/cangetinfo001/TestDescription.java JBR-6831 macosx-aarch64
 vmTestbase/nsk/jdi/VirtualMachine/canGetSourceDebugExtension/cangetsde001/TestDescription.java JBR-6645 macosx-aarch64
+vmTestbase/nsk/jdi/VirtualMachine/canGetSyntheticAttribute/cangetattr001/TestDescription.java JBR-6840 macosx-aarch64
 
 vmTestbase/metaspace/gc/firstGC_10m/TestDescription.java 8208250 generic-all
 vmTestbase/metaspace/gc/firstGC_50m/TestDescription.java 8208250 generic-all
@@ -227,6 +230,7 @@
 vmTestbase/nsk/jvmti/scenarios/sampling/SP04/sp04t002/TestDescription.java initial_run windows-x64
 vmTestbase/nsk/jvmti/scenarios/sampling/SP05/sp05t003/TestDescription.java initial_run generic-all
 
+vmTestbase/gc/gctests/StringInternSyncWithGC/StringInternSyncWithGC.java JBR-6841 macosx-all timeout on macstudio
 vmTestbase/gc/lock/jni/jnilock002/TestDescription.java 8192647 generic-all
 
 vmTestbase/jit/escape/LockCoarsening/LockCoarsening001.java 8148743 generic-all
diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/BadNativeStackInErrorHandlingTest.java b/test/hotspot/jtreg/runtime/ErrorHandling/BadNativeStackInErrorHandlingTest.java
index 64faead..a51a891 100644
--- a/test/hotspot/jtreg/runtime/ErrorHandling/BadNativeStackInErrorHandlingTest.java
+++ b/test/hotspot/jtreg/runtime/ErrorHandling/BadNativeStackInErrorHandlingTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -35,6 +35,7 @@
  * @bug 8194652
  * @summary Printing native stack shows an "error occurred during error reporting".
  * @modules java.base/jdk.internal.misc
+ * @requires vm.flagless
  * @requires vm.debug
  * @requires vm.flavor != "zero"
  * @library /test/lib
diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/ErrorFileOverwriteTest.java b/test/hotspot/jtreg/runtime/ErrorHandling/ErrorFileOverwriteTest.java
index c9b9e43..ea8e944 100644
--- a/test/hotspot/jtreg/runtime/ErrorHandling/ErrorFileOverwriteTest.java
+++ b/test/hotspot/jtreg/runtime/ErrorHandling/ErrorFileOverwriteTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2019, SAP. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -30,6 +30,7 @@
  *           in the error file name)
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
+ * @requires vm.flagless
  * @requires (vm.debug == true)
  * @run driver ErrorFileOverwriteTest
  */
diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/ErrorFileRedirectTest.java b/test/hotspot/jtreg/runtime/ErrorHandling/ErrorFileRedirectTest.java
index 154d5cf..3c32c6f 100644
--- a/test/hotspot/jtreg/runtime/ErrorHandling/ErrorFileRedirectTest.java
+++ b/test/hotspot/jtreg/runtime/ErrorHandling/ErrorFileRedirectTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2019, SAP. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -29,6 +29,7 @@
  * @summary Test ErrorFileToStderr and ErrorFileToStdout
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
+ * @requires vm.flagless
  * @requires (vm.debug == true)
  * @run driver ErrorFileRedirectTest
  */
diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/MachCodeFramesInErrorFile.java b/test/hotspot/jtreg/runtime/ErrorHandling/MachCodeFramesInErrorFile.java
index 0095c83..1e91c25 100644
--- a/test/hotspot/jtreg/runtime/ErrorHandling/MachCodeFramesInErrorFile.java
+++ b/test/hotspot/jtreg/runtime/ErrorHandling/MachCodeFramesInErrorFile.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
 /*
  * @test
  * @bug 8272586
+ * @requires vm.flagless
  * @requires vm.compiler2.enabled
  * @summary Test that abstract machine code is dumped for the top frames in a hs-err log
  * @library /test/lib
diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/NestedThreadsListHandleInErrorHandlingTest.java b/test/hotspot/jtreg/runtime/ErrorHandling/NestedThreadsListHandleInErrorHandlingTest.java
index d21c8a0..c897de4 100644
--- a/test/hotspot/jtreg/runtime/ErrorHandling/NestedThreadsListHandleInErrorHandlingTest.java
+++ b/test/hotspot/jtreg/runtime/ErrorHandling/NestedThreadsListHandleInErrorHandlingTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,6 +33,7 @@
 
 /*
  * @test
+ * @requires vm.flagless
  * @requires (vm.debug == true)
  * @bug 8167108
  * @summary Nested ThreadsListHandle info should be in error handling output.
diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/ProblematicFrameTest.java b/test/hotspot/jtreg/runtime/ErrorHandling/ProblematicFrameTest.java
index 0f0b48b..dc54b09 100644
--- a/test/hotspot/jtreg/runtime/ErrorHandling/ProblematicFrameTest.java
+++ b/test/hotspot/jtreg/runtime/ErrorHandling/ProblematicFrameTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,6 +30,7 @@
  *          java.compiler
  *          java.management
  *          jdk.internal.jvmstat/sun.jvmstat.monitor
+ * @requires vm.flagless
  * @run driver ProblematicFrameTest
  */
 
diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/SafeFetchInErrorHandlingTest.java b/test/hotspot/jtreg/runtime/ErrorHandling/SafeFetchInErrorHandlingTest.java
index 8f3419d..241d418 100644
--- a/test/hotspot/jtreg/runtime/ErrorHandling/SafeFetchInErrorHandlingTest.java
+++ b/test/hotspot/jtreg/runtime/ErrorHandling/SafeFetchInErrorHandlingTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -36,6 +36,7 @@
  * @summary SafeFetch32 and SafeFetchN do not work in error handling
  * @modules java.base/jdk.internal.misc
  * @library /test/lib
+ * @requires vm.flagless
  * @requires vm.debug
  * @requires vm.flavor != "zero"
  * @author Thomas Stuefe (SAP)
diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/SecondaryErrorTest.java b/test/hotspot/jtreg/runtime/ErrorHandling/SecondaryErrorTest.java
index 7790d06..8fa7fd5 100644
--- a/test/hotspot/jtreg/runtime/ErrorHandling/SecondaryErrorTest.java
+++ b/test/hotspot/jtreg/runtime/ErrorHandling/SecondaryErrorTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
  * @bug 8065896
  * @summary Synchronous signals during error reporting may terminate or hang VM process
  * @library /test/lib
+ * @requires vm.flagless
  * @requires vm.debug
  * @requires os.family != "windows"
  * @author Thomas Stuefe (SAP)
diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/ShowRegistersOnAssertTest.java b/test/hotspot/jtreg/runtime/ErrorHandling/ShowRegistersOnAssertTest.java
index f0e4456..098818e 100644
--- a/test/hotspot/jtreg/runtime/ErrorHandling/ShowRegistersOnAssertTest.java
+++ b/test/hotspot/jtreg/runtime/ErrorHandling/ShowRegistersOnAssertTest.java
@@ -27,6 +27,7 @@
  * @bug 8191101
  * @summary Show Registers on assert/guarantee
  * @library /test/lib
+ * @requires vm.flagless
  * @requires (vm.debug == true) & (os.family == "linux")
  * @author Thomas Stuefe (SAP)
  * @modules java.base/jdk.internal.misc
diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/TestCrashOnOutOfMemoryError.java b/test/hotspot/jtreg/runtime/ErrorHandling/TestCrashOnOutOfMemoryError.java
index 3ef7c86..2b33f4f 100644
--- a/test/hotspot/jtreg/runtime/ErrorHandling/TestCrashOnOutOfMemoryError.java
+++ b/test/hotspot/jtreg/runtime/ErrorHandling/TestCrashOnOutOfMemoryError.java
@@ -26,6 +26,7 @@
  * @summary Test using -XX:+CrashOnOutOfMemoryError
  * @modules java.base/jdk.internal.misc
  * @library /test/lib
+ * @requires vm.flagless
  * @run driver TestCrashOnOutOfMemoryError
  * @bug 8138745
  */
diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/TestExitOnOutOfMemoryError.java b/test/hotspot/jtreg/runtime/ErrorHandling/TestExitOnOutOfMemoryError.java
index 2159442..e56ed4a 100644
--- a/test/hotspot/jtreg/runtime/ErrorHandling/TestExitOnOutOfMemoryError.java
+++ b/test/hotspot/jtreg/runtime/ErrorHandling/TestExitOnOutOfMemoryError.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
  * @summary Test using -XX:ExitOnOutOfMemoryError
  * @modules java.base/jdk.internal.misc
  * @library /test/lib
+ * @requires vm.flagless
  * @run driver TestExitOnOutOfMemoryError
  * @bug 8138745
  */
diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/TestGZippedHeapDumpOnOutOfMemoryError.java b/test/hotspot/jtreg/runtime/ErrorHandling/TestGZippedHeapDumpOnOutOfMemoryError.java
index 40f6a6e..a2a0154 100644
--- a/test/hotspot/jtreg/runtime/ErrorHandling/TestGZippedHeapDumpOnOutOfMemoryError.java
+++ b/test/hotspot/jtreg/runtime/ErrorHandling/TestGZippedHeapDumpOnOutOfMemoryError.java
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2021 SAP SE. All rights reserved.
+ * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,6 +33,7 @@
  * @test
  * @summary Test verifies that -XX:HeapDumpGzipLevel=1 works
  * @library /test/lib
+ * @requires vm.flagless
  * @run driver/timeout=240 TestGZippedHeapDumpOnOutOfMemoryError run 1
  */
 
diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/TestHeapDumpOnOutOfMemoryError.java b/test/hotspot/jtreg/runtime/ErrorHandling/TestHeapDumpOnOutOfMemoryError.java
index d5293cd..9324adb 100644
--- a/test/hotspot/jtreg/runtime/ErrorHandling/TestHeapDumpOnOutOfMemoryError.java
+++ b/test/hotspot/jtreg/runtime/ErrorHandling/TestHeapDumpOnOutOfMemoryError.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
  * @test TestHeapDumpOnOutOfMemoryError
  * @summary Test verifies that -XX:HeapDumpOnOutOfMemoryError dumps heap when OutOfMemory is thrown in heap
  * @library /test/lib
+ * @requires vm.flagless
  * @run driver TestHeapDumpOnOutOfMemoryError run heap
  */
 
@@ -32,6 +33,7 @@
  * @test TestHeapDumpOnOutOfMemoryError
  * @summary Test verifies that -XX:HeapDumpOnOutOfMemoryError dumps heap when OutOfMemory is thrown in metaspace.
  * @library /test/lib
+ * @requires vm.flagless
  * @run driver/timeout=240 TestHeapDumpOnOutOfMemoryError run metaspace
  */
 
diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/TestHeapDumpPath.java b/test/hotspot/jtreg/runtime/ErrorHandling/TestHeapDumpPath.java
index b1c4dc0..0cc6dbc 100644
--- a/test/hotspot/jtreg/runtime/ErrorHandling/TestHeapDumpPath.java
+++ b/test/hotspot/jtreg/runtime/ErrorHandling/TestHeapDumpPath.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
  * @test TestHeapDumpPath
  * @summary Test verifies that -XX:HeapDumpPath= supports directory as a parameter.
  * @library /test/lib
+ * @requires vm.flagless
  * @run driver TestHeapDumpPath
  */
 
diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/TestOnError.java b/test/hotspot/jtreg/runtime/ErrorHandling/TestOnError.java
index 776d1c9..00475f8 100644
--- a/test/hotspot/jtreg/runtime/ErrorHandling/TestOnError.java
+++ b/test/hotspot/jtreg/runtime/ErrorHandling/TestOnError.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
  * @summary Test using -XX:OnError=<cmd>
  * @modules java.base/jdk.internal.misc
  * @library /test/lib
+ * @requires vm.flagless
  * @requires vm.debug
  * @run driver TestOnError
  */
diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/TestOnOutOfMemoryError.java b/test/hotspot/jtreg/runtime/ErrorHandling/TestOnOutOfMemoryError.java
index 6d72bd5..fe3c5c3 100644
--- a/test/hotspot/jtreg/runtime/ErrorHandling/TestOnOutOfMemoryError.java
+++ b/test/hotspot/jtreg/runtime/ErrorHandling/TestOnOutOfMemoryError.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
  * @summary Test using single and multiple -XX:OnOutOfMemoryError=<cmd>
  * @modules java.base/jdk.internal.misc
  * @library /test/lib
+ * @requires vm.flagless
  * @run driver TestOnOutOfMemoryError
  * @bug 8078470 8177522
  */
diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/ThreadsListHandleInErrorHandlingTest.java b/test/hotspot/jtreg/runtime/ErrorHandling/ThreadsListHandleInErrorHandlingTest.java
index 5ab7ad6..9683379 100644
--- a/test/hotspot/jtreg/runtime/ErrorHandling/ThreadsListHandleInErrorHandlingTest.java
+++ b/test/hotspot/jtreg/runtime/ErrorHandling/ThreadsListHandleInErrorHandlingTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -38,6 +38,7 @@
  * @summary ThreadsListHandle info should be in error handling output.
  * @modules java.base/jdk.internal.misc
  * @library /test/lib
+ * @requires vm.flagless
  * @run driver ThreadsListHandleInErrorHandlingTest
  */
 
diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/TimeoutInErrorHandlingTest.java b/test/hotspot/jtreg/runtime/ErrorHandling/TimeoutInErrorHandlingTest.java
index 3aba36e..5111a22 100644
--- a/test/hotspot/jtreg/runtime/ErrorHandling/TimeoutInErrorHandlingTest.java
+++ b/test/hotspot/jtreg/runtime/ErrorHandling/TimeoutInErrorHandlingTest.java
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2023, Red Hat, Inc. and/or its affiliates.
- * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -41,6 +41,7 @@
  * @summary Hanging Error Reporting steps may lead to torn error logs
  * @modules java.base/jdk.internal.misc
  * @library /test/lib
+ * @requires vm.flagless
  * @requires (vm.debug == true) & (os.family != "windows")
  * @run driver TimeoutInErrorHandlingTest
  * @author Thomas Stuefe (SAP)
@@ -52,6 +53,7 @@
  * @summary Error handling step timeouts should never be blocked by OnError etc.
  * @modules java.base/jdk.internal.misc
  * @library /test/lib
+ * @requires vm.flagless
  * @requires (vm.debug == true) & (os.family != "windows")
  * @run driver TimeoutInErrorHandlingTest with-on-error
  */
diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/VeryEarlyAssertTest.java b/test/hotspot/jtreg/runtime/ErrorHandling/VeryEarlyAssertTest.java
index 09b5c04..4395775 100644
--- a/test/hotspot/jtreg/runtime/ErrorHandling/VeryEarlyAssertTest.java
+++ b/test/hotspot/jtreg/runtime/ErrorHandling/VeryEarlyAssertTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2018, SAP. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -29,6 +29,7 @@
  * @summary No hs-err file if fatal error is raised during dynamic initialization.
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
+ * @requires vm.flagless
  * @requires (vm.debug == true)
  * @requires os.family == "linux"
  * @run driver VeryEarlyAssertTest
@@ -49,8 +50,7 @@
   public static void main(String[] args) throws Exception {
 
 
-    ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
-            "-version");
+    ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-version");
     Map<String, String> env = pb.environment();
     env.put("HOTSPOT_FATAL_ERROR_DURING_DYNAMIC_INITIALIZATION", "1");
 
diff --git a/test/hotspot/jtreg/runtime/LocalVariableTable/TestLVT.java b/test/hotspot/jtreg/runtime/LocalVariableTable/TestLVT.java
index 2750038..b1ed991 100644
--- a/test/hotspot/jtreg/runtime/LocalVariableTable/TestLVT.java
+++ b/test/hotspot/jtreg/runtime/LocalVariableTable/TestLVT.java
@@ -41,21 +41,16 @@
     public static void main(String[] args) throws Exception {
         test();  // Test good LVT in this test
 
-        String jarFile = System.getProperty("test.src") + "/testcase.jar";
-
-        // java -cp $testSrc/testcase.jar DuplicateLVT
         ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("DuplicateLVT");
         new OutputAnalyzer(pb.start())
             .shouldContain("Duplicated LocalVariableTable attribute entry for 'by' in class file DuplicateLVT")
             .shouldHaveExitValue(1);
 
-        // java -cp $testclasses/testcase.jar DuplicateLVTT
         pb = ProcessTools.createJavaProcessBuilder("DuplicateLVTT");
         new OutputAnalyzer(pb.start())
             .shouldContain("Duplicated LocalVariableTypeTable attribute entry for 'list' in class file DuplicateLVTT")
             .shouldHaveExitValue(1);
 
-        // java -cp $testclasses/testcase.jar NotFoundLVTT
         pb = ProcessTools.createJavaProcessBuilder("NotFoundLVTT");
         new OutputAnalyzer(pb.start())
             .shouldContain("LVTT entry for 'list' in class file NotFoundLVTT does not match any LVT entry")
diff --git a/test/hotspot/jtreg/runtime/cds/appcds/JarBuilder.java b/test/hotspot/jtreg/runtime/cds/appcds/JarBuilder.java
index 46ea9d4..b9c2063 100644
--- a/test/hotspot/jtreg/runtime/cds/appcds/JarBuilder.java
+++ b/test/hotspot/jtreg/runtime/cds/appcds/JarBuilder.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -259,21 +259,36 @@
         }
     }
 
+    static final String keyTool = JDKToolFinder.getJDKTool("keytool");
+    static final String jarSigner = JDKToolFinder.getJDKTool("jarsigner");
 
-    public static void signJar() throws Exception {
-        String keyTool = JDKToolFinder.getJDKTool("keytool");
-        String jarSigner = JDKToolFinder.getJDKTool("jarsigner");
-
+    public static void signJarWithDisabledAlgorithm(String jarName) throws Exception {
+        String keyName = "key_with_disabled_alg";
         executeProcess(keyTool,
-            "-genkey", "-keystore", "./keystore", "-alias", "mykey",
+            "-genkey", "-keystore", "./keystore", "-alias", keyName,
+            "-storepass", "abc123", "-keypass", "abc123", "-keyalg", "dsa",
+            "-sigalg", "SHA1withDSA", "-keysize", "512", "-dname", "CN=jvmtest2")
+            .shouldHaveExitValue(0);
+
+        doSigning(jarName, keyName);
+    }
+
+    public static void signJar(String jarName) throws Exception {
+        String keyName = "mykey";
+        executeProcess(keyTool,
+            "-genkey", "-keystore", "./keystore", "-alias", keyName,
             "-storepass", "abc123", "-keypass", "abc123", "-keyalg", "dsa",
             "-dname", "CN=jvmtest")
             .shouldHaveExitValue(0);
 
+        doSigning(jarName, keyName);
+    }
+
+    private static void doSigning(String jarName, String keyName) throws Exception {
         executeProcess(jarSigner,
            "-keystore", "./keystore", "-storepass", "abc123", "-keypass",
-           "abc123", "-signedjar", getJarFilePath("signed_hello"),
-           getJarFilePath("hello"), "mykey")
+           "abc123", "-signedjar", getJarFilePath("signed_" + jarName),
+           getJarFilePath(jarName), keyName)
            .shouldHaveExitValue(0);
     }
 
diff --git a/test/hotspot/jtreg/runtime/cds/appcds/SealingViolation.java b/test/hotspot/jtreg/runtime/cds/appcds/SealingViolation.java
new file mode 100644
index 0000000..9aa75fb
--- /dev/null
+++ b/test/hotspot/jtreg/runtime/cds/appcds/SealingViolation.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ * @test
+ * @bug 8312434
+ * @summary A jar file containing classes in the same package. Sign the jar file with
+ *          a disabled algorithm. The jar will be treated as unsigned.
+ *          Dump only one class into the CDS archive. During runtime, load the class
+ *          stored in the archive and then load another class not from the archive
+ *          but from the same pacakge. Loading of the second class should not result
+ *          in sealing violation.
+ *
+ * @requires vm.cds
+ * @library /test/lib
+ * @compile test-classes/GenericTestApp.java test-classes/pkg/ClassInPackage.java test-classes/C2.java
+ * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar WhiteBox.jar jdk.test.whitebox.WhiteBox
+ * @run driver SealingViolation
+ */
+
+import jdk.test.lib.helpers.ClassFileInstaller;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class SealingViolation {
+    public static void main(String[] args) throws Exception {
+        String[] classList = {"pkg/ClassInPackage"};
+        String appJar = ClassFileInstaller.writeJar("pkg-classes-sealed.jar",
+            ClassFileInstaller.Manifest.fromSourceFile("test-classes/pkg/package_seal.mf"),
+            "GenericTestApp", "pkg/ClassInPackage", "pkg/C2");
+
+        JarBuilder.signJarWithDisabledAlgorithm("pkg-classes-sealed");
+        String signedJar = TestCommon.getTestJar("pkg-classes-sealed.jar");
+
+        // GenericTestApp requires WhiteBox
+        String wbJar = ClassFileInstaller.getJarPath("WhiteBox.jar");
+        String bootclasspath = "-Xbootclasspath/a:" + wbJar;
+
+        OutputAnalyzer output = TestCommon.dump(signedJar, classList, bootclasspath,
+                                     "-Xlog:cds+class=debug");
+        output.shouldMatch("cds.class.*klasses.* pkg.ClassInPackage")
+              .shouldHaveExitValue(0);
+
+        output = TestCommon.exec(signedJar, "-Xlog:cds=debug,class+load",
+                                 bootclasspath,
+                                 "-XX:+UnlockDiagnosticVMOptions",
+                                 "-XX:+WhiteBoxAPI",
+                                 "GenericTestApp",
+                                 "assertShared:pkg.ClassInPackage",
+                                 "assertNotShared:pkg.C2");
+        output.shouldHaveExitValue(0);
+    }
+}
diff --git a/test/hotspot/jtreg/runtime/cds/appcds/SignedJar.java b/test/hotspot/jtreg/runtime/cds/appcds/SignedJar.java
index 4bc90bb..6f1e243 100644
--- a/test/hotspot/jtreg/runtime/cds/appcds/SignedJar.java
+++ b/test/hotspot/jtreg/runtime/cds/appcds/SignedJar.java
@@ -37,7 +37,7 @@
 public class SignedJar {
     public static void main(String[] args) throws Exception {
         String unsignedJar = JarBuilder.getOrCreateHelloJar();
-        JarBuilder.signJar();
+        JarBuilder.signJar("hello");
 
         // Test class exists in signed JAR
         String signedJar = TestCommon.getTestJar("signed_hello.jar");
diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/LinkClassTest.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/LinkClassTest.java
index ea6abe0..388c942 100644
--- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/LinkClassTest.java
+++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/LinkClassTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,7 +31,7 @@
  *          /test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/test-classes
  * @build LinkClassApp
  * @build jdk.test.whitebox.WhiteBox
- * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar link_class_app.jar LinkClassApp Parent Child Parent2 Child2 MyShutdown
+ * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar link_class_app.jar LinkClassApp Parent Child Parent2 Child2 LinkClassApp$MyShutdown
  * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
  * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. LinkClassTest
  */
diff --git a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/test-classes/LinkClassApp.java b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/test-classes/LinkClassApp.java
index 1cfb450..347c932 100644
--- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/test-classes/LinkClassApp.java
+++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/test-classes/LinkClassApp.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -46,13 +46,13 @@
     int get() {return 4;}
 }
 
-class MyShutdown extends Thread{
-    public void run(){
-        System.out.println("shut down hook invoked...");
-    }
-}
-
 class LinkClassApp {
+    static class MyShutdown extends Thread{
+        public void run(){
+            System.out.println("shut down hook invoked...");
+        }
+    }
+
     public static void main(String args[]) {
         Runtime r=Runtime.getRuntime();
         r.addShutdownHook(new MyShutdown());
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnireflock04/TestDescription.java b/test/hotspot/jtreg/runtime/cds/appcds/test-classes/pkg/ClassInPackage.java
similarity index 70%
copy from test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnireflock04/TestDescription.java
copy to test/hotspot/jtreg/runtime/cds/appcds/test-classes/pkg/ClassInPackage.java
index 8e61aa3..35fdab4 100644
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnireflock04/TestDescription.java
+++ b/test/hotspot/jtreg/runtime/cds/appcds/test-classes/pkg/ClassInPackage.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -19,18 +19,12 @@
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  * questions.
+ *
  */
 
+package pkg;
 
-/*
- * @test
- * @key stress randomness
- *
- * @summary converted from VM Testbase gc/lock/jniref/jnireflock04.
- * VM Testbase keywords: [gc, stress, stressopt, nonconcurrent, quick]
- *
- * @library /vmTestbase
- *          /test/lib
- * @run main/othervm/native -XX:-UseGCOverheadLimit gc.lock.LockerTest -gp1 class -lockers jniRef
- */
+public class ClassInPackage {
 
+
+}
diff --git a/test/hotspot/jtreg/runtime/cds/appcds/test-classes/pkg/package_seal.mf b/test/hotspot/jtreg/runtime/cds/appcds/test-classes/pkg/package_seal.mf
new file mode 100644
index 0000000..ff3d31c
--- /dev/null
+++ b/test/hotspot/jtreg/runtime/cds/appcds/test-classes/pkg/package_seal.mf
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+Created-By: 1.9.0-internal (Oracle Corporation)
+
+Name: pkg/
+Sealed: true
+
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnilocalreflock04/TestDescription.java b/test/hotspot/jtreg/runtime/jni/abstractMethod/AbstractMethodClass.jasm
similarity index 67%
copy from test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnilocalreflock04/TestDescription.java
copy to test/hotspot/jtreg/runtime/jni/abstractMethod/AbstractMethodClass.jasm
index 42d7299..24c53f2 100644
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnilocalreflock04/TestDescription.java
+++ b/test/hotspot/jtreg/runtime/jni/abstractMethod/AbstractMethodClass.jasm
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -19,22 +19,25 @@
  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  * or visit www.oracle.com if you need additional information or have any
  * questions.
+ *
  */
-
-
 /*
- * @test
- * @key stress randomness
+ *  This is a non-abstract class with an abstract method.
  *
- * @summary converted from VM Testbase gc/lock/jniref/jnilocalreflock04.
- * VM Testbase keywords: [gc, stress, stressopt, nonconcurrent]
- *
- * @library /vmTestbase
- *          /test/lib
- * @run main/othervm/native
- *      -XX:-UseGCOverheadLimit
- *      gc.lock.LockerTest
- *      -gp1 class
- *      -lockers jniLocalRef
  */
+super public class AbstractMethodClass
+      extends java/lang/Object
+              version 51:0  // Java 7 version
+{
 
+    public Method "<init>":"()V"
+       stack 1 locals 1
+    {
+        aload_0;
+        invokespecial Method java/lang/Object."<init>":"()V";
+        return;
+    }
+
+    public abstract Method "abstractM":"()V";
+
+}
diff --git a/test/hotspot/jtreg/runtime/jni/abstractMethod/TestJNIAbstractMethod.java b/test/hotspot/jtreg/runtime/jni/abstractMethod/TestJNIAbstractMethod.java
new file mode 100644
index 0000000..2384f6d
--- /dev/null
+++ b/test/hotspot/jtreg/runtime/jni/abstractMethod/TestJNIAbstractMethod.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ * @test
+ * @bug 8323243
+ * @summary Test that invocation of an abstract method from JNI works correctly
+ * @compile AbstractMethodClass.jasm
+ * @run main/othervm/native TestJNIAbstractMethod
+ */
+
+/**
+ * We are testing invocation of an abstract method from JNI - which should
+ * simply result in throwning AbstractMethodError. To invoke an abstract method
+ * we must have an instance method (as abstract static methods are illegal),
+ * but instantiating an abstract class is also illegal at the Java language
+ * level, so we have to use a custom jasm class that contains an abstract method
+ * declaration, but which is not itself declared as an abstract class.
+ */
+public class TestJNIAbstractMethod {
+
+    // Invokes an abstract method from JNI and throws AbstractMethodError.
+    private static native void invokeAbstractM(Class<?> AMclass,
+                                               AbstractMethodClass receiver);
+
+    static {
+        System.loadLibrary("JNIAbstractMethod");
+    }
+
+    public static void main(String[] args) {
+        AbstractMethodClass obj = new AbstractMethodClass();
+        try {
+            System.out.println("Attempting direct invocation via Java");
+            obj.abstractM();
+            throw new RuntimeException("Did not get AbstractMethodError from Java!");
+        } catch (AbstractMethodError expected) {
+            System.out.println("ok - got expected exception: " + expected);
+        }
+        try {
+            System.out.println("Attempting direct invocation via JNI");
+            invokeAbstractM(obj.getClass(), obj);
+            throw new RuntimeException("Did not get AbstractMethodError from JNI!");
+        } catch (AbstractMethodError expected) {
+            System.out.println("ok - got expected exception: " + expected);
+        }
+    }
+}
diff --git a/test/hotspot/jtreg/runtime/jni/abstractMethod/libJNIAbstractMethod.c b/test/hotspot/jtreg/runtime/jni/abstractMethod/libJNIAbstractMethod.c
new file mode 100644
index 0000000..35a28f7
--- /dev/null
+++ b/test/hotspot/jtreg/runtime/jni/abstractMethod/libJNIAbstractMethod.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+#include <jni.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+JNIEXPORT void JNICALL Java_TestJNIAbstractMethod_invokeAbstractM(JNIEnv* env,
+                                                                  jclass this_cls,
+                                                                  jclass target_cls,
+                                                                  jobject receiver) {
+
+  jmethodID mid = (*env)->GetMethodID(env, target_cls, "abstractM", "()V");
+  if (mid == NULL) {
+    fprintf(stderr, "Error looking up method abstractM\n");
+    (*env)->ExceptionDescribe(env);
+    exit(1);
+  }
+
+  printf("Invoking abstract method ...\n");
+  (*env)->CallVoidMethod(env, receiver, mid);  // Should raise exception
+
+}
diff --git a/test/hotspot/jtreg/runtime/os/TestTracePageSizes.java b/test/hotspot/jtreg/runtime/os/TestTracePageSizes.java
index 3275e43..dca9f8b 100644
--- a/test/hotspot/jtreg/runtime/os/TestTracePageSizes.java
+++ b/test/hotspot/jtreg/runtime/os/TestTracePageSizes.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -51,7 +51,7 @@
  * @library /test/lib
  * @build jdk.test.lib.Platform
  * @requires os.family == "linux"
- * @requires vm.gc != "Z"
+ * @requires vm.gc != "Z" & vm.gc != "Shenandoah"
  * @run main/othervm -XX:+AlwaysPreTouch -Xmx128m -Xlog:pagesize:ps-%p.log -XX:-SegmentedCodeCache TestTracePageSizes
  * @run main/othervm -XX:+AlwaysPreTouch -Xmx128m -Xlog:pagesize:ps-%p.log -XX:-SegmentedCodeCache -XX:+UseLargePages TestTracePageSizes
  * @run main/othervm -XX:+AlwaysPreTouch -Xmx128m -Xlog:pagesize:ps-%p.log -XX:-SegmentedCodeCache -XX:+UseTransparentHugePages TestTracePageSizes
diff --git a/test/hotspot/jtreg/serviceability/jvmti/thread/GetStackTrace/GetStackTraceAndRetransformTest/GetStackTraceAndRetransformTest.java b/test/hotspot/jtreg/serviceability/jvmti/thread/GetStackTrace/GetStackTraceAndRetransformTest/GetStackTraceAndRetransformTest.java
new file mode 100644
index 0000000..eb7d301
--- /dev/null
+++ b/test/hotspot/jtreg/serviceability/jvmti/thread/GetStackTrace/GetStackTraceAndRetransformTest/GetStackTraceAndRetransformTest.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2023, Datadog, Inc. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8313816
+ * @summary Test that a sequence of method retransformation and stacktrace capture while the old method
+ *          version is still on stack does not lead to a crash when that method's jmethodID is used as
+ *          an argument for JVMTI functions.
+ * @requires vm.jvmti
+ * @requires vm.flagless
+ * @library /test/lib
+ * @build jdk.test.whitebox.WhiteBox
+ * @modules java.instrument
+ *          java.compiler
+ * @compile GetStackTraceAndRetransformTest.java
+ * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
+ * @run main RedefineClassHelper
+ * @run main/othervm/native -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -javaagent:redefineagent.jar -agentlib:GetStackTraceAndRetransformTest GetStackTraceAndRetransformTest
+ */
+
+import jdk.test.whitebox.WhiteBox;
+
+class Transformable {
+  static final String newClass = """
+    class Transformable {
+      static final String newClass = "";
+      static void redefineAndStacktrace() throws Exception {}
+      static void stacktrace() throws Exception {
+        capture(Thread.currentThread());
+      }
+      public static native void capture(Thread thread);
+    }
+  """;
+  static void redefineAndStacktrace() throws Exception {
+    // This call will cause the class to be retransformed.
+    // However, this method is still on stack so the subsequent attempt to capture the stacktrace
+    // will result into this frame being identified by the jmethodID of the previous method version.
+    RedefineClassHelper.redefineClass(Transformable.class, newClass);
+    capture(Thread.currentThread());
+  }
+
+  static void stacktrace() throws Exception {
+  }
+
+  public static native void capture(Thread thread);
+}
+
+public class GetStackTraceAndRetransformTest {
+    public static void main(String args[]) throws Throwable {
+        initialize(Transformable.class);
+
+        Transformable.redefineAndStacktrace();
+        Transformable.stacktrace();
+
+        WhiteBox.getWhiteBox().cleanMetaspaces();
+        check(2);
+    }
+
+    public static native void initialize(Class<?> target);
+    public static native void check(int expected);
+}
diff --git a/test/hotspot/jtreg/serviceability/jvmti/thread/GetStackTrace/GetStackTraceAndRetransformTest/libGetStackTraceAndRetransformTest.cpp b/test/hotspot/jtreg/serviceability/jvmti/thread/GetStackTrace/GetStackTraceAndRetransformTest/libGetStackTraceAndRetransformTest.cpp
new file mode 100644
index 0000000..3be6dcf
--- /dev/null
+++ b/test/hotspot/jtreg/serviceability/jvmti/thread/GetStackTrace/GetStackTraceAndRetransformTest/libGetStackTraceAndRetransformTest.cpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2023, Datadog, Inc. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "jvmti.h"
+#include "jvmti_common.h"
+#include "../get_stack_trace.h"
+
+
+extern "C" {
+
+static jvmtiEnv *jvmti = NULL;
+static jmethodID* ids = NULL;
+static int ids_size = 0;
+
+JNIEXPORT jint JNICALL
+Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) {
+  jint res = jvm->GetEnv((void **) &jvmti, JVMTI_VERSION_1_1);
+  if (res != JNI_OK || jvmti == NULL) {
+    printf("Wrong result of a valid call to GetEnv!\n");
+    return JNI_ERR;
+  }
+  ids = (jmethodID*)malloc(sizeof(jmethodID) * 10);
+  return JNI_OK;
+}
+
+JNIEXPORT void JNICALL
+Java_GetStackTraceAndRetransformTest_initialize(JNIEnv *env, jclass cls, jclass tgt) {
+  // we need to force jmethodids to be created for the methods we are going to retransform
+  env->GetStaticMethodID(tgt, "redefineAndStacktrace", "()V");
+  env->GetStaticMethodID(tgt, "stacktrace", "()V");
+}
+
+JNIEXPORT void JNICALL
+Java_Transformable_capture(JNIEnv *env, jclass cls, jthread thread) {
+  jint count;
+  const int MAX_NUMBER_OF_FRAMES = 32;
+  jvmtiFrameInfo frames[MAX_NUMBER_OF_FRAMES];
+
+  jvmtiError err = jvmti->GetStackTrace(thread, 0, MAX_NUMBER_OF_FRAMES, frames, &count);
+  check_jvmti_status(env, err, "GetStackTrace failed.");
+
+  ids[ids_size++] = frames[1].method;
+}
+
+JNIEXPORT void JNICALL
+Java_GetStackTraceAndRetransformTest_check(JNIEnv *jni, jclass cls, jint expected) {
+  if (ids_size != expected) {
+    fprintf(stderr, "Unexpected number methods captured: %d (expected %d)\n", ids_size, expected);
+    exit(2);
+  }
+  for (int i = 0; i < ids_size; i++) {
+    jclass rslt = NULL;
+    char* class_name = NULL;
+    jvmti->GetMethodDeclaringClass(ids[i], &rslt);
+    if (rslt != NULL) {
+        jvmti->GetClassSignature(rslt, &class_name, NULL);
+    }
+  }
+}
+}
diff --git a/test/hotspot/jtreg/serviceability/jvmti/thread/GetStackTrace/get_stack_trace.h b/test/hotspot/jtreg/serviceability/jvmti/thread/GetStackTrace/get_stack_trace.h
new file mode 100644
index 0000000..788d3dd
--- /dev/null
+++ b/test/hotspot/jtreg/serviceability/jvmti/thread/GetStackTrace/get_stack_trace.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef GET_STACK_TRACE_H
+#define GET_STACK_TRACE_H
+#include "jvmti.h"
+
+typedef struct {
+  const char *cls;
+  const char *name;
+  const char *sig;
+} frame_info;
+
+
+int compare_stack_trace(jvmtiEnv *jvmti, JNIEnv *jni, jthread thread,
+                        frame_info expected_frames[], int expected_frames_length, int offset = 0) {
+  int result = JNI_TRUE;
+  char *class_signature, *name, *sig, *generic;
+  jint count;
+  const int MAX_NUMBER_OF_FRAMES = 32;
+  jvmtiFrameInfo frames[MAX_NUMBER_OF_FRAMES];
+  jclass caller_class;
+
+  printf("Calling compare_stack_trace for: \n");
+  print_stack_trace(jvmti, jni, thread);
+
+  jvmtiError err = jvmti->GetStackTrace(thread, 0, MAX_NUMBER_OF_FRAMES, frames, &count);
+  check_jvmti_status(jni, err, "GetStackTrace failed.");
+
+  printf("Number of frames: %d, expected: %d\n", count, expected_frames_length - offset);
+
+
+  if (count < expected_frames_length - offset) {
+    printf("Number of expected_frames: %d is less then expected: %d\n", count, expected_frames_length);
+    result = JNI_FALSE;
+  }
+  for (int i = 0; i < count - offset; i++) {
+    int idx = count - 1 - i;
+    printf(">>> checking frame#%d ...\n", idx);
+    check_jvmti_status(jni, jvmti->GetMethodDeclaringClass(frames[count - 1 - i].method, &caller_class),
+                       "GetMethodDeclaringClass failed.");
+    check_jvmti_status(jni, jvmti->GetClassSignature(caller_class, &class_signature, &generic),
+                       "GetClassSignature");
+    check_jvmti_status(jni, jvmti->GetMethodName(frames[count - 1 - i].method, &name, &sig, &generic),
+                       "GetMethodName");
+
+    printf(">>>   class:  \"%s\"\n", class_signature);
+    printf(">>>   method: \"%s%s\"\n", name, sig);
+    printf(">>>   %d ... done\n", i);
+
+    int exp_idx = expected_frames_length - 1 - i;
+    printf("expected idx %d\n", exp_idx);
+    fflush(0);
+    if (i < expected_frames_length) {
+
+      // for generated classes don't compare lambda indicies
+      // Example: {"Ljava/lang/VirtualThread$VThreadContinuation$$Lambda.0x0000000800098340;"
+      size_t lambda_idx = strlen(expected_frames[exp_idx].cls);
+      const char *lambda = strstr(expected_frames[exp_idx].cls, "$$Lambda");
+      if (lambda != nullptr) {
+        lambda_idx = lambda - expected_frames[exp_idx].cls;
+        printf("Comparing only first %zu chars in classname.\n", lambda_idx);
+      }
+      if (class_signature == NULL || strncmp(class_signature, expected_frames[exp_idx].cls, lambda_idx) != 0) {
+        printf("(frame#%d) wrong class sig: \"%s\", expected: \"%s\"\n",
+               exp_idx, class_signature, expected_frames[exp_idx].cls);
+        result = JNI_FALSE;
+      }
+
+      if (name == NULL || strcmp(name, expected_frames[exp_idx].name) != 0) {
+        printf("(frame#%d) wrong method name: \"%s\", expected: \"%s\"\n",
+               exp_idx, name, expected_frames[exp_idx].name);
+        result = JNI_FALSE;
+      }
+      if (sig == NULL || strcmp(sig, expected_frames[exp_idx].sig) != 0) {
+        printf("(frame#%d) wrong method sig: \"%s\", expected: \"%s\"\n",
+               exp_idx, sig, expected_frames[exp_idx].sig);
+        result = JNI_FALSE;
+      }
+    }
+  }
+  return result;
+}
+
+
+#endif //GET_STACK_TRACE_H
diff --git a/test/hotspot/jtreg/serviceability/sa/TestJmapCoreMetaspace.java b/test/hotspot/jtreg/serviceability/sa/TestJmapCoreMetaspace.java
index 3dd060b..b8e00e5 100644
--- a/test/hotspot/jtreg/serviceability/sa/TestJmapCoreMetaspace.java
+++ b/test/hotspot/jtreg/serviceability/sa/TestJmapCoreMetaspace.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
 
 /**
  * @test TestJmapCoreMetaspace
- * @summary Test verifies that jhsdb jmap could generate heap dump from core when metspace is full
+ * @summary Test verifies that jhsdb jmap could generate heap dump from core when metaspace is full
  * @requires vm.hasSA
  * @library /test/lib
  * @run driver/timeout=480 TestJmapCore run metaspace
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/LockerTest.java b/test/hotspot/jtreg/vmTestbase/gc/lock/LockerTest.java
index 33bf680..d11aff2 100644
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/LockerTest.java
+++ b/test/hotspot/jtreg/vmTestbase/gc/lock/LockerTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,9 +22,10 @@
  */
 package gc.lock;
 
+import jdk.test.whitebox.WhiteBox;
 import nsk.share.runner.*;
 import nsk.share.gc.*;
-import nsk.share.gc.gp.*;
+import nsk.share.gc.gp.GarbageUtils;
 import nsk.share.gc.lock.*;
 import nsk.share.test.ExecutionController;
 
@@ -33,26 +34,30 @@
  *
  * A number of threads is started. Each one locks and eats memory.
  */
-public class LockerTest extends ThreadedGCTest implements GarbageProducerAware, GarbageProducer1Aware, LockersAware {
+public class LockerTest extends ThreadedGCTest implements LockersAware {
 
-    private GarbageProducer garbageProducer;
-    private GarbageProducer garbageProducer1;
     private Lockers lockers;
     private long objectSize = 1000;
 
     private class Worker implements Runnable {
 
-        byte[] rezerve = new byte[1024 * 1024];
-        private Locker locker = lockers.createLocker(garbageProducer1.create(objectSize));
+        byte[] rezerve = new byte[1024];
+        private Locker locker = lockers.createLocker(rezerve);
 
         public Worker() {
             locker.enable();
         }
 
         public void run() {
-            locker.lock();
-            GarbageUtils.eatMemory(getExecutionController(), garbageProducer);
-            locker.unlock();
+            ExecutionController stresser = getExecutionController();
+            // Use only 30% of the heap.
+            final long testMemorySize = 3 * Runtime.getRuntime().maxMemory() / 10;
+
+            while (stresser.continueExecution()) {
+                locker.lock();
+                GarbageUtils.engageGC(testMemorySize);
+                locker.unlock();
+            }
         }
     }
 
@@ -60,14 +65,6 @@
         return new Worker();
     }
 
-    public void setGarbageProducer(GarbageProducer garbageProducer) {
-        this.garbageProducer = garbageProducer;
-    }
-
-    public void setGarbageProducer1(GarbageProducer garbageProducer1) {
-        this.garbageProducer1 = garbageProducer1;
-    }
-
     public void setLockers(Lockers lockers) {
         this.lockers = lockers;
     }
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jni/jnilock001/TestDescription.java b/test/hotspot/jtreg/vmTestbase/gc/lock/jni/jnilock001/TestDescription.java
index 74fa24c..41de075 100644
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jni/jnilock001/TestDescription.java
+++ b/test/hotspot/jtreg/vmTestbase/gc/lock/jni/jnilock001/TestDescription.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,10 +31,8 @@
  *
  * @library /vmTestbase
  *          /test/lib
- * @run main/othervm/native
- *      -XX:-UseGCOverheadLimit
- *      gc.lock.LockerTest
- *      -gp1 randomString
- *      -lockers jni
+ * @build jdk.test.whitebox.WhiteBox
+ * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
+ * @run main/othervm/native -Xbootclasspath/a:. -Xlog:gc=debug:gc.log -XX:+HeapDumpOnOutOfMemoryError -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI gc.lock.LockerTest -lockers jni -t 1
  */
 
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jni/jnilock002/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/lock/jni/jnilock002/TEST.properties
deleted file mode 100644
index 04b22a1..0000000
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jni/jnilock002/TEST.properties
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-exclusiveAccess.dirs=.
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jni/jnilock002/TestDescription.java b/test/hotspot/jtreg/vmTestbase/gc/lock/jni/jnilock002/TestDescription.java
deleted file mode 100644
index 3df984c..0000000
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jni/jnilock002/TestDescription.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-/*
- * @test
- * @key stress randomness
- *
- * @summary converted from VM Testbase gc/lock/jni/jnilock002.
- * VM Testbase keywords: [gc, stress, stressopt, nonconcurrent]
- *
- * @library /vmTestbase
- *          /test/lib
- * @run main/othervm/native
- *      -XX:-UseGCOverheadLimit
- *      gc.lock.LockerTest
- *      -gp1 random(primitiveArrays)
- *      -lockers jni
- */
-
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jni/jnilock003/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/lock/jni/jnilock003/TEST.properties
deleted file mode 100644
index 04b22a1..0000000
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jni/jnilock003/TEST.properties
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-exclusiveAccess.dirs=.
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jni/jnilock003/TestDescription.java b/test/hotspot/jtreg/vmTestbase/gc/lock/jni/jnilock003/TestDescription.java
deleted file mode 100644
index 3518c46..0000000
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jni/jnilock003/TestDescription.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-/*
- * @test
- * @key stress randomness
- *
- * @summary converted from VM Testbase gc/lock/jni/jnilock003.
- * VM Testbase keywords: [gc, stress, stressopt, nonconcurrent]
- *
- * @library /vmTestbase
- *          /test/lib
- * @run main/othervm/native
- *      -XX:-UseGCOverheadLimit
- *      gc.lock.LockerTest
- *      -gp1 interned(randomString)
- *      -lockers jni
- */
-
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jniglobalreflock01/TestDescription.java b/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jniglobalreflock01/TestDescription.java
index 145c827..4b78d02 100644
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jniglobalreflock01/TestDescription.java
+++ b/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jniglobalreflock01/TestDescription.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,10 +31,8 @@
  *
  * @library /vmTestbase
  *          /test/lib
- * @run main/othervm/native
- *      -XX:-UseGCOverheadLimit
- *      gc.lock.LockerTest
- *      -gp1 randomString
- *      -lockers jniGlobalRef
+ * @build jdk.test.whitebox.WhiteBox
+ * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
+ * @run main/othervm/native -Xbootclasspath/a:. -Xlog:gc=debug:gc.log -XX:+HeapDumpOnOutOfMemoryError -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI gc.lock.LockerTest -lockers jniGlobalRef -t 1
  */
 
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jniglobalreflock02/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jniglobalreflock02/TEST.properties
deleted file mode 100644
index 04b22a1..0000000
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jniglobalreflock02/TEST.properties
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-exclusiveAccess.dirs=.
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jniglobalreflock02/TestDescription.java b/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jniglobalreflock02/TestDescription.java
deleted file mode 100644
index 7caeb88..0000000
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jniglobalreflock02/TestDescription.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-/*
- * @test
- * @key stress randomness
- *
- * @summary converted from VM Testbase gc/lock/jniref/jniglobalreflock02.
- * VM Testbase keywords: [gc, stress, stressopt, nonconcurrent]
- *
- * @library /vmTestbase
- *          /test/lib
- * @run main/othervm/native
- *      -XX:-UseGCOverheadLimit
- *      gc.lock.LockerTest
- *      -gp1 random(primitiveArrays)
- *      -lockers jniGlobalRef
- */
-
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jniglobalreflock03/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jniglobalreflock03/TEST.properties
deleted file mode 100644
index 04b22a1..0000000
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jniglobalreflock03/TEST.properties
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-exclusiveAccess.dirs=.
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jniglobalreflock03/TestDescription.java b/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jniglobalreflock03/TestDescription.java
deleted file mode 100644
index 7e2a78a..0000000
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jniglobalreflock03/TestDescription.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-/*
- * @test
- * @key stress randomness
- *
- * @summary converted from VM Testbase gc/lock/jniref/jniglobalreflock03.
- * VM Testbase keywords: [gc, stress, stressopt, nonconcurrent]
- *
- * @library /vmTestbase
- *          /test/lib
- * @run main/othervm/native
- *      -XX:-UseGCOverheadLimit
- *      gc.lock.LockerTest
- *      -gp1 interned(randomString)
- *      -lockers jniGlobalRef
- */
-
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jniglobalreflock04/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jniglobalreflock04/TEST.properties
deleted file mode 100644
index 04b22a1..0000000
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jniglobalreflock04/TEST.properties
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-exclusiveAccess.dirs=.
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jniglobalreflock04/TestDescription.java b/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jniglobalreflock04/TestDescription.java
deleted file mode 100644
index b62fbb8..0000000
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jniglobalreflock04/TestDescription.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-/*
- * @test
- * @key stress randomness
- *
- * @summary converted from VM Testbase gc/lock/jniref/jniglobalreflock04.
- * VM Testbase keywords: [gc, stress, stressopt, nonconcurrent]
- *
- * @library /vmTestbase
- *          /test/lib
- * @run main/othervm/native
- *      -XX:-UseGCOverheadLimit
- *      gc.lock.LockerTest
- *      -gp1 class
- *      -lockers jniGlobalRef
- */
-
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnilocalreflock01/TestDescription.java b/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnilocalreflock01/TestDescription.java
index 2f98e7d..d56ff12 100644
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnilocalreflock01/TestDescription.java
+++ b/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnilocalreflock01/TestDescription.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,10 +31,8 @@
  *
  * @library /vmTestbase
  *          /test/lib
- * @run main/othervm/native
- *      -XX:-UseGCOverheadLimit
- *      gc.lock.LockerTest
- *      -gp1 randomString
- *      -lockers jniLocalRef
+ * @build jdk.test.whitebox.WhiteBox
+ * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
+ * @run main/othervm/native -Xbootclasspath/a:. -Xlog:gc=debug:gc.log -XX:+HeapDumpOnOutOfMemoryError -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI gc.lock.LockerTest -lockers jniLocalRef -t 1
  */
 
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnilocalreflock02/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnilocalreflock02/TEST.properties
deleted file mode 100644
index 04b22a1..0000000
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnilocalreflock02/TEST.properties
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-exclusiveAccess.dirs=.
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnilocalreflock02/TestDescription.java b/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnilocalreflock02/TestDescription.java
deleted file mode 100644
index e6ceb45..0000000
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnilocalreflock02/TestDescription.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-/*
- * @test
- * @key stress randomness
- *
- * @summary converted from VM Testbase gc/lock/jniref/jnilocalreflock02.
- * VM Testbase keywords: [gc, stress, stressopt, nonconcurrent]
- *
- * @library /vmTestbase
- *          /test/lib
- * @run main/othervm/native
- *      -XX:-UseGCOverheadLimit
- *      gc.lock.LockerTest
- *      -gp1 random(primitiveArrays)
- *      -lockers jniLocalRef
- */
-
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnilocalreflock03/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnilocalreflock03/TEST.properties
deleted file mode 100644
index 04b22a1..0000000
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnilocalreflock03/TEST.properties
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-exclusiveAccess.dirs=.
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnilocalreflock03/TestDescription.java b/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnilocalreflock03/TestDescription.java
deleted file mode 100644
index 7b15ea0..0000000
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnilocalreflock03/TestDescription.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-/*
- * @test
- * @key stress randomness
- *
- * @summary converted from VM Testbase gc/lock/jniref/jnilocalreflock03.
- * VM Testbase keywords: [gc, stress, stressopt, nonconcurrent]
- *
- * @library /vmTestbase
- *          /test/lib
- * @run main/othervm/native
- *      -XX:-UseGCOverheadLimit
- *      gc.lock.LockerTest
- *      -gp1 interned(randomString)
- *      -lockers jniLocalRef
- */
-
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnilocalreflock04/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnilocalreflock04/TEST.properties
deleted file mode 100644
index 04b22a1..0000000
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnilocalreflock04/TEST.properties
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-exclusiveAccess.dirs=.
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnireflock01/TestDescription.java b/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnireflock01/TestDescription.java
index a7afe84..294ee1d 100644
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnireflock01/TestDescription.java
+++ b/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnireflock01/TestDescription.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,10 +31,8 @@
  *
  * @library /vmTestbase
  *          /test/lib
- * @run main/othervm/native
- *      -XX:-UseGCOverheadLimit
- *      gc.lock.LockerTest
- *      -gp1 randomString
- *      -lockers jniRef
+ * @build jdk.test.whitebox.WhiteBox
+ * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
+ * @run main/othervm/native -Xbootclasspath/a:. -Xlog:gc=debug:gc.log -XX:+HeapDumpOnOutOfMemoryError -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI gc.lock.LockerTest -lockers jniRef -t 1
  */
 
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnireflock02/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnireflock02/TEST.properties
deleted file mode 100644
index 04b22a1..0000000
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnireflock02/TEST.properties
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-exclusiveAccess.dirs=.
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnireflock02/TestDescription.java b/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnireflock02/TestDescription.java
deleted file mode 100644
index 05e356a..0000000
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnireflock02/TestDescription.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-/*
- * @test
- * @key stress randomness
- *
- * @summary converted from VM Testbase gc/lock/jniref/jnireflock02.
- * VM Testbase keywords: [gc, stress, stressopt, nonconcurrent]
- *
- * @library /vmTestbase
- *          /test/lib
- * @run main/othervm/native
- *      -XX:-UseGCOverheadLimit
- *      gc.lock.LockerTest
- *      -gp1 random(primitiveArrays)
- *      -lockers jniRef
- */
-
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnireflock03/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnireflock03/TEST.properties
deleted file mode 100644
index 04b22a1..0000000
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnireflock03/TEST.properties
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-exclusiveAccess.dirs=.
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnireflock03/TestDescription.java b/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnireflock03/TestDescription.java
deleted file mode 100644
index 53a16c9..0000000
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnireflock03/TestDescription.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-/*
- * @test
- * @key stress randomness
- *
- * @summary converted from VM Testbase gc/lock/jniref/jnireflock03.
- * VM Testbase keywords: [gc, stress, stressopt, nonconcurrent]
- *
- * @library /vmTestbase
- *          /test/lib
- * @run main/othervm/native
- *      -XX:-UseGCOverheadLimit
- *      gc.lock.LockerTest
- *      -gp1 interned(randomString)
- *      -lockers jniRef
- */
-
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnireflock04/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnireflock04/TEST.properties
deleted file mode 100644
index 04b22a1..0000000
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnireflock04/TEST.properties
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-exclusiveAccess.dirs=.
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jniweakglobalreflock01/TestDescription.java b/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jniweakglobalreflock01/TestDescription.java
index d0c0caa..9609e34 100644
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jniweakglobalreflock01/TestDescription.java
+++ b/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jniweakglobalreflock01/TestDescription.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,10 +31,8 @@
  *
  * @library /vmTestbase
  *          /test/lib
- * @run main/othervm/native
- *      -XX:-UseGCOverheadLimit
- *      gc.lock.LockerTest
- *      -gp1 randomString
- *      -lockers jniWeakGlobalRef
+ * @build jdk.test.whitebox.WhiteBox
+ * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
+ * @run main/othervm/native -Xbootclasspath/a:. -Xlog:gc=debug:gc.log -XX:+HeapDumpOnOutOfMemoryError -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI gc.lock.LockerTest -lockers jniWeakGlobalRef -t 1
  */
 
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jniweakglobalreflock02/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jniweakglobalreflock02/TEST.properties
deleted file mode 100644
index 04b22a1..0000000
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jniweakglobalreflock02/TEST.properties
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-exclusiveAccess.dirs=.
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jniweakglobalreflock02/TestDescription.java b/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jniweakglobalreflock02/TestDescription.java
deleted file mode 100644
index 63b600b..0000000
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jniweakglobalreflock02/TestDescription.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-/*
- * @test
- * @key stress randomness
- *
- * @summary converted from VM Testbase gc/lock/jniref/jniweakglobalreflock02.
- * VM Testbase keywords: [gc, stress, stressopt, nonconcurrent]
- *
- * @library /vmTestbase
- *          /test/lib
- * @run main/othervm/native
- *      -XX:-UseGCOverheadLimit
- *      gc.lock.LockerTest
- *      -gp1 random(primitiveArrays)
- *      -lockers jniWeakGlobalRef
- */
-
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jniweakglobalreflock03/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jniweakglobalreflock03/TEST.properties
deleted file mode 100644
index 04b22a1..0000000
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jniweakglobalreflock03/TEST.properties
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-exclusiveAccess.dirs=.
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jniweakglobalreflock03/TestDescription.java b/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jniweakglobalreflock03/TestDescription.java
deleted file mode 100644
index 86fc198..0000000
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jniweakglobalreflock03/TestDescription.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-/*
- * @test
- * @key stress randomness
- *
- * @summary converted from VM Testbase gc/lock/jniref/jniweakglobalreflock03.
- * VM Testbase keywords: [gc, stress, stressopt, nonconcurrent]
- *
- * @library /vmTestbase
- *          /test/lib
- * @run main/othervm/native
- *      -XX:-UseGCOverheadLimit
- *      gc.lock.LockerTest
- *      -gp1 interned(randomString)
- *      -lockers jniWeakGlobalRef
- */
-
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jniweakglobalreflock04/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jniweakglobalreflock04/TEST.properties
deleted file mode 100644
index 04b22a1..0000000
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jniweakglobalreflock04/TEST.properties
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-exclusiveAccess.dirs=.
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jniweakglobalreflock04/TestDescription.java b/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jniweakglobalreflock04/TestDescription.java
deleted file mode 100644
index 3de445e..0000000
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jniweakglobalreflock04/TestDescription.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-/*
- * @test
- * @key stress randomness
- *
- * @summary converted from VM Testbase gc/lock/jniref/jniweakglobalreflock04.
- * VM Testbase keywords: [gc, stress, stressopt, nonconcurrent]
- *
- * @library /vmTestbase
- *          /test/lib
- * @run main/othervm/native
- *      -XX:-UseGCOverheadLimit
- *      gc.lock.LockerTest
- *      -gp1 class
- *      -lockers jniWeakGlobalRef
- */
-
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jvmti/alloc/jvmtialloclock01/TestDescription.java b/test/hotspot/jtreg/vmTestbase/gc/lock/jvmti/alloc/jvmtialloclock01/TestDescription.java
index 21224bc..ec47cd8 100644
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jvmti/alloc/jvmtialloclock01/TestDescription.java
+++ b/test/hotspot/jtreg/vmTestbase/gc/lock/jvmti/alloc/jvmtialloclock01/TestDescription.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,11 +31,8 @@
  *
  * @library /vmTestbase
  *          /test/lib
- * @run main/othervm/native
- *      -XX:-UseGCOverheadLimit
- *      -agentlib:JVMTIAllocLocker
- *      gc.lock.LockerTest
- *      -gp1 randomString
- *      -lockers jvmtiAlloc
+ * @build jdk.test.whitebox.WhiteBox
+ * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
+ * @run main/othervm/native -Xbootclasspath/a:. -Xlog:gc=debug:gc.log -XX:+HeapDumpOnOutOfMemoryError -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -agentlib:JVMTIAllocLocker gc.lock.LockerTest -lockers jvmtiAlloc -t 1
  */
 
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jvmti/alloc/jvmtialloclock02/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/lock/jvmti/alloc/jvmtialloclock02/TEST.properties
deleted file mode 100644
index 04b22a1..0000000
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jvmti/alloc/jvmtialloclock02/TEST.properties
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-exclusiveAccess.dirs=.
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jvmti/alloc/jvmtialloclock02/TestDescription.java b/test/hotspot/jtreg/vmTestbase/gc/lock/jvmti/alloc/jvmtialloclock02/TestDescription.java
deleted file mode 100644
index 14e004b..0000000
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jvmti/alloc/jvmtialloclock02/TestDescription.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-/*
- * @test
- * @key stress randomness
- *
- * @summary converted from VM Testbase gc/lock/jvmti/alloc/jvmtialloclock02.
- * VM Testbase keywords: [gc, stress, stressopt, jvmti, nonconcurrent, quick]
- *
- * @library /vmTestbase
- *          /test/lib
- * @run main/othervm/native
- *      -XX:-UseGCOverheadLimit
- *      -agentlib:JVMTIAllocLocker
- *      gc.lock.LockerTest
- *      -gp1 random(primitiveArrays)
- *      -lockers jvmtiAlloc
- */
-
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jvmti/alloc/jvmtialloclock03/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/lock/jvmti/alloc/jvmtialloclock03/TEST.properties
deleted file mode 100644
index 04b22a1..0000000
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jvmti/alloc/jvmtialloclock03/TEST.properties
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-exclusiveAccess.dirs=.
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jvmti/alloc/jvmtialloclock03/TestDescription.java b/test/hotspot/jtreg/vmTestbase/gc/lock/jvmti/alloc/jvmtialloclock03/TestDescription.java
deleted file mode 100644
index bcc954a..0000000
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jvmti/alloc/jvmtialloclock03/TestDescription.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-/*
- * @test
- * @key stress randomness
- *
- * @summary converted from VM Testbase gc/lock/jvmti/alloc/jvmtialloclock03.
- * VM Testbase keywords: [gc, stress, stressopt, jvmti, nonconcurrent]
- *
- * @library /vmTestbase
- *          /test/lib
- * @run main/othervm/native
- *      -XX:-UseGCOverheadLimit
- *      -agentlib:JVMTIAllocLocker
- *      gc.lock.LockerTest
- *      -gp1 interned(randomString)
- *      -lockers jvmtiAlloc
- */
-
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jvmti/alloc/jvmtialloclock04/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/lock/jvmti/alloc/jvmtialloclock04/TEST.properties
deleted file mode 100644
index 04b22a1..0000000
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jvmti/alloc/jvmtialloclock04/TEST.properties
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-exclusiveAccess.dirs=.
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jvmti/alloc/jvmtialloclock04/TestDescription.java b/test/hotspot/jtreg/vmTestbase/gc/lock/jvmti/alloc/jvmtialloclock04/TestDescription.java
deleted file mode 100644
index 9164567..0000000
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jvmti/alloc/jvmtialloclock04/TestDescription.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-/*
- * @test
- * @key stress randomness
- *
- * @summary converted from VM Testbase gc/lock/jvmti/alloc/jvmtialloclock04.
- * VM Testbase keywords: [gc, stress, stressopt, jvmti, nonconcurrent]
- *
- * @library /vmTestbase
- *          /test/lib
- * @run main/othervm/native
- *      -XX:-UseGCOverheadLimit
- *      -agentlib:JVMTIAllocLocker
- *      gc.lock.LockerTest
- *      -gp1 class
- *      -lockers jvmtiAlloc
- */
-
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/malloc/malloclock01/TestDescription.java b/test/hotspot/jtreg/vmTestbase/gc/lock/malloc/malloclock01/TestDescription.java
index 5349f58..47663fe 100644
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/malloc/malloclock01/TestDescription.java
+++ b/test/hotspot/jtreg/vmTestbase/gc/lock/malloc/malloclock01/TestDescription.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,10 +31,8 @@
  *
  * @library /vmTestbase
  *          /test/lib
- * @run main/othervm/native
- *      -XX:-UseGCOverheadLimit
- *      gc.lock.LockerTest
- *      -gp1 randomString
- *      -lockers malloc
+ * @build jdk.test.whitebox.WhiteBox
+ * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
+ * @run main/othervm/native -Xbootclasspath/a:. -Xlog:gc=debug:gc.log -XX:+HeapDumpOnOutOfMemoryError -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI gc.lock.LockerTest -lockers malloc -t 1
  */
 
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/malloc/malloclock02/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/lock/malloc/malloclock02/TEST.properties
deleted file mode 100644
index 04b22a1..0000000
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/malloc/malloclock02/TEST.properties
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-exclusiveAccess.dirs=.
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/malloc/malloclock02/TestDescription.java b/test/hotspot/jtreg/vmTestbase/gc/lock/malloc/malloclock02/TestDescription.java
deleted file mode 100644
index a584d96..0000000
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/malloc/malloclock02/TestDescription.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-/*
- * @test
- * @key stress randomness
- *
- * @summary converted from VM Testbase gc/lock/malloc/malloclock02.
- * VM Testbase keywords: [gc, stress, stressopt, nonconcurrent]
- *
- * @library /vmTestbase
- *          /test/lib
- * @run main/othervm/native
- *      -XX:-UseGCOverheadLimit
- *      gc.lock.LockerTest
- *      -gp1 random(primitiveArrays)
- *      -lockers malloc
- */
-
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/malloc/malloclock03/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/lock/malloc/malloclock03/TEST.properties
deleted file mode 100644
index 04b22a1..0000000
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/malloc/malloclock03/TEST.properties
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-exclusiveAccess.dirs=.
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/malloc/malloclock03/TestDescription.java b/test/hotspot/jtreg/vmTestbase/gc/lock/malloc/malloclock03/TestDescription.java
deleted file mode 100644
index 866c7c3..0000000
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/malloc/malloclock03/TestDescription.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-/*
- * @test
- * @key stress randomness
- *
- * @summary converted from VM Testbase gc/lock/malloc/malloclock03.
- * VM Testbase keywords: [gc, stress, stressopt, nonconcurrent, quick]
- *
- * @library /vmTestbase
- *          /test/lib
- * @run main/othervm/native
- *      -XX:-UseGCOverheadLimit
- *      gc.lock.LockerTest
- *      -gp1 interned(randomString)
- *      -lockers malloc
- */
-
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/malloc/malloclock04/TEST.properties b/test/hotspot/jtreg/vmTestbase/gc/lock/malloc/malloclock04/TEST.properties
deleted file mode 100644
index 04b22a1..0000000
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/malloc/malloclock04/TEST.properties
+++ /dev/null
@@ -1,23 +0,0 @@
-#
-# Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-exclusiveAccess.dirs=.
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/RunAgentThread/agentthr001/agentthr001.cpp b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/RunAgentThread/agentthr001/agentthr001.cpp
index 4fd205e..775f564 100644
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/RunAgentThread/agentthr001/agentthr001.cpp
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/RunAgentThread/agentthr001/agentthr001.cpp
@@ -136,7 +136,11 @@
 
 static void JNICALL
 sys_thread_3(jvmtiEnv* jvmti, JNIEnv* jni, void *p) {
-    while (1) {
+    /* The volatile variable in the loop body is necessary
+     * to avoid the compiler optimization to elide the loop. */
+    volatile int i = 1;
+    while (i) {
+      i += 2;
     }
 }
 
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/share/gc/gp/GarbageUtils.java b/test/hotspot/jtreg/vmTestbase/nsk/share/gc/gp/GarbageUtils.java
index 87dff30..dc5bc5e 100644
--- a/test/hotspot/jtreg/vmTestbase/nsk/share/gc/gp/GarbageUtils.java
+++ b/test/hotspot/jtreg/vmTestbase/nsk/share/gc/gp/GarbageUtils.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@
 import java.io.StringWriter;
 import java.lang.invoke.*;
 import java.util.*;
+import jdk.test.whitebox.WhiteBox;
 import nsk.share.gc.gp.array.*;
 import nsk.share.gc.gp.string.*;
 import nsk.share.gc.gp.list.*;
@@ -87,6 +88,27 @@
         }
 
         /**
+         * engages GC by allocating memory chunks and triggering youngGC.
+         * Allocations are done for a total of YOUNG_GC_ITERATIONS times.
+         * Each iteration, we allocate a memory chunk and trigger youngGC.
+         * Finally fullGC is run once.
+         * This way the objects get to travel to various GC regions.
+         * @param testMemory - memory size to be operated on
+         */
+        public static void engageGC(long testMemory) {
+            final int YOUNG_GC_ITERATIONS = 100;
+            final long memChunk = testMemory / YOUNG_GC_ITERATIONS;
+            int iteration = 0;
+            Object referenceArray[] = new Object[YOUNG_GC_ITERATIONS];
+
+            while (iteration < YOUNG_GC_ITERATIONS) {
+                referenceArray[iteration++] = byteArrayProducer.create(memChunk);
+                WhiteBox.getWhiteBox().youngGC();
+            }
+            WhiteBox.getWhiteBox().fullGC();
+        }
+
+        /**
          * Eat memory using execution controller that waits for 2 minutes.
          * @return number of OOME occured
          */
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except011.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except011.java
deleted file mode 100644
index 0efc3b3..0000000
--- a/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except011.java
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-/*
- * @test
- * @key stress
- *
- * @summary converted from VM testbase nsk/stress/except/except011.
- * VM testbase keywords: [stress, slow, nonconcurrent, quick]
- * VM testbase readme:
- * DESCRIPTION
- *     This checks if various exceptions are thrown (and caught) correctly
- *     when there apparently are no free space in the heap to allocate new
- *     Throwable instance.
- *     The test tries to occupy all of memory available in the heap by allocating
- *     lots of new Object() instances. Instances of the type Object are the smallest
- *     objects, so they apparently should occupy most fine-grained fragments in the
- *     heap and leave no free space for new Throwable instance. After that, the test
- *     provokes various exceptions (e.g.: by executing integer division by 0 and so
- *     on), and checks if appropriate exceptions are thrown.
- * COMMENTS
- *     The test needs a lot of memory to start up, so it should not run under older
- *     JDK 1.1.x release due to its poorer heap utilization. Also, some checks are
- *     skipped when testing classic VM, because OutOfMemoryError is correctly thrown
- *     instead of target exception.
- *     When the test is being self-initiating (i.e.: eating heap), memory occupation
- *     is terminated if memory allocation slows down crucially. This is a workaround
- *     intended to avoid the HotSpot bug:
- *         #4248801 (P1/S5) slow memory allocation when heap is almost exhausted
- *     There is also a workaround involved to avoid the following bugs known
- *     for HotSpot and for classic VM:
- *         #4239841 (P1/S5) 1.1: poor garbage collector performance  (HotSpot bug)
- *         #4245060 (P4/S5) poor garbage collector performance       (Classic VM bug)
- *     However, printing of the test's error messages, warnings, and of execution
- *     trace fails under JDK 1.2 for Win32 even so. If the test fails due to this
- *     problem, exit status 96 is returned instead of 97.
- *     JDK 1.3 classic VM for Sparc may crash (core dump) due to the known bug:
- *         #4245057 (P2/S3) VM crashes when heap is exhausted
- *
- * @run main/othervm -Xms50M -Xmx200M nsk.stress.except.except011
- */
-
-package nsk.stress.except;
-
-import java.io.PrintStream;
-
-/**
- * This checks if various exceptions are thrown (and caught) correctly
- * when there apparently are no free space in the heap to allocate new
- * <code>Throwable</code> instance.
- * <p>
- * <p>The test tries to occupy all of memory available in the heap by
- * allocating lots of new <code>Object()</code> instances. Instances of the
- * type <code>Object</code> are the smallest objects, so they apparently should
- * occupy most fine-grained fragments in the heap and leave no free space for
- * new <code>Throwable</code> instance. After that, the test provokes various
- * exceptions (e.g.: by executing integer division by 0 and so on), and checks
- * if appropriate exceptions are thrown.
- * <p>
- * <p>Note, that memory occupation is terminated if memory allocation slows
- * down crucially. This is a workaround intended to avoid the HotSpot bug:
- * <br>&nbsp;&nbsp;
- * #4248801 (P1/S5) slow memory allocation when heap is almost exhausted
- * <p>
- * <p>There is also a workaround involved to avoid the following bugs known
- * for HotSpot and for classic VM:
- * <br>&nbsp;&nbsp;
- * #4239841 (P1/S5) 1.1: poor garbage collector performance
- * <br>&nbsp;&nbsp;
- * #4245060 (P4/S5) poor garbage collector performance
- * <br>However, printing of the test's error messages, warnings, and of
- * execution trace may fail even so. If the test fails due to poor GC
- * performance, exit status 96 is returned instead of 97.
- * <p>
- * <p>Also note, that the test needs a lot of memory to start up, so it should
- * not run under older JDK 1.1.x release due to its poor heap utilization.
- */
-public class except011 {
-    /**
-     * Either allow or supress printing of execution trace.
-     */
-    private static boolean TRACE_ON = false;
-    /**
-     * Either allow or supress printing of warning messages.
-     */
-    private static final boolean WARN_ON = true;
-    /*
-     * Storage for a lot of tiny objects
-     * "static volatile" keywords are for preventing heap optimization
-     */
-    private static volatile Object pool[] = null;
-    /**
-     * Temporary <code>log</code> for error messages, warnings and/or execution trace.
-     *
-     * @see #messages
-     */
-    private static String log[] = new String[1000]; // up to 1000 messages
-    /**
-     * How many <code>messages</code> were submitted to the <code>log</code>.
-     *
-     * @see #log
-     */
-    private static int messages = 0;
-
-    private static final String className = "nsk.stress.except.except011oops";
-
-    /**
-     * Re-call to the method <code>run(out)</code> (ignore <code>args[]</code>),
-     * and print the test summary - either test passed of failed.
-     */
-    public static int run(String args[], PrintStream out) {
-        if (args.length > 0) {
-            if (args[0].toLowerCase().startsWith("-v"))
-                TRACE_ON = true;
-        }
-
-        int exitCode = run(out);
-        pool = null;
-        System.gc();
-        // Print the log[] and the test summary:
-        try {
-            for (int i = 0; i < messages; i++)
-                out.println(log[i]);
-            if (exitCode == 0) {
-                if (TRACE_ON)
-                    out.println("Test passed.");
-            } else
-                out.println("Test failed.");
-        } catch (OutOfMemoryError oome) {
-            // Poor performance of garbage collector:
-            exitCode = 1;
-        }
-
-        return exitCode;
-    }
-
-    /**
-     * Allocate as much <code>Object</code> instances as possible to bring JVM
-     * into stress, and then check if exceptions are correctly thrown accordingly
-     * to various situations like integer division by 0, etc.
-     */
-    private static int run(PrintStream out) {
-        out.println("# While printing this message, JVM seems to initiate the output");
-        out.println("# stream, so that it will not need more memory to print later,");
-        out.println("# when the heap would fail to provide more memory.");
-        out.println("# ");
-        out.println("# Note, that the test maintains especial static log[] field in");
-        out.println("# order to avoid printing when the heap seems exhausted.");
-        out.println("# Nevertheless, printing could arise OutOfMemoryError even");
-        out.println("# after all the memory allocated by the test is released.");
-        out.println("# ");
-        out.println("# That problem is caused by the known JDK/HotSpot bugs:");
-        out.println("#     4239841 (P1/S5) 1.1: poor garbage collector performance");
-        out.println("#     4245060 (P4/S5) poor garbage collector performance");
-        out.println("# ");
-        out.println("# This message is just intended to work-around that problem.");
-        out.println("# If printing should fail even so, the test will try to return");
-        out.println("# the exit status 96 instead of 97 to indicate the problem.");
-        out.println("# However, the test may fail or even crash on some platforms");
-        out.println("# suffering the bug 4239841 or 4245060.");
-
-        // Sum up exit code:
-        int exitCode = 0; // apparently PASSED
-        int skipped = 0;  // some checks may correctly suffer OutOfMemoryError
-        Class oops;
-        // Allocate repository for a lots of tiny objects:
-        for (int size = 1 << 30; size > 0 && pool == null; size >>= 1)
-            try {
-                pool = new Object[size];
-            } catch (OutOfMemoryError oome) {
-            }
-        if (pool == null)
-            throw new Error("HS bug: cannot allocate new Object[1]");
-        int poolSize = pool.length;
-
-        int index = 0;
-        pool[index++] = new Object();
-
-        // Sum up time spent, when it was hard to JVM to allocate next object
-        // (i.e.: when JVM has spent more than 1 second to allocate new object):
-        double totalDelay = 0;
-        long timeMark = System.currentTimeMillis();
-        try {
-            for (; index < poolSize; index++) {
-                //-------------------------
-                pool[index] = new Object();
-                long nextTimeMark = System.currentTimeMillis();
-                long elapsed = nextTimeMark - timeMark;
-                timeMark = nextTimeMark;
-                //----------------------
-                if (elapsed > 1000) {
-                    double seconds = elapsed / 1000.0;
-                    if (TRACE_ON)
-                        out.println(
-                                "pool[" + index + "]=new Object(); // elapsed " + seconds + "s");
-                    totalDelay += seconds;
-                    if (totalDelay > 60) {
-                        if (TRACE_ON)
-                            out.println(
-                                    "Memory allocation became slow; so, heap seems exhausted.");
-                        break;
-                    }
-                }
-            }
-        } catch (OutOfMemoryError oome) {
-            if (TRACE_ON)
-                log[messages++] = "Heap seems exhausted - OutOfMemoryError thrown.";
-        }
-
-        if (index > poolSize - 1000) {
-            if (WARN_ON)
-                log[messages++] = "Warning: pool[] is full; so, checks would not be enough hard...";
-        }
-
-        // Check ExceptionInInitializerError:
-        try {
-            oops = Class.forName(className);
-            log[messages++] = "Failure: ExceptionInInitializerError failed to throw";
-            exitCode = 2;
-        } catch (ExceptionInInitializerError eiie) {
-            String message = eiie.getException().getMessage();
-            if (!message.equals("except011oops")) {
-                log[messages++] =
-                        "Failure: ExceptionInInitializerError: unexpected target exception";
-                exitCode = 2;
-            } else if (TRACE_ON)
-                log[messages++] = "Success: ExceptionInInitializerError thrown as expected";
-        } catch (ClassNotFoundException cnfe) {
-            log[messages++] = "Failure: ExceptionInInitializerError: target class not found";
-            exitCode = 2;
-        } catch (OutOfMemoryError oome) {
-            if (WARN_ON)
-                log[messages++] =
-                        "Skipped: ExceptionInInitializerError: thrown OutOfMemoryError";
-            skipped++;
-        }
-
-        return exitCode;
-    }
-
-    /**
-     * Re-call to <code>run(args,out)</code>, and return JCK-like exit status.
-     * (The stream <code>out</code> is assigned to <code>System.out</code> here.)
-     *
-     * @see #run(String[], PrintStream)
-     */
-    public static void main(String args[]) {
-        Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
-            // Last try. If there is some OOME, test should end correctly
-            @Override
-            public void uncaughtException(Thread t, Throwable e) {
-                try {
-                    pool = null;
-                    log = null;
-                    System.gc(); // Empty memory to be able to write to the output
-                    if (e instanceof OutOfMemoryError) {
-                        try {
-                            System.out.println("OOME : Test Skipped");
-                            System.exit(0);
-                        } catch (Throwable ignore) {
-                        } // No code in the handler can provoke correct exceptions.
-                    } else {
-                        e.printStackTrace();
-                        throw (RuntimeException) e;
-                    }
-                } catch (OutOfMemoryError oome) {
-                }
-            }
-        });
-        int exitCode = run(args, System.out);
-        System.exit(exitCode + 95);
-        // JCK-like exit status.
-    }
-
-}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except011oops.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except011oops.java
deleted file mode 100644
index 46c9324..0000000
--- a/test/hotspot/jtreg/vmTestbase/nsk/stress/except/except011oops.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package nsk.stress.except;
-
-/**
- * This class throws exception while static initialization.
- * The test should load this class via reflection in order
- * to hold the exception until runtime.
- *
- * @see nsk.stress.except.except011
- */
-public class except011oops {
-    static boolean truth = true;
-
-    static {
-        if (truth)
-            throw new RuntimeException("except011oops");
-    }
-}
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/TEST.properties b/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/TEST.properties
deleted file mode 100644
index 8b51b2a..0000000
--- a/test/hotspot/jtreg/vmTestbase/nsk/stress/jni/TEST.properties
+++ /dev/null
@@ -1,24 +0,0 @@
-#
-# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-exclusiveAccess.dirs=.
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/thread/TEST.properties b/test/hotspot/jtreg/vmTestbase/nsk/stress/thread/TEST.properties
deleted file mode 100644
index 8b51b2a..0000000
--- a/test/hotspot/jtreg/vmTestbase/nsk/stress/thread/TEST.properties
+++ /dev/null
@@ -1,24 +0,0 @@
-#
-# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-exclusiveAccess.dirs=.
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/thread/thread007.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/thread/thread007.java
index 07031a7..26388c2 100644
--- a/test/hotspot/jtreg/vmTestbase/nsk/stress/thread/thread007.java
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/thread/thread007.java
@@ -32,7 +32,7 @@
  *     Try to start the given number of threads starting simultaneously
  *     when notifyall() is signaled at the stopLine object.
  *
- * @run main/othervm nsk.stress.thread.thread007 500 2m 5s
+ * @run main/othervm/timeout=300 nsk.stress.thread.thread007 500 2m 5s
  */
 
 package nsk.stress.thread;
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/thread/thread008.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/thread/thread008.java
index 40a76e0..2cbc198 100644
--- a/test/hotspot/jtreg/vmTestbase/nsk/stress/thread/thread008.java
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/thread/thread008.java
@@ -33,7 +33,7 @@
  *     starting simultaneously when notifyall() is signaled at the
  *     stopLine object.
  *
- * @run main/othervm nsk.stress.thread.thread008 500 2m 5s
+ * @run main/othervm/timeout=300 nsk.stress.thread.thread008 500 2m 5s
  */
 
 package nsk.stress.thread;
diff --git a/test/jaxp/TEST.groups b/test/jaxp/TEST.groups
index 0b67ed4..f8cb73c 100644
--- a/test/jaxp/TEST.groups
+++ b/test/jaxp/TEST.groups
@@ -20,6 +20,14 @@
 #  questions.
 #
 
+# All tests
+
+all = \
+    :jaxp_all
+
+jaxp_all = \
+    /
+
 # Tiered testing definitions
 
 # No jaxp tests are tier 1.
@@ -34,6 +42,3 @@
 
 # No tier 4 tests.
 tier4 =
-
-jaxp_all = \
-    javax/xml/jaxp
diff --git a/test/jaxp/javax/xml/jaxp/unittest/validation/ErrorHandlingTest.java b/test/jaxp/javax/xml/jaxp/unittest/validation/ErrorHandlingTest.java
new file mode 100644
index 0000000..b007c73
--- /dev/null
+++ b/test/jaxp/javax/xml/jaxp/unittest/validation/ErrorHandlingTest.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package validation;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.ArrayList;
+import static java.util.Collections.unmodifiableList;
+import java.util.List;
+import javax.xml.XMLConstants;
+import javax.xml.transform.Source;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import javax.xml.validation.Validator;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+/*
+ * @test
+ * @bug 8298087
+ * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
+ * @run testng validation.ErrorHandlingTest
+ * @summary Verifies error handling.
+ */
+public class ErrorHandlingTest {
+    private final static String xsd = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"
+            +"<schema xmlns=\"http://www.w3.org/2001/XMLSchema\""
+            +"       targetNamespace=\"https://errorhandlingtest/schema/Example\""
+            +"        elementFormDefault=\"qualified\">"
+            +"\n"
+            +"    <element name=\"root\">"
+            +"        <complexType>"
+            +"            <sequence>"
+            +"                <element name=\"a\">"
+            +"                    <complexType>"
+            +"                        <simpleContent>"
+            +"                            <extension base=\"string\">"
+            +"                                <attribute name=\"enabled\" type=\"boolean\" use=\"required\"/>"
+            +"                            </extension>"
+            +"                        </simpleContent>"
+            +"                    </complexType>"
+            +"                </element>"
+            +"            </sequence>"
+            +"        </complexType>"
+            +"    </element>"
+            +"\n"
+            +"</schema>";
+
+    private final static String xml = "<e:root xmlns:e=\"https://errorhandlingtest/schema/Example\">\n"
+            +"    <e:a>string</e:a>\n"
+            +"</e:root>";
+
+    /**
+     * Verifies that validation error is reported properly (once rather than twice).
+     *
+     * @throws Exception if the test fails
+     */
+    @Test
+    public void test() throws Exception {
+        List<SAXParseException> ex = validateXMLWithSchema(new StreamSource(new StringReader(xsd)),
+                new StreamSource(new StringReader(xml)));
+        Assert.assertEquals(ex.size(), 1);
+    }
+
+    public static List<SAXParseException> validateXMLWithSchema(final Source xsd, final Source xml) {
+        final List<SAXParseException> exceptions = new ArrayList<>();
+        try {
+            final SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+            final Schema schema = factory.newSchema(xsd);
+            final Validator validator = schema.newValidator();
+            validator.setErrorHandler(new ErrorHandler() {
+                @Override
+                public void warning(final SAXParseException exception) {
+                    System.err.printf("Warning: %s%n", exception);
+                    exceptions.add(exception);
+                }
+
+                @Override
+                public void error(final SAXParseException exception) {
+                    System.err.printf("Error: %s%n", exception);
+                    exceptions.add(exception);
+                }
+
+                @Override
+                public void fatalError(final SAXParseException exception) {
+                    System.err.printf("Fatal: %s%n", exception);
+                    exceptions.add(exception);
+                }
+            });
+
+            validator.validate(xml);
+
+        } catch (final SAXException | IOException e) {
+            System.err.printf("Exception: %s%n", e.getMessage());
+        }
+        return unmodifiableList(exceptions);
+    }
+
+}
diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt
index 5a9145e..f87c8f7 100644
--- a/test/jdk/ProblemList.txt
+++ b/test/jdk/ProblemList.txt
@@ -548,7 +548,6 @@
 # jdk_io
 
 java/io/pathNames/GeneralWin32.java                             8180264 windows-all
-java/io/File/createTempFile/SpecialTempFile.java                8274122 windows11
 
 ############################################################################
 
@@ -660,6 +659,7 @@
 sun/security/pkcs11/rsa/TestKeyPairGenerator.java               8295343 linux-all
 sun/security/pkcs11/rsa/TestKeyFactory.java                     8295343 linux-all
 sun/security/pkcs11/KeyStore/Basic.java                         8295343 linux-all
+sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java            8316183 linux-ppc64le
 
 ############################################################################
 
diff --git a/test/jdk/TEST.ROOT b/test/jdk/TEST.ROOT
index a584c31..25d2a4e 100644
--- a/test/jdk/TEST.ROOT
+++ b/test/jdk/TEST.ROOT
@@ -52,6 +52,7 @@
 requires.properties= \
     sun.arch.data.model \
     java.runtime.name \
+    vm.flagless \
     vm.gc.G1 \
     vm.gc.Serial \
     vm.gc.Parallel \
diff --git a/test/jdk/TEST.groups b/test/jdk/TEST.groups
index 0b3502d..c31ce5d 100644
--- a/test/jdk/TEST.groups
+++ b/test/jdk/TEST.groups
@@ -22,6 +22,17 @@
 
 ###############################################################################
 #
+# All tests
+#
+
+all = \
+    :jdk_all
+
+jdk_all = \
+    /
+
+###############################################################################
+#
 # Tiered testing definitions
 #
 
@@ -210,6 +221,7 @@
 jdk_security2 = \
     javax/crypto \
     javax/xml/crypto \
+    com/sun/org/apache/xml/internal/security \
     com/sun/crypto
 
 jdk_security3 = \
@@ -218,7 +230,6 @@
     com/sun/jarsigner \
     com/sun/security \
     -com/sun/security/jgss \
-    com/sun/org/apache/xml/internal/security \
     jdk/security \
     sun/security \
     -sun/security/krb5 \
@@ -591,3 +602,8 @@
     java/util/TimeZone/DefaultTimeZoneTest.java
 
 
+# Test sets for running inside container environment
+jdk_containers_extended = \
+    :jdk_io \
+    :jdk_nio \
+    :jdk_svc
diff --git a/test/jdk/com/sun/jdi/JdwpOnThrowTest.java b/test/jdk/com/sun/jdi/JdwpOnThrowTest.java
index d083b2a..ba35646 100644
--- a/test/jdk/com/sun/jdi/JdwpOnThrowTest.java
+++ b/test/jdk/com/sun/jdi/JdwpOnThrowTest.java
@@ -57,12 +57,11 @@
     private static AttachingConnector attachingConnector;
 
     public static void main(String[] args) throws Exception {
-        int port = findFreePort();
-        try (Debuggee debuggee = Debuggee.launcher("ThrowCaughtException").setAddress("localhost:" + port)
-                                         .enableOnThrow("Ex", "Start").setSuspended(true).launch()) {
+        try (Debuggee debuggee = Debuggee.launcher("ThrowCaughtException")
+                                         .enableOnThrow("Ex").setSuspended(true).launch()) {
             VirtualMachine vm = null;
             try {
-                vm = attach("localhost", "" + port);
+                vm = attach("localhost", debuggee.getAddress());
                 EventQueue queue = vm.eventQueue();
                 log("Waiting for exception event");
                 long start = System.currentTimeMillis();
@@ -110,14 +109,6 @@
         }
     }
 
-    private static int findFreePort() {
-        try (ServerSocket socket = new ServerSocket(0)) {
-            return socket.getLocalPort();
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
     private static VirtualMachine attach(String address, String port) throws IOException {
         if (attachingConnector == null) {
             attachingConnector = (AttachingConnector)getConnector(ATTACH_CONNECTOR);
diff --git a/test/jdk/com/sun/jdi/lib/jdb/Debuggee.java b/test/jdk/com/sun/jdi/lib/jdb/Debuggee.java
index b1a1b58..2379a9e 100644
--- a/test/jdk/com/sun/jdi/lib/jdb/Debuggee.java
+++ b/test/jdk/com/sun/jdi/lib/jdb/Debuggee.java
@@ -24,6 +24,7 @@
 package lib.jdb;
 
 import jdk.test.lib.Utils;
+import jdk.test.lib.util.Pair;
 import jdk.test.lib.process.ProcessTools;
 
 import java.io.Closeable;
@@ -32,6 +33,7 @@
 import java.util.List;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
+import java.util.function.Function;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
@@ -70,8 +72,7 @@
         private String address = null;
         private boolean suspended = true;
         private String onthrow = "";
-        private boolean waitForPortPrint = true;
-        private String expectedOutputBeforeThrow = "";
+        private static final String LAUNCH_ECHO_STRING = "Listen Args:";
 
         private Launcher(String mainClass) {
             this.mainClass = mainClass;
@@ -104,11 +105,8 @@
             return this;
         }
 
-        // required to pass non null port with address and emit string before the throw
-        public Launcher enableOnThrow(String value, String expectedOutputBeforeThrow) {
-            this.onthrow = value;
-            this.waitForPortPrint = false;
-            this.expectedOutputBeforeThrow = expectedOutputBeforeThrow;
+        public Launcher enableOnThrow(String exceptionClassName) {
+            this.onthrow = exceptionClassName;
             return this;
         }
 
@@ -117,7 +115,7 @@
             if (vmOptions != null) {
                 debuggeeArgs.add(vmOptions);
             }
-            String onthrowArgs = onthrow.isEmpty() ? "" : ",onthrow=" + onthrow + ",launch=exit";
+            String onthrowArgs = onthrow.isEmpty() ? "" : ",onthrow=" + onthrow + ",launch=echo " + LAUNCH_ECHO_STRING;
             debuggeeArgs.add("-agentlib:jdwp=transport=" + transport
                     + (address == null ? "" : ",address=" + address)
                     + ",server=y,suspend=" + (suspended ? "y" : "n")
@@ -128,41 +126,57 @@
         }
 
         public Debuggee launch(String name) {
-            return new Debuggee(prepare(), name, waitForPortPrint, expectedOutputBeforeThrow);
+            return new Debuggee(prepare(), name,
+                onthrow.isEmpty() ?
+                    Launcher::parseListenAddress :
+                    Launcher::parseLaunchEchoListenAddress
+            );
         }
         public Debuggee launch() {
             return launch("debuggee");
         }
+
+        /**
+         * Parses debuggee output to get listening transport and address, printed by `launch=echo`.
+         * Returns null if the string specified does not contain required info.
+         */
+        private static Pair<String, String> parseLaunchEchoListenAddress(String debuggeeOutput) {
+            Pattern listenRegexp = Pattern.compile(LAUNCH_ECHO_STRING + " \\b(.+)\\b \\b(.+)\\b");
+            Matcher m = listenRegexp.matcher(debuggeeOutput);
+            if (m.find()) {
+                return new Pair<String, String>(m.group(1), m.group(2));
+            }
+            return null;
+        }
+
+        /**
+         * Parses debuggee output to get listening transport and address, printed by `launch=echo`.
+         * Returns null if the string specified does not contain required info.
+         */
+        private static Pair<String, String> parseListenAddress(String debuggeeOutput) {
+            Pattern listenRegexp = Pattern.compile("Listening for transport \\b(.+)\\b at address: \\b(.+)\\b");
+            Matcher m = listenRegexp.matcher(debuggeeOutput);
+            if (m.find()) {
+                return new Pair<String, String>(m.group(1), m.group(2));
+            }
+            return null;
+        }
     }
 
-    // starts the process, waits for "Listening for transport" output and detects transport/address
-    private Debuggee(ProcessBuilder pb, String name, boolean waitForPortPrint, String expectedOutputBeforeThrow) {
-        // debuggeeListen[0] - transport, debuggeeListen[1] - address
+    // starts the process, waits until the provided addressDetector detects transport/address from the process output
+    private Debuggee(ProcessBuilder pb, String name, Function<String, Pair<String, String>> addressDetector) {
         String[] debuggeeListen = new String[2];
-        Pattern listenRegexp = Pattern.compile("Listening for transport \\b(.+)\\b at address: \\b(.+)\\b");
-        if (!waitForPortPrint) {
-            try {
-                p = ProcessTools.startProcess(name, pb, s -> {output.add(s);}, s -> {
-                    return s.equals(expectedOutputBeforeThrow);
-                }, 30, TimeUnit.SECONDS);
-            } catch (IOException | InterruptedException | TimeoutException ex) {
-                throw new RuntimeException("failed to launch debuggee", ex);
-            }
-            transport = null;
-            address = null;
-            return;
-        }
         try {
             p = ProcessTools.startProcess(name, pb,
                     s -> output.add(s),  // output consumer
-                    s -> {  // warm-up predicate
-                        Matcher m = listenRegexp.matcher(s);
-                        if (!m.matches()) {
-                            return false;
+                    s -> {
+                        Pair<String, String> addr = addressDetector.apply(s);
+                        if (addr != null) {
+                            debuggeeListen[0] = addr.first;
+                            debuggeeListen[1] = addr.second;
+                            return true;
                         }
-                        debuggeeListen[0] = m.group(1);
-                        debuggeeListen[1] = m.group(2);
-                        return true;
+                        return false;
                     },
                     30, TimeUnit.SECONDS);
             transport = debuggeeListen[0];
@@ -219,5 +233,4 @@
             p.destroy();
         }
     }
-
 }
diff --git a/test/jdk/com/sun/jndi/ldap/LdapPoolTimeoutTest.java b/test/jdk/com/sun/jndi/ldap/LdapPoolTimeoutTest.java
index 4646d9f..66865f8 100644
--- a/test/jdk/com/sun/jndi/ldap/LdapPoolTimeoutTest.java
+++ b/test/jdk/com/sun/jndi/ldap/LdapPoolTimeoutTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -124,7 +124,7 @@
             // assertCompletion may wrap a CommunicationException in an RTE
             assertNotNull(msg);
             assertTrue(msg.contains("Network is unreachable")
-                        || msg.contains("No route to host"));
+                        || msg.contains("No route to host") || msg.contains("Connection timed out"));
         } catch (NamingException ex) {
             String msg = ex.getCause() == null ? ex.getMessage() : ex.getCause().getMessage();
             System.err.println("MSG: " + msg);
diff --git a/test/jdk/com/sun/management/HotSpotDiagnosticMXBean/CheckOrigin.java b/test/jdk/com/sun/management/HotSpotDiagnosticMXBean/CheckOrigin.java
index e51f7e3..d146d98 100644
--- a/test/jdk/com/sun/management/HotSpotDiagnosticMXBean/CheckOrigin.java
+++ b/test/jdk/com/sun/management/HotSpotDiagnosticMXBean/CheckOrigin.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
  * @test
  * @bug 8028994
  * @author Staffan Larsen
+ * @requires vm.flagless
  * @library /test/lib
  * @modules jdk.attach/sun.tools.attach
  *          jdk.management
diff --git a/test/jdk/com/sun/management/ThreadMXBean/ThreadAllocatedMemory.java b/test/jdk/com/sun/management/ThreadMXBean/ThreadAllocatedMemory.java
index 9d954f9..3ff2a3b 100644
--- a/test/jdk/com/sun/management/ThreadMXBean/ThreadAllocatedMemory.java
+++ b/test/jdk/com/sun/management/ThreadMXBean/ThreadAllocatedMemory.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,10 +22,19 @@
  */
 
 /*
- * @test
- * @bug     6173675 8231209
+ * @test    id=G1
+ * @bug     6173675 8231209 8304074 8313081
  * @summary Basic test of ThreadMXBean.getThreadAllocatedBytes
- * @author  Paul Hohensee
+ * @requires vm.gc.G1
+ * @run main/othervm -XX:+UseG1GC ThreadAllocatedMemory
+ */
+
+/*
+ * @test    id=Serial
+ * @bug     6173675 8231209 8304074 8313081
+ * @summary Basic test of ThreadMXBean.getThreadAllocatedBytes
+ * @requires vm.gc.Serial
+ * @run main/othervm -XX:+UseSerialGC ThreadAllocatedMemory
  */
 
 import java.lang.management.*;
@@ -33,6 +42,7 @@
 public class ThreadAllocatedMemory {
     private static com.sun.management.ThreadMXBean mbean =
         (com.sun.management.ThreadMXBean)ManagementFactory.getThreadMXBean();
+    private static boolean testFailed = false;
     private static volatile boolean done = false;
     private static volatile boolean done1 = false;
     private static Object obj = new Object();
@@ -55,6 +65,13 @@
         // Test many threads that are not this one
         testGetThreadsAllocatedBytes();
 
+        // Test cumulative Java thread allocation since JVM launch
+        testGetTotalThreadAllocatedBytes();
+
+        if (testFailed) {
+            throw new RuntimeException("TEST FAILED");
+        }
+
         System.out.println("Test passed");
     }
 
@@ -92,13 +109,15 @@
     }
 
     private static void testGetCurrentThreadAllocatedBytes() {
+        Thread curThread = Thread.currentThread();
+
         long size = mbean.getCurrentThreadAllocatedBytes();
-        ensureValidSize(size);
+        ensureValidSize(curThread, size);
 
         // do some more allocation
         doit();
 
-        checkResult(Thread.currentThread(), size,
+        checkResult(curThread, size,
                     mbean.getCurrentThreadAllocatedBytes());
     }
 
@@ -107,7 +126,7 @@
         long id = curThread.getId();
 
         long size = mbean.getThreadAllocatedBytes(id);
-        ensureValidSize(size);
+        ensureValidSize(curThread, size);
 
         // do some more allocation
         doit();
@@ -119,7 +138,8 @@
         throws Exception {
 
         // start a thread
-        done = false; done1 = false;
+        done = false;
+        done1 = false;
         Thread curThread = new MyThread("MyThread");
         curThread.start();
         long id = curThread.getId();
@@ -128,7 +148,7 @@
         waitUntilThreadBlocked(curThread);
 
         long size = mbean.getThreadAllocatedBytes(id);
-        ensureValidSize(size);
+        ensureValidSize(curThread, size);
 
         // let thread go to do some more allocation
         synchronized (obj) {
@@ -152,8 +172,7 @@
         try {
             curThread.join();
         } catch (InterruptedException e) {
-            System.out.println("Unexpected exception is thrown.");
-            e.printStackTrace(System.out);
+            reportUnexpected(e, "during join");
         }
     }
 
@@ -161,7 +180,8 @@
         throws Exception {
 
         // start threads
-        done = false; done1 = false;
+        done = false;
+        done1 = false;
         for (int i = 0; i < NUM_THREADS; i++) {
             threads[i] = new MyThread("MyThread-" + i);
             threads[i].start();
@@ -172,7 +192,7 @@
 
         for (int i = 0; i < NUM_THREADS; i++) {
             sizes[i] = mbean.getThreadAllocatedBytes(threads[i].getId());
-            ensureValidSize(sizes[i]);
+            ensureValidSize(threads[i], sizes[i]);
         }
 
         // let threads go to do some more allocation
@@ -201,38 +221,106 @@
             try {
                 threads[i].join();
             } catch (InterruptedException e) {
-                System.out.println("Unexpected exception is thrown.");
-                e.printStackTrace(System.out);
+                reportUnexpected(e, "during join");
                 break;
             }
         }
     }
 
-    private static void ensureValidSize(long size) {
+    private static void testGetTotalThreadAllocatedBytes()
+        throws Exception {
+
+        // baseline should be positive
+        Thread curThread = Thread.currentThread();
+        long cumulativeSize = mbean.getTotalThreadAllocatedBytes();
+        if (cumulativeSize <= 0) {
+            throw new RuntimeException(
+                "Invalid allocated bytes returned for " + curThread.getName() + " = " + cumulativeSize);
+        }
+
+        // start threads
+        done = false;
+        done1 = false;
+        for (int i = 0; i < NUM_THREADS; i++) {
+            threads[i] = new MyThread("MyThread-" + i);
+            threads[i].start();
+        }
+
+        // wait for threads to block after doing some allocation
+        waitUntilThreadsBlocked();
+
+        // check after threads are blocked
+        cumulativeSize = checkResult(curThread, cumulativeSize, mbean.getTotalThreadAllocatedBytes());
+
+        // let threads go to do some more allocation
+        synchronized (obj) {
+            done = true;
+            obj.notifyAll();
+        }
+
+        // wait for threads to get going again. we don't care if we
+        // catch them in mid-execution or if some of them haven't
+        // restarted after we're done sleeping.
+        goSleep(400);
+
+        System.out.println("Done sleeping");
+
+        // check while threads are running
+        cumulativeSize = checkResult(curThread, cumulativeSize, mbean.getTotalThreadAllocatedBytes());
+
+        // let threads exit
+        synchronized (obj) {
+            done1 = true;
+            obj.notifyAll();
+        }
+
+        for (int i = 0; i < NUM_THREADS; i++) {
+            try {
+                threads[i].join();
+            } catch (InterruptedException e) {
+                reportUnexpected(e, "during join");
+                break;
+            }
+        }
+
+        // check after threads exit
+        checkResult(curThread, cumulativeSize, mbean.getTotalThreadAllocatedBytes());
+    }
+
+    private static void ensureValidSize(Thread curThread, long size) {
         // implementation could have started measurement when
         // measurement was enabled, in which case size can be 0
         if (size < 0) {
             throw new RuntimeException(
-                "Invalid allocated bytes returned = " + size);
+                "Invalid allocated bytes returned for thread " +
+                curThread.getName() + " = " + size);
         }
     }
 
-    private static void checkResult(Thread curThread,
-                                    long prev_size, long curr_size) {
-        if (curr_size < prev_size) {
-            throw new RuntimeException("Allocated bytes " + curr_size +
-                                       " expected >= " + prev_size);
-        }
+    private static long checkResult(Thread curThread,
+                                    long prevSize, long currSize) {
         System.out.println(curThread.getName() +
-                           " Previous allocated bytes = " + prev_size +
-                           " Current allocated bytes = " + curr_size);
+                           " Previous allocated bytes = " + prevSize +
+                           " Current allocated bytes = " + currSize);
+        if (currSize < prevSize) {
+            throw new RuntimeException("TEST FAILED: " +
+                                       curThread.getName() +
+                                       " previous allocated bytes = " + prevSize +
+                                       " > current allocated bytes = " + currSize);
+        }
+        return currSize;
+    }
+
+    private static void reportUnexpected(Exception e, String when) {
+        System.out.println("Unexpected exception thrown " + when + ".");
+        e.printStackTrace(System.out);
+        testFailed = true;
     }
 
     private static void goSleep(long ms) throws Exception {
         try {
             Thread.sleep(ms);
         } catch (InterruptedException e) {
-            System.out.println("Unexpected exception is thrown.");
             throw e;
         }
     }
@@ -287,34 +375,23 @@
                     try {
                         obj.wait();
                     } catch (InterruptedException e) {
-                        System.out.println("Unexpected exception is thrown.");
-                        e.printStackTrace(System.out);
+                        reportUnexpected(e, "while !done");
                         break;
                     }
                 }
             }
 
-            long size1 = mbean.getThreadAllocatedBytes(getId());
+            long prevSize = mbean.getThreadAllocatedBytes(getId());
             ThreadAllocatedMemory.doit();
-            long size2 = mbean.getThreadAllocatedBytes(getId());
-
-            System.out.println(getName() + ": " +
-                "ThreadAllocatedBytes  = " + size1 +
-                " ThreadAllocatedBytes  = " + size2);
-
-            if (size1 > size2) {
-                throw new RuntimeException(getName() +
-                    " ThreadAllocatedBytes = " + size1 +
-                    " > ThreadAllocatedBytes = " + size2);
-            }
+            long currSize = mbean.getThreadAllocatedBytes(getId());
+            checkResult(this, prevSize, currSize);
 
             synchronized (obj) {
                 while (!done1) {
                     try {
                         obj.wait();
                     } catch (InterruptedException e) {
-                        System.out.println("Unexpected exception is thrown.");
-                        e.printStackTrace(System.out);
+                        reportUnexpected(e, "while !done1");
                         break;
                     }
                 }
diff --git a/test/jdk/com/sun/management/ThreadMXBean/ThreadAllocatedMemoryArray.java b/test/jdk/com/sun/management/ThreadMXBean/ThreadAllocatedMemoryArray.java
index cbd3d1d..d325d1d 100644
--- a/test/jdk/com/sun/management/ThreadMXBean/ThreadAllocatedMemoryArray.java
+++ b/test/jdk/com/sun/management/ThreadMXBean/ThreadAllocatedMemoryArray.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -47,7 +47,6 @@
             return;
         }
 
-
         // start threads, wait for them to block
         long[] ids = new long[NUM_THREADS];
 
@@ -59,7 +58,6 @@
 
         waitUntilThreadBlocked();
 
-
         // disable allocated memory measurement
         if (mbean.isThreadAllocatedMemoryEnabled()) {
             mbean.setThreadAllocatedMemoryEnabled(false);
@@ -117,19 +115,9 @@
         // restarted after we're done sleeping.
         goSleep(400);
 
-        long[] sizes1 = mbean.getThreadAllocatedBytes(ids);
-
+        long[] afterSizes = mbean.getThreadAllocatedBytes(ids);
         for (int i = 0; i < NUM_THREADS; i++) {
-            long newSize = sizes1[i];
-            if (sizes[i] > newSize) {
-                throw new RuntimeException("TEST FAILED: " +
-                    threads[i].getName() +
-                    " previous allocated bytes = " + sizes[i] +
-                    " > current allocated bytes = " + newSize);
-            }
-            System.out.println(threads[i].getName() +
-                " Previous allocated bytes = " + sizes[i] +
-                " Current allocated bytes = " + newSize);
+            checkResult(threads[i], sizes[i], afterSizes[i]);
         }
 
         try {
@@ -147,7 +135,6 @@
                 "Caught expected IllegalArgumentException: " + e.getMessage());
         }
 
-
         // let threads exit
         synchronized (obj) {
             done1 = true;
@@ -158,9 +145,7 @@
             try {
                 threads[i].join();
             } catch (InterruptedException e) {
-                System.out.println("Unexpected exception is thrown.");
-                e.printStackTrace(System.out);
-                testFailed = true;
+                reportUnexpected(e, "during join");
                 break;
             }
         }
@@ -173,11 +158,30 @@
     }
 
 
+    private static void checkResult(Thread curThread,
+                                    long prevSize, long currSize) {
+        System.out.println(curThread.getName() +
+                           " Previous allocated bytes = " + prevSize +
+                           " Current allocated bytes = " + currSize);
+        if (currSize < prevSize) {
+            throw new RuntimeException("TEST FAILED: " +
+                                       curThread.getName() +
+                                       " previous allocated bytes = " + prevSize +
+                                       " > current allocated bytes = " + currSize);
+
+        }
+    }
+
+    private static void reportUnexpected(Exception e, String when) {
+        System.out.println("Unexpected exception thrown " + when + ".");
+        e.printStackTrace(System.out);
+        testFailed = true;
+    }
+
     private static void goSleep(long ms) throws Exception {
         try {
             Thread.sleep(ms);
         } catch (InterruptedException e) {
-            System.out.println("Unexpected exception is thrown.");
             throw e;
         }
     }
@@ -221,9 +225,7 @@
                     try {
                         obj.wait();
                     } catch (InterruptedException e) {
-                        System.out.println("Unexpected exception is thrown.");
-                        e.printStackTrace(System.out);
-                        testFailed = true;
+                        reportUnexpected(e, "while !done");
                         break;
                     }
                 }
@@ -236,9 +238,7 @@
                     try {
                         obj.wait();
                     } catch (InterruptedException e) {
-                        System.out.println("Unexpected exception is thrown.");
-                        e.printStackTrace(System.out);
-                        testFailed = true;
+                        reportUnexpected(e, "while !done");
                         break;
                     }
                 }
diff --git a/test/jdk/com/sun/net/httpserver/SANTest.java b/test/jdk/com/sun/net/httpserver/SANTest.java
new file mode 100644
index 0000000..db0fc05
--- /dev/null
+++ b/test/jdk/com/sun/net/httpserver/SANTest.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8278312
+ * @library /test/lib /test/jdk/java/net/httpclient /test/jdk/java/net/httpclient/http2/server
+ * @build jdk.test.lib.net.SimpleSSLContext HttpServerAdapters Http2Handler
+ *          jdk.test.lib.net.IPSupport
+ *          Http2TestExchange
+ *
+ * @modules java.net.http/jdk.internal.net.http.common
+ *          java.net.http/jdk.internal.net.http.frame
+ *          java.net.http/jdk.internal.net.http.hpack
+ *          java.logging
+ *          java.base/sun.net.www.http
+ *          java.base/sun.net.www
+ *          java.base/sun.net
+ *
+ * @run main/othervm SANTest
+ * @summary Update SimpleSSLContext keystore to use SANs for localhost IP addresses
+ */
+
+import com.sun.net.httpserver.*;
+
+import java.util.concurrent.*;
+import java.io.*;
+import java.net.*;
+import java.net.http.*;
+import java.nio.charset.StandardCharsets;
+import javax.net.ssl.*;
+import jdk.test.lib.net.SimpleSSLContext;
+import jdk.test.lib.net.URIBuilder;
+import jdk.test.lib.net.IPSupport;
+
+/*
+ * Will fail if the testkeys file belonging to SimpleSSLContext
+ * does not have SAN entries for 127.0.0.1 or ::1
+ */
+public class SANTest implements HttpServerAdapters {
+
+    static SSLContext ctx;
+
+    static HttpServer getHttpsServer(InetSocketAddress addr, Executor exec, SSLContext ctx) throws Exception {
+        HttpsServer server = HttpsServer.create(addr, 0);
+        server.setExecutor(exec);
+        server.setHttpsConfigurator(new HttpsConfigurator (ctx));
+        return server;
+    }
+
+    static final boolean hasIPv4 = IPSupport.hasIPv4();
+    static final boolean hasIPv6 = IPSupport.hasIPv6();
+
+    static HttpTestServer initServer(boolean h2, InetAddress addr, SSLContext ctx,
+                String sni, ExecutorService e) throws Exception {
+        HttpTestServer s = null;
+        InetSocketAddress ia = new InetSocketAddress (addr, 0);
+        if ((addr instanceof Inet4Address) && !hasIPv4)
+                return null;
+        if ((addr instanceof Inet6Address) && !hasIPv6)
+                return null;
+
+        if (!h2) {
+            s = HttpTestServer.of(getHttpsServer(ia, e, ctx));
+            HttpTestHandler h = new HttpTestEchoHandler();
+            s.addHandler(h, "/test1");
+            s.start();
+            return s;
+        } else {
+            s = HttpTestServer.of(new Http2TestServer(addr, sni, true, 0, e,
+                        10, null, ctx, false));
+            HttpTestHandler h = new HttpTestEchoHandler();
+            s.addHandler(h, "/test1");
+            s.start();
+            return s;
+        }
+    }
+
+    public static void main (String[] args) throws Exception {
+        // Http/1.1 servers
+        HttpTestServer h1s1 = null;
+        HttpTestServer h1s2 = null;
+
+        // Http/2 servers
+        HttpTestServer h2s1 = null;
+        HttpTestServer h2s2 = null;
+
+        ExecutorService executor=null;
+        try {
+            System.out.print ("SANTest: ");
+            ctx = new SimpleSSLContext().get();
+            executor = Executors.newCachedThreadPool();
+
+            InetAddress l1 = InetAddress.getByName("::1");
+            InetAddress l2 = InetAddress.getByName("127.0.0.1");
+
+            h1s1 = initServer(false, l1, ctx, "::1", executor);
+            h1s2 = initServer(false, l2, ctx, "127.0.0.1", executor);
+
+            h2s1 = initServer(true, l1, ctx, "::1", executor);
+            h2s2 = initServer(true, l2, ctx, "127.0.0.1", executor);
+
+            test("127.0.0.1", h1s2);
+            test("::1", h1s1);
+            testNew("127.0.0.1", h2s2, executor);
+            testNew("::1", h2s1, executor);
+            System.out.println ("OK");
+        } finally {
+            if (h1s1 != null)
+                h1s1.stop();
+            if (h1s2 != null)
+                h1s2.stop();
+            if (h2s1 != null)
+                h2s1.stop();
+            if (h2s2 != null)
+                h2s2.stop();
+            if (executor != null)
+                executor.shutdown ();
+        }
+    }
+
+    static void test (String host, HttpTestServer server) throws Exception {
+        if (server == null)
+            return;
+        int port = server.getAddress().getPort();
+        String body = "Yellow world";
+        URL url = URIBuilder.newBuilder()
+                 .scheme("https")
+                 .host(host)
+                 .port(port)
+                 .path("/test1/foo.txt")
+                 .toURL();
+        System.out.println("URL = " + url);
+        HttpURLConnection urlc = (HttpURLConnection) url.openConnection(Proxy.NO_PROXY);
+        System.out.println("urlc = " + urlc);
+        if (urlc instanceof HttpsURLConnection) {
+            HttpsURLConnection urlcs = (HttpsURLConnection) urlc;
+            urlcs.setSSLSocketFactory (ctx.getSocketFactory());
+        }
+
+        urlc.setRequestMethod("POST");
+        urlc.setDoOutput(true);
+
+        OutputStream os = urlc.getOutputStream();
+        os.write(body.getBytes(StandardCharsets.ISO_8859_1));
+        os.close();
+        InputStream is = urlc.getInputStream();
+        byte[] vv = is.readAllBytes();
+        String ff = new String(vv, StandardCharsets.ISO_8859_1);
+        System.out.println("resp = " + ff);
+        if (!ff.equals(body))
+            throw new RuntimeException();
+        is.close();
+    }
+
+    static void testNew (String host, HttpTestServer server, Executor exec) throws Exception {
+        if (server == null)
+            return;
+        int port = server.getAddress().getPort();
+        String body = "Red and Yellow world";
+        URI uri = URIBuilder.newBuilder()
+                 .scheme("https")
+                 .host(host)
+                 .port(port)
+                 .path("/test1/foo.txt")
+                 .build();
+
+        HttpClient client = HttpClient.newBuilder()
+                .sslContext(ctx)
+                .executor(exec)
+                .build();
+        HttpRequest req = HttpRequest.newBuilder(uri)
+                .version(HttpClient.Version.HTTP_2)
+                .POST(HttpRequest.BodyPublishers.ofString(body))
+                .build();
+
+        HttpResponse<String> resp = client.send(req, HttpResponse.BodyHandlers.ofString());
+        System.out.println("resp = " + resp.body());
+        if (!resp.body().equals(body))
+            throw new RuntimeException();
+    }
+}
diff --git a/test/jdk/java/awt/Frame/Iconify/IconifiedToFront.java b/test/jdk/java/awt/Frame/Iconify/IconifiedToFront.java
new file mode 100644
index 0000000..03e418e
--- /dev/null
+++ b/test/jdk/java/awt/Frame/Iconify/IconifiedToFront.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2024, JetBrains s.r.o.. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @summary Verifies that an iconified window is restored with Window.toFront()
+ * @key headful
+ * @requires (os.name == "linux")
+ * @library /test/lib
+ * @run main IconifiedToFront
+ */
+import javax.swing.JFrame;
+import javax.swing.SwingUtilities;
+import java.awt.Robot;
+
+public class IconifiedToFront {
+    private static final int PAUSE_MS = 500;
+    private static Robot robot;
+
+    public static void main(String[] args) throws Exception {
+        robot = new Robot();
+        SwingUtilities.invokeAndWait(IconifiedToFront::test1);
+        SwingUtilities.invokeAndWait(IconifiedToFront::test2);
+        SwingUtilities.invokeAndWait(IconifiedToFront::test3);
+        SwingUtilities.invokeAndWait(IconifiedToFront::test4);
+    }
+
+    private static void test1() {
+        JFrame frame1 = new JFrame("IconifiedToFront Test 1");
+        try {
+            frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+            frame1.setSize(400, 300);
+            frame1.setVisible(true);
+            pause();
+            frame1.setExtendedState(JFrame.ICONIFIED);
+            pause();
+            frame1.toFront();
+            pause();
+            int state = frame1.getExtendedState();
+            if ((state & JFrame.ICONIFIED) != 0) {
+                throw new RuntimeException("Test Failed: state is still ICONIFIED: " + state);
+            }
+        } finally {
+            frame1.dispose();
+        }
+    }
+
+    private static void test2() {
+        JFrame frame1 = new JFrame("IconifiedToFront Test 2");
+        try {
+            frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+            frame1.setSize(400, 300);
+            frame1.setExtendedState(JFrame.MAXIMIZED_BOTH);
+            frame1.setVisible(true);
+            pause();
+            frame1.setExtendedState(JFrame.ICONIFIED | JFrame.MAXIMIZED_BOTH);
+            pause();
+            frame1.toFront();
+            pause();
+            int state = frame1.getExtendedState();
+            if ((state & JFrame.ICONIFIED) != 0) {
+                throw new RuntimeException("Test Failed: state is still ICONIFIED: " + state);
+            }
+        } finally {
+            frame1.dispose();
+        }
+    }
+
+    private static void test3() {
+        JFrame frame1 = new JFrame("IconifiedToFront Test 3");
+        try {
+            frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+            frame1.setSize(400, 300);
+            frame1.setUndecorated(true);
+            frame1.setVisible(true);
+            pause();
+            frame1.setExtendedState(JFrame.ICONIFIED);
+            pause();
+            frame1.toFront();
+            pause();
+            int state = frame1.getExtendedState();
+            if ((state & JFrame.ICONIFIED) != 0) {
+                throw new RuntimeException("Test Failed: state is still ICONIFIED: " + state);
+            }
+        } finally {
+            frame1.dispose();
+        }
+    }
+
+    private static void test4() {
+        JFrame frame1 = new JFrame("IconifiedToFront Test 4");
+        try {
+            frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+            frame1.setSize(400, 300);
+            frame1.setUndecorated(true);
+            frame1.setExtendedState(JFrame.MAXIMIZED_BOTH);
+            frame1.setVisible(true);
+            pause();
+            frame1.setExtendedState(JFrame.ICONIFIED | JFrame.MAXIMIZED_BOTH);
+            pause();
+            frame1.toFront();
+            pause();
+            int state = frame1.getExtendedState();
+            if ((state & JFrame.ICONIFIED) != 0) {
+                throw new RuntimeException("Test Failed: state is still ICONIFIED: " + state);
+            }
+        } finally {
+            frame1.dispose();
+        }
+    }
+
+    private static void pause() {
+        robot.delay(PAUSE_MS);
+    }
+}
diff --git a/test/jdk/java/awt/GraphicsDevice/CheckDisplayModes.java b/test/jdk/java/awt/GraphicsDevice/CheckDisplayModes.java
index 3d909e2..ffc98dc 100644
--- a/test/jdk/java/awt/GraphicsDevice/CheckDisplayModes.java
+++ b/test/jdk/java/awt/GraphicsDevice/CheckDisplayModes.java
@@ -41,28 +41,36 @@
                 continue;
             }
             DisplayMode defaultDisplayMode = graphicDevice.getDisplayMode();
+            System.out.println("Initial Display mode: " + defaultDisplayMode);
             checkDisplayMode(defaultDisplayMode);
             graphicDevice.setDisplayMode(defaultDisplayMode);
 
-            DisplayMode[] displayModes = graphicDevice.getDisplayModes();
-            boolean isDefaultDisplayModeIncluded = false;
-            for (DisplayMode displayMode : displayModes) {
-                checkDisplayMode(displayMode);
-                graphicDevice.setDisplayMode(displayMode);
-                if (defaultDisplayMode.equals(displayMode)) {
-                    isDefaultDisplayModeIncluded = true;
+            try {
+                DisplayMode[] displayModes = graphicDevice.getDisplayModes();
+                boolean isDefaultDisplayModeIncluded = false;
+                for (DisplayMode displayMode : displayModes) {
+                    checkDisplayMode(displayMode);
+                    graphicDevice.setDisplayMode(displayMode);
+                    System.out.println("\tDisplay mode changed to " + displayMode);
+                    if (defaultDisplayMode.equals(displayMode)) {
+                        isDefaultDisplayModeIncluded = true;
+                    }
                 }
-            }
 
-            if (!isDefaultDisplayModeIncluded) {
-                throw new RuntimeException("Default display mode is not included");
+                if (!isDefaultDisplayModeIncluded) {
+                    throw new RuntimeException("Default display mode is not included");
+                }
+            } finally {
+                System.out.println("Restoring display mode to " + defaultDisplayMode);
+                graphicDevice.setDisplayMode(defaultDisplayMode);
+                System.out.println("Display mode restored " + defaultDisplayMode);
             }
         }
     }
 
     static void checkDisplayMode(DisplayMode displayMode) {
         if (displayMode == null || displayMode.getWidth() <= 1 || displayMode.getHeight() <= 1) {
-            throw new RuntimeException("invalid display mode");
+            throw new RuntimeException("invalid display mode" + displayMode);
         }
     }
 }
diff --git a/test/jdk/java/awt/event/MouseEvent/MouseEnterExitTest.java b/test/jdk/java/awt/event/MouseEvent/MouseEnterExitTest.java
new file mode 100644
index 0000000..67c0272
--- /dev/null
+++ b/test/jdk/java/awt/event/MouseEvent/MouseEnterExitTest.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.Dimension;
+import java.awt.EventQueue;
+import java.awt.FlowLayout;
+import java.awt.Frame;
+import java.awt.List;
+import java.awt.Point;
+import java.awt.Robot;
+import java.awt.TextArea;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+
+/*
+ * @test
+ * @key headful
+ * @bug 4454304
+ * @summary On Solaris, TextArea triggers MouseEntered when the mouse is inside the component
+ * @run main MouseEnterExitTest
+ */
+public class MouseEnterExitTest {
+
+    private static Frame frame;
+
+    private volatile static boolean entered = false;
+    private volatile static boolean exited = false;
+    private volatile static boolean passed = true;
+
+    private volatile static Point compAt;
+    private volatile static Dimension compSize;
+
+    private static final MouseListener mouseListener = new MouseAdapter() {
+        @Override
+        public void mouseEntered(MouseEvent e) {
+            System.out.println(
+                "MouseEntered component " + e.getSource().getClass().getName());
+            if (entered) {
+                passed = false;
+            }
+            entered = true;
+            exited = false;
+        }
+
+        @Override
+        public void mouseExited(MouseEvent e) {
+            System.out.println(
+                "MouseExited component " + e.getSource().getClass().getName());
+            if (exited) {
+                passed = false;
+            }
+            entered = false;
+            exited = true;
+        }
+    };
+
+    private static void initializeGUI() {
+        frame = new Frame("MouseEnterExitTest");
+        frame.setLayout(new FlowLayout());
+        List list = new List(4);
+        for (int i = 0; i < 10; i++) {
+            list.add("item " + i);
+        }
+        list.addMouseListener(mouseListener);
+        frame.add(list);
+
+        TextArea textArea = new TextArea("TextArea", 10, 20);
+        textArea.addMouseListener(mouseListener);
+        frame.add(textArea);
+
+        frame.pack();
+        frame.setLocationRelativeTo(null);
+        frame.setVisible(true);
+    }
+
+    public static void main(String[] args) throws Exception {
+        try {
+            Robot robot = new Robot();
+            robot.setAutoDelay(100);
+            robot.setAutoWaitForIdle(true);
+
+            EventQueue.invokeAndWait(MouseEnterExitTest::initializeGUI);
+            robot.waitForIdle();
+
+            EventQueue.invokeAndWait(() -> {
+                compAt = frame.getLocationOnScreen();
+                compSize = frame.getSize();
+            });
+            compAt.y += compSize.getHeight() / 2;
+            int xr = compAt.x + compSize.width + 1;
+            for (int i = compAt.x - 5; (i < xr) && passed; i++) {
+                robot.mouseMove(i, compAt.y);
+            }
+
+            if (!passed || entered || !exited) {
+                throw new RuntimeException(
+                    "MouseEnterExitTest FAILED. MouseEntered/MouseExited "
+                        + "not properly triggered. Please see the log");
+            }
+            System.out.println("Test PASSED");
+        } finally {
+            EventQueue.invokeAndWait(MouseEnterExitTest::disposeFrame);
+        }
+    }
+
+    private static void disposeFrame() {
+        if (frame != null) {
+            frame.dispose();
+        }
+    }
+}
diff --git a/test/jdk/java/awt/event/MouseWheelEvent/WheelModifier/WheelModifier.java b/test/jdk/java/awt/event/MouseWheelEvent/WheelModifier/WheelModifier.java
index 8f16b03..0af2ba9 100644
--- a/test/jdk/java/awt/event/MouseWheelEvent/WheelModifier/WheelModifier.java
+++ b/test/jdk/java/awt/event/MouseWheelEvent/WheelModifier/WheelModifier.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -21,32 +21,55 @@
  * questions.
  */
 
-/*
-   @test
-   @key headful
-   @bug 8041470
-   @summary JButtons stay pressed after they have lost focus if you use the mouse wheel
-   @author Anton Nashatyrev
- */
-
-import javax.swing.*;
-import java.awt.*;
-import java.awt.event.*;
+import java.awt.AWTEvent;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.Point;
+import java.awt.Robot;
+import java.awt.Toolkit;
+import java.awt.event.AWTEventListener;
+import java.awt.event.FocusAdapter;
+import java.awt.event.FocusEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
 import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.SwingUtilities;
+
+/*
+ * @test
+ * @key headful
+ * @bug 8041470
+ * @summary JButtons stay pressed after they have lost focus if you use the mouse wheel
+ */
 public class WheelModifier {
 
     JFrame f;
     JButton fb;
 
-    CountDownLatch pressSema = new CountDownLatch(1);
-    CountDownLatch exitSema = new CountDownLatch(1);
-    CountDownLatch releaseSema = new CountDownLatch(1);
+    final CountDownLatch focusSema = new CountDownLatch(1);
+    final CountDownLatch pressSema = new CountDownLatch(1);
+    final CountDownLatch exitSema = new CountDownLatch(1);
+    final CountDownLatch releaseSema = new CountDownLatch(1);
     volatile CountDownLatch wheelSema;
 
+    private volatile Point sLoc;
+    private volatile Dimension bSize;
+
     void createGui() {
         f = new JFrame("frame");
         fb = new JButton("frame_button");
+
+        fb.addFocusListener(new FocusAdapter() {
+            @Override
+            public void focusGained(FocusEvent focusEvent) {
+                focusSema.countDown();
+            }
+        });
+
         fb.addMouseListener(new MouseAdapter() {
             @Override
             public void mouseReleased(MouseEvent e) {
@@ -57,7 +80,6 @@
             @Override
             public void mouseEntered(MouseEvent e) {
                 System.out.println("WheelModifier.mouseEntered: " + e);
-
             }
 
             @Override
@@ -94,41 +116,66 @@
     }
 
     void run() throws Exception {
+        System.out.println("# Started");
+        if (!focusSema.await(2, TimeUnit.SECONDS)) {
+            throw new RuntimeException("Didn't receive focus in time");
+        }
+
         Robot r = new Robot();
         r.waitForIdle();
-        System.out.println("# Started");
 
-        Point sLoc = fb.getLocationOnScreen();
-        Dimension bSize = fb.getSize();
+        SwingUtilities.invokeAndWait(() -> {
+            sLoc = fb.getLocationOnScreen();
+            bSize = fb.getSize();
+        });
+
         r.mouseMove(sLoc.x + bSize.width / 2, sLoc.y + bSize.height / 2);
-        r.mousePress(MouseEvent.BUTTON1_MASK);
-        pressSema.await();
+        r.mousePress(MouseEvent.BUTTON1_DOWN_MASK);
+        if (!pressSema.await(2, TimeUnit.SECONDS)) {
+            throw new RuntimeException("Mouse is not pressed");
+        }
         System.out.println("# Pressed");
 
         r.mouseMove(sLoc.x + bSize.width / 2, sLoc.y + bSize.height * 2);
-        exitSema.await();
+        if (!exitSema.await(1, TimeUnit.SECONDS)) {
+            throw new RuntimeException("Mouse did not exit");
+        }
         System.out.println("# Exited");
 
         wheelSema = new CountDownLatch(1);
         r.mouseWheel(1);
-        wheelSema.await();
+        if (!wheelSema.await(1, TimeUnit.SECONDS)) {
+            throw new RuntimeException("Mouse is not wheeled 1");
+        }
         System.out.println("# Wheeled 1");
 
         wheelSema = new CountDownLatch(1);
         r.mouseWheel(-1);
-        wheelSema.await();
+        if (!wheelSema.await(1, TimeUnit.SECONDS)) {
+            throw new RuntimeException("Mouse is not wheeled 2");
+        }
         System.out.println("# Wheeled 2");
 
-        r.mouseRelease(MouseEvent.BUTTON1_MASK);
-        releaseSema.await();
+        r.mouseRelease(MouseEvent.BUTTON1_DOWN_MASK);
+        if (!releaseSema.await(1, TimeUnit.SECONDS)) {
+            throw new RuntimeException("Mouse is not released");
+        }
         System.out.println("# Released!");
     }
 
     public static void main(String[] args) throws Exception {
         WheelModifier test = new WheelModifier();
 
-        SwingUtilities.invokeAndWait(() -> test.createGui());
-        test.run();
+        try {
+            SwingUtilities.invokeAndWait(test::createGui);
+            test.run();
+        } finally {
+            SwingUtilities.invokeAndWait(() -> {
+                if (test.f != null) {
+                    test.f.dispose();
+                }
+            });
+        }
 
         System.out.println("Done.");
     }
diff --git a/test/jdk/java/awt/regtesthelpers/PassFailJFrame.java b/test/jdk/java/awt/regtesthelpers/PassFailJFrame.java
index a13d6ee..4d8f3c6 100644
--- a/test/jdk/java/awt/regtesthelpers/PassFailJFrame.java
+++ b/test/jdk/java/awt/regtesthelpers/PassFailJFrame.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -21,30 +21,47 @@
  * questions.
  */
 
+import java.awt.AWTException;
 import java.awt.BorderLayout;
 import java.awt.Dimension;
 import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsDevice;
 import java.awt.GraphicsEnvironment;
+import java.awt.Image;
 import java.awt.Insets;
 import java.awt.Rectangle;
+import java.awt.Robot;
 import java.awt.Toolkit;
 import java.awt.Window;
 import java.awt.event.WindowAdapter;
 import java.awt.event.WindowEvent;
+import java.awt.image.RenderedImage;
+import java.io.File;
+import java.io.IOException;
 import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javax.imageio.ImageIO;
 import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JComponent;
 import javax.swing.JDialog;
+import javax.swing.JEditorPane;
 import javax.swing.JFrame;
 import javax.swing.JLabel;
+import javax.swing.JOptionPane;
 import javax.swing.JPanel;
 import javax.swing.JScrollPane;
 import javax.swing.JTextArea;
 import javax.swing.Timer;
-
+import javax.swing.text.JTextComponent;
+import javax.swing.text.html.HTMLEditorKit;
+import javax.swing.text.html.StyleSheet;
 
 import static javax.swing.SwingUtilities.invokeAndWait;
 import static javax.swing.SwingUtilities.isEventDispatchThread;
@@ -68,8 +85,13 @@
     private static volatile boolean failed;
     private static volatile boolean timeout;
     private static volatile String testFailedReason;
+
+    private static final AtomicInteger imgCounter = new AtomicInteger(0);
+
     private static JFrame frame;
 
+    private static Robot robot;
+
     public enum Position {HORIZONTAL, VERTICAL, TOP_LEFT_CORNER}
 
     public PassFailJFrame(String instructions) throws InterruptedException,
@@ -114,21 +136,69 @@
     public PassFailJFrame(String title, String instructions, long testTimeOut,
                           int rows, int columns) throws InterruptedException,
             InvocationTargetException {
+        this(title, instructions, testTimeOut, rows, columns, false);
+    }
+
+    /**
+     * Constructs a JFrame with a given title & serves as test instructional
+     * frame where the user follows the specified test instruction in order
+     * to test the test case & mark the test pass or fail. If the expected
+     * result is seen then the user click on the 'Pass' button else click
+     * on the 'Fail' button and the reason for the failure should be
+     * specified in the JDialog JTextArea.
+     * <p>
+     * The test instruction frame also provides a way for the tester to take
+     * a screenshot (full screen or individual frame) if this feature
+     * is enabled by passing {@code true} as {@code  enableScreenCapture}
+     * parameter.
+     *
+     * @param title        title of the Frame.
+     * @param instructions the instruction for the tester on how to test
+     *                     and what is expected (pass) and what is not
+     *                     expected (fail).
+     * @param testTimeOut  test timeout where time is specified in minutes.
+     * @param rows         number of visible rows of the JTextArea where the
+     *                     instruction is show.
+     * @param columns      Number of columns of the instructional
+     *                     JTextArea
+     * @param enableScreenCapture if set to true, 'Capture Screen' button & its
+     *                            associated UIs are added to test instruction
+     *                            frame
+     * @throws InterruptedException      exception thrown when thread is
+     *                                   interrupted
+     * @throws InvocationTargetException if an exception is thrown while
+     *                                   creating the test instruction frame on
+     *                                   EDT
+     */
+    public PassFailJFrame(String title, String instructions, long testTimeOut,
+                          int rows, int columns,
+                          boolean enableScreenCapture) throws InterruptedException,
+            InvocationTargetException {
         if (isEventDispatchThread()) {
-            createUI(title, instructions, testTimeOut, rows, columns);
+            createUI(title, instructions, testTimeOut, rows, columns,
+                     enableScreenCapture);
         } else {
             invokeAndWait(() -> createUI(title, instructions, testTimeOut,
-                    rows, columns));
+                    rows, columns, enableScreenCapture));
         }
     }
 
+    private PassFailJFrame(Builder builder) throws InterruptedException,
+            InvocationTargetException {
+        this(builder.title, builder.instructions, builder.testTimeOut,
+                builder.rows, builder.columns, builder.screenCapture);
+    }
+
     private static void createUI(String title, String instructions,
-                                 long testTimeOut, int rows, int columns) {
+                                 long testTimeOut, int rows, int columns,
+                                 boolean enableScreenCapture) {
         frame = new JFrame(title);
         frame.setLayout(new BorderLayout());
-        JTextArea instructionsText = new JTextArea(instructions, rows, columns);
-        instructionsText.setEditable(false);
-        instructionsText.setLineWrap(true);
+
+        JTextComponent text = instructions.startsWith("<html>")
+                              ? configureHTML(instructions, rows, columns)
+                              : configurePlainText(instructions, rows, columns);
+        text.setEditable(false);
 
         long tTimeout = TimeUnit.MINUTES.toMillis(testTimeOut);
 
@@ -149,7 +219,7 @@
         });
         timer.start();
         frame.add(testTimeoutLabel, BorderLayout.NORTH);
-        frame.add(new JScrollPane(instructionsText), BorderLayout.CENTER);
+        frame.add(new JScrollPane(text), BorderLayout.CENTER);
 
         JButton btnPass = new JButton("Pass");
         btnPass.addActionListener((e) -> {
@@ -167,6 +237,10 @@
         buttonsPanel.add(btnPass);
         buttonsPanel.add(btnFail);
 
+        if (enableScreenCapture) {
+            buttonsPanel.add(createCapturePanel());
+        }
+
         frame.addWindowListener(new WindowAdapter() {
             @Override
             public void windowClosing(WindowEvent e) {
@@ -184,6 +258,117 @@
         windowList.add(frame);
     }
 
+    private static JTextComponent configurePlainText(String instructions,
+                                                     int rows, int columns) {
+        JTextArea text = new JTextArea(instructions, rows, columns);
+        text.setLineWrap(true);
+        text.setWrapStyleWord(true);
+        return text;
+    }
+
+    private static JTextComponent configureHTML(String instructions,
+                                                int rows, int columns) {
+        JEditorPane text = new JEditorPane("text/html", instructions);
+        text.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES,
+                               Boolean.TRUE);
+        // Set preferred size as if it were JTextArea
+        text.setPreferredSize(new JTextArea(rows, columns).getPreferredSize());
+
+        HTMLEditorKit kit = (HTMLEditorKit) text.getEditorKit();
+        StyleSheet styles = kit.getStyleSheet();
+        // Reduce the default margins
+        styles.addRule("ol, ul { margin-left-ltr: 20; margin-left-rtl: 20 }");
+        // Make the size of code blocks the same as other text
+        styles.addRule("code { font-size: inherit }");
+
+        return text;
+    }
+
+    private static JComponent createCapturePanel() {
+        JComboBox<CaptureType> screenShortType = new JComboBox<>(CaptureType.values());
+
+        JButton capture = new JButton("ScreenShot");
+        capture.addActionListener((e) ->
+                captureScreen((CaptureType) screenShortType.getSelectedItem()));
+
+        JPanel panel = new JPanel();
+        panel.add(screenShortType);
+        panel.add(capture);
+        return panel;
+    }
+
+    private enum CaptureType {
+        FULL_SCREEN("Capture Full Screen"),
+        WINDOWS("Capture Individual Frame");
+
+        private final String type;
+        CaptureType(String type) {
+            this.type = type;
+        }
+
+        @Override
+        public String toString() {
+            return type;
+        }
+    }
+
+    private static Robot createRobot() {
+        if (robot == null) {
+            try {
+                robot = new Robot();
+            } catch (AWTException e) {
+                String errorMsg = "Failed to create an instance of Robot.";
+                JOptionPane.showMessageDialog(frame, errorMsg, "Failed",
+                                              JOptionPane.ERROR_MESSAGE);
+                forceFail(errorMsg + e.getMessage());
+            }
+        }
+        return robot;
+    }
+
+    private static void captureScreen(Rectangle bounds) {
+        Robot robot = createRobot();
+
+        List<Image> imageList = robot.createMultiResolutionScreenCapture(bounds)
+                                     .getResolutionVariants();
+        Image image = imageList.get(imageList.size() - 1);
+
+        File file = new File("CaptureScreen_"
+                             + imgCounter.incrementAndGet() + ".png");
+        try {
+            ImageIO.write((RenderedImage) image, "png", file);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private static void captureScreen(CaptureType type) {
+        switch (type) {
+            case FULL_SCREEN:
+                Arrays.stream(GraphicsEnvironment.getLocalGraphicsEnvironment()
+                                                 .getScreenDevices())
+                      .map(GraphicsDevice::getDefaultConfiguration)
+                      .map(GraphicsConfiguration::getBounds)
+                      .forEach(PassFailJFrame::captureScreen);
+                break;
+
+            case WINDOWS:
+                windowList.stream()
+                          .filter(Window::isShowing)
+                          .map(Window::getBounds)
+                          .forEach(PassFailJFrame::captureScreen);
+                break;
+
+            default:
+                throw new IllegalStateException("Unexpected value of capture type");
+        }
+
+        JOptionPane.showMessageDialog(frame,
+                                      "Screen Captured Successfully",
+                                      "Screen Capture",
+                                      JOptionPane.INFORMATION_MESSAGE);
+    }
+
     private static String convertMillisToTimeStr(long millis) {
         if (millis < 0) {
             return "00:00:00";
@@ -421,4 +606,72 @@
         testFailedReason = FAILURE_REASON + reason;
         latch.countDown();
     }
+
+    public static class Builder {
+        private String title;
+        private String instructions;
+        private long testTimeOut;
+        private int rows;
+        private int columns;
+        private boolean screenCapture = false;
+
+        public Builder title(String title) {
+            this.title = title;
+            return this;
+        }
+
+        public Builder instructions(String instructions) {
+            this.instructions = instructions;
+            return this;
+        }
+
+        public Builder testTimeOut(long testTimeOut) {
+            this.testTimeOut = testTimeOut;
+            return this;
+        }
+
+        public Builder rows(int rows) {
+            this.rows = rows;
+            return this;
+        }
+
+        public Builder columns(int columns) {
+            this.columns = columns;
+            return this;
+        }
+
+        public Builder screenCapture() {
+            this.screenCapture = true;
+            return this;
+        }
+
+        public PassFailJFrame build() throws InterruptedException,
+                InvocationTargetException {
+            validate();
+            return new PassFailJFrame(this);
+        }
+
+        private void validate() {
+            if (this.title == null) {
+                this.title = TITLE;
+            }
+
+            if (this.instructions == null || this.instructions.length() == 0) {
+                throw new RuntimeException("Please provide the test " +
+                        "instruction for this manual test");
+            }
+
+            if (this.testTimeOut == 0L) {
+                this.testTimeOut = TEST_TIMEOUT;
+            }
+
+            if (this.rows == 0) {
+                this.rows = ROWS;
+            }
+
+            if (this.columns == 0) {
+                this.columns = COLUMNS;
+            }
+        }
+    }
 }
diff --git a/test/jdk/java/io/File/createTempFile/SpecialTempFile.java b/test/jdk/java/io/File/createTempFile/SpecialTempFile.java
index a2fa855..736e721 100644
--- a/test/jdk/java/io/File/createTempFile/SpecialTempFile.java
+++ b/test/jdk/java/io/File/createTempFile/SpecialTempFile.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,7 +24,11 @@
 /*
  * @test
  * @bug 8013827 8011950 8017212 8025128
+ * @library /test/lib
+ * @modules java.base/jdk.internal.util
  * @summary Check whether File.createTempFile can handle special parameters
+ * @build jdk.test.lib.OSVersion jdk.test.lib.Platform
+   @run main SpecialTempFile
  * @author Dan Xu
  */
 
@@ -32,10 +36,11 @@
 import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Path;
-import java.nio.file.Paths;
+
+import jdk.test.lib.Platform;
+import jdk.test.lib.OSVersion;
 
 public class SpecialTempFile {
-
     private static void test(String name, String[] prefix, String[] suffix,
                              boolean exceptionExpected) throws IOException
     {
@@ -48,7 +53,7 @@
         final String exceptionMsg = "Unable to create temporary file";
         String[] dirs = { null, "." };
 
-        Path testPath = Paths.get(System.getProperty("test.dir", "."));
+        Path testPath = Path.of(System.getProperty("test.dir", "."));
         for (int i = 0; i < prefix.length; i++) {
             boolean exceptionThrown = false;
             File f = null;
@@ -99,12 +104,15 @@
         test("SlashedName", slashPre, slashSuf, true);
 
         // Windows tests
-        if (!System.getProperty("os.name").startsWith("Windows"))
+        if (!Platform.isWindows())
             return;
 
         // Test JDK-8013827
         String[] resvPre = { "LPT1.package.zip", "com7.4.package.zip" };
         String[] resvSuf = { ".temp", ".temp" };
-        test("ReservedName", resvPre, resvSuf, true);
+        boolean exceptionExpected =
+            !(System.getProperty("os.name").endsWith("11") ||
+              new OSVersion(10, 0).compareTo(OSVersion.current()) > 0);
+        test("ReservedName", resvPre, resvSuf, exceptionExpected);
     }
 }
diff --git a/test/jdk/java/lang/ProcessBuilder/JspawnhelperProtocol.java b/test/jdk/java/lang/ProcessBuilder/JspawnhelperProtocol.java
new file mode 100644
index 0000000..d82a317
--- /dev/null
+++ b/test/jdk/java/lang/ProcessBuilder/JspawnhelperProtocol.java
@@ -0,0 +1,237 @@
+/*
+ * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ * @test
+ * @bug 8307990
+ * @requires (os.family == "linux") | (os.family == "aix")
+ * @requires vm.debug
+ * @library /test/lib
+ * @run main/othervm/timeout=300 JspawnhelperProtocol
+ */
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.Optional;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import jdk.test.lib.process.ProcessTools;
+
+public class JspawnhelperProtocol {
+    // Timout in seconds
+    private static final int TIMEOUT = 60;
+    // Base error code to communicate various error states from the parent process to the top-level test
+    private static final int ERROR = 10;
+    private static final String[] CMD = { "pwd" };
+    private static final String ENV_KEY = "JTREG_JSPAWNHELPER_PROTOCOL_TEST";
+
+    private static void parentCode(String arg) throws IOException, InterruptedException {
+        System.out.println("Recursively executing 'JspawnhelperProtocol " + arg + "'");
+        Process p = null;
+        try {
+            p = Runtime.getRuntime().exec(CMD);
+        } catch (Exception e) {
+            e.printStackTrace(System.out);
+            System.exit(ERROR);
+        }
+        if (!p.waitFor(TIMEOUT, TimeUnit.SECONDS)) {
+            System.out.println("Child process timed out");
+            System.exit(ERROR + 1);
+        }
+        if (p.exitValue() == 0) {
+            String pwd = p.inputReader().readLine();
+            String realPwd = Path.of("").toAbsolutePath().toString();
+            if (!realPwd.equals(pwd)) {
+                System.out.println("Child process returned '" + pwd + "' (expected '" + realPwd + "')");
+                System.exit(ERROR + 2);
+            }
+            System.out.println("  Successfully executed '" + CMD[0] + "'");
+            System.exit(0);
+        } else {
+            System.out.println("  Failed to executed '" + CMD[0] + "' (exitValue=" + p.exitValue() + ")");
+            System.exit(ERROR + 3);
+        }
+    }
+
+    private static void normalExec() throws Exception {
+        ProcessBuilder pb;
+        pb = ProcessTools.createJavaProcessBuilder("-Djdk.lang.Process.launchMechanism=posix_spawn",
+                                                   "JspawnhelperProtocol",
+                                                   "normalExec");
+        pb.inheritIO();
+        Process p = pb.start();
+        if (!p.waitFor(TIMEOUT, TimeUnit.SECONDS)) {
+            throw new Exception("Parent process timed out");
+        }
+        if (p.exitValue() != 0) {
+            throw new Exception("Parent process exited with " + p.exitValue());
+        }
+    }
+
+    private static void simulateCrashInChild(int stage) throws Exception {
+        ProcessBuilder pb;
+        pb = ProcessTools.createJavaProcessBuilder("-Djdk.lang.Process.launchMechanism=posix_spawn",
+                                                   "JspawnhelperProtocol",
+                                                   "simulateCrashInChild" + stage);
+        pb.environment().put(ENV_KEY, Integer.toString(stage));
+        Process p = pb.start();
+
+        boolean foundCrashInfo = false;
+        try (BufferedReader br = p.inputReader()) {
+            String line = br.readLine();
+            while (line != null) {
+                System.out.println(line);
+                if (line.equals("posix_spawn:0")) {
+                    foundCrashInfo = true;
+                }
+                line = br.readLine();
+            }
+        }
+        if (!foundCrashInfo) {
+            throw new Exception("Wrong output from child process");
+        }
+        if (!p.waitFor(TIMEOUT, TimeUnit.SECONDS)) {
+            throw new Exception("Parent process timed out");
+        }
+
+        int ret = p.exitValue();
+        if (ret == 0) {
+            throw new Exception("Expected error during child execution");
+        }
+        System.out.println("Parent exit code: " + ret);
+    }
+
+    private static void simulateCrashInParent(int stage) throws Exception {
+        ProcessBuilder pb;
+        pb = ProcessTools.createJavaProcessBuilder("-Djdk.lang.Process.launchMechanism=posix_spawn",
+                                                   "JspawnhelperProtocol",
+                                                   "simulateCrashInParent" + stage);
+        pb.environment().put(ENV_KEY, Integer.toString(stage));
+        Process p = pb.start();
+
+        String line = null;
+        try (BufferedReader br = p.inputReader()) {
+            line = br.readLine();
+            while (line != null && !line.startsWith("posix_spawn:")) {
+                System.out.println(line);
+                line = br.readLine();
+            }
+        }
+        if (line == null) {
+            throw new Exception("Wrong output from parent process");
+        }
+        System.out.println(line);
+        long childPid = Integer.parseInt(line.substring(line.indexOf(':') + 1));
+
+        if (!p.waitFor(TIMEOUT, TimeUnit.SECONDS)) {
+            throw new Exception("Parent process timed out");
+        }
+
+        Optional<ProcessHandle> oph = ProcessHandle.of(childPid);
+        if (!oph.isEmpty()) {
+            ProcessHandle ph = oph.get();
+            try {
+                // Give jspawnhelper a chance to exit gracefully
+                ph.onExit().get(TIMEOUT, TimeUnit.SECONDS);
+            } catch (TimeoutException te) {
+                Optional<String> cmd = ph.info().command();
+                if (cmd.isPresent() && cmd.get().endsWith("jspawnhelper")) {
+                    throw new Exception("jspawnhelper still alive after parent Java process terminated");
+                }
+            }
+        }
+        int ret = p.exitValue();
+        if (ret != stage) {
+            throw new Exception("Expected exit code " + stage + " but got " + ret);
+        }
+        System.out.println("Parent exit code: " + ret);
+    }
+
+    private static void simulateTruncatedWriteInParent(int stage) throws Exception {
+        ProcessBuilder pb;
+        pb = ProcessTools.createJavaProcessBuilder("-Djdk.lang.Process.launchMechanism=posix_spawn",
+                                                   "JspawnhelperProtocol",
+                                                   "simulateTruncatedWriteInParent" + stage);
+        pb.environment().put(ENV_KEY, Integer.toString(stage));
+        Process p = pb.start();
+
+        BufferedReader br = p.inputReader();
+        String line = br.readLine();
+        while (line != null && !line.startsWith("posix_spawn:")) {
+            System.out.println(line);
+            line = br.readLine();
+        }
+        if (line == null) {
+            throw new Exception("Wrong output from parent process");
+        }
+        System.out.println(line);
+
+        if (!p.waitFor(TIMEOUT, TimeUnit.SECONDS)) {
+            throw new Exception("Parent process timed out");
+        }
+        line = br.readLine();
+        while (line != null) {
+            System.out.println(line);
+            line = br.readLine();
+        }
+
+        int ret = p.exitValue();
+        if (ret != ERROR) {
+            throw new Exception("Expected exit code " + ERROR + " but got " + ret);
+        }
+        System.out.println("Parent exit code: " + ret);
+    }
+
+    public static void main(String[] args) throws Exception {
+        // This test works as follows:
+        //  - jtreg executes the test class `JspawnhelperProtocol` without arguments.
+        //    This is the initial "grandparent" process.
+        //  - For each sub-test (i.e. `normalExec()`, `simulateCrashInParent()` and
+        //    `simulateCrashInChild()`), a new sub-process (called the "parent") will be
+        //    forked which executes `JspawnhelperProtocol` recursively with a corresponding
+        //    command line argument.
+        //  - The forked `JspawnhelperProtocol` process (i.e. the "parent") runs
+        //    `JspawnhelperProtocol::parentCode()` which forks off yet another sub-process
+        //    (called the "child").
+        //  - The sub-tests in the "grandparent" check that various abnormal program
+        //    terminations in the "parent" or the "child" process are handled gracefully and
+        //    don't lead to deadlocks or zombie processes.
+        if (args.length > 0) {
+            // Entry point for recursive execution in the "parent" process
+            parentCode(args[0]);
+        } else {
+            // Main test entry for execution from jtreg
+            normalExec();
+            simulateCrashInParent(1);
+            simulateCrashInParent(2);
+            simulateCrashInParent(3);
+            simulateCrashInChild(4);
+            simulateCrashInChild(5);
+            simulateCrashInChild(6);
+            simulateTruncatedWriteInParent(99);
+        }
+    }
+}
diff --git a/test/jdk/java/lang/instrument/BootClassPath/BootClassPathTest.sh b/test/jdk/java/lang/instrument/BootClassPath/BootClassPathTest.sh
index 9776b03..9ab2604 100644
--- a/test/jdk/java/lang/instrument/BootClassPath/BootClassPathTest.sh
+++ b/test/jdk/java/lang/instrument/BootClassPath/BootClassPathTest.sh
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -64,7 +64,18 @@
 # java Setup <workdir> <premain-class>
 # - outputs boot class path to boot.dir
 
-"$JAVA" ${TESTVMOPTS} -classpath "${TESTCLASSES}" Setup "${TESTCLASSES}" Agent
+OS=`uname -s`
+case ${OS} in
+    CYGWIN*)
+        CYGWIN="CYGWIN"
+        ;;
+    *)
+        CYGWIN=""
+        ;;
+esac
+
+"$JAVA" ${TESTVMOPTS} -classpath "${TESTCLASSES}" Setup "${TESTCLASSES}" Agent "${CYGWIN}"
+
 BOOTDIR=`cat ${TESTCLASSES}/boot.dir`
 
 echo "Created ${BOOTDIR}"
diff --git a/test/jdk/java/lang/instrument/BootClassPath/Setup.java b/test/jdk/java/lang/instrument/BootClassPath/Setup.java
index 40529fd..3d3332a 100644
--- a/test/jdk/java/lang/instrument/BootClassPath/Setup.java
+++ b/test/jdk/java/lang/instrument/BootClassPath/Setup.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -45,6 +45,10 @@
         }
         String workDir = args[0];
         String premainClass = args[1];
+        boolean isCygwin = false;
+        if (args.length==3 && args[2].equals("CYGWIN")) {
+            isCygwin = true;
+        }
 
         String manifestFile = workDir + fileSeparator + "MANIFEST.MF";
         String bootClassPath = "boot" + suffix();
@@ -94,7 +98,12 @@
          */
         f = new File(workDir + fileSeparator + "boot.dir");
         try (FileOutputStream out = new FileOutputStream(f)) {
-            out.write(bootDir.getBytes(defaultEncoding));
+            if (osName.startsWith("Windows") && isCygwin) {
+                out.write(bootDir.getBytes("UTF-8"));
+            }
+            else {
+                out.write(bootDir.getBytes(defaultEncoding));
+            }
         }
     }
 
diff --git a/test/jdk/java/lang/module/ModuleDescriptorHashCodeTest.java b/test/jdk/java/lang/module/ModuleDescriptorHashCodeTest.java
index 78b124d..c1269f2 100644
--- a/test/jdk/java/lang/module/ModuleDescriptorHashCodeTest.java
+++ b/test/jdk/java/lang/module/ModuleDescriptorHashCodeTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -21,22 +21,24 @@
  * questions.
  */
 
-import org.testng.annotations.Test;
-
 import java.io.IOException;
 import java.io.InputStream;
 import java.lang.module.ModuleDescriptor;
+import java.lang.module.ModuleDescriptor.Exports;
+import java.lang.module.ModuleDescriptor.Opens;
+import java.lang.module.ModuleDescriptor.Requires;
 import java.util.Set;
 
+import org.testng.annotations.Test;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotSame;
 
 /**
  * @test
- * @bug 8275509
+ * @bug 8275509 8290041
+ * @summary Tests the ModuleDescriptor.hashCode()
  * @run testng ModuleDescriptorHashCodeTest
  * @run testng/othervm -Xshare:off ModuleDescriptorHashCodeTest
- * @summary Tests the ModuleDescriptor.hashCode() for boot layer modules
  */
 public class ModuleDescriptorHashCodeTest {
 
@@ -63,6 +65,99 @@
         }
     }
 
+    /**
+     * Verifies that two "equal" module descriptors which only differ in the order of
+     * {@link ModuleDescriptor.Opens.Modifier opens modifiers}, that were used to construct the
+     * descriptors, have the same hashcode.
+     */
+    @Test
+    public void testOpensModifiersOrdering() throws Exception {
+        // important to use Set.of() (i.e. backed by immutable set) to reproduce the issue
+        final Set<Opens.Modifier> mods1 = Set.of(Opens.Modifier.SYNTHETIC, Opens.Modifier.MANDATED);
+        final ModuleDescriptor desc1 = createModuleDescriptor(mods1, null, null);
+
+        // create the same module descriptor again and this time just change the order of the
+        // "opens" modifiers' Set.
+
+        // important to use Set.of() (i.e. backed by immutable set) to reproduce the issue
+        final Set<Opens.Modifier> mods2 = Set.of(Opens.Modifier.MANDATED, Opens.Modifier.SYNTHETIC);
+        final ModuleDescriptor desc2 = createModuleDescriptor(mods2, null, null);
+
+        // basic verification of the modifiers themselves before we check the module descriptors
+        assertEquals(mods1, mods2, "Modifiers were expected to be equal");
+
+        // now verify the module descriptors
+        assertEquals(desc1, desc2, "Module descriptors were expected to be equal");
+        assertEquals(desc1.compareTo(desc2), 0, "compareTo was expected to return" +
+                " 0 for module descriptors that are equal");
+        System.out.println(desc1 + " hashcode = " + desc1.hashCode());
+        System.out.println(desc2 + " hashcode = " + desc2.hashCode());
+        assertEquals(desc1.hashCode(), desc2.hashCode(), "Module descriptor hashcodes" +
+                " were expected to be equal");
+    }
+
+    /**
+     * Verifies that two "equal" module descriptors which only differ in the order of
+     * {@link ModuleDescriptor.Exports.Modifier exports modifiers}, that were used to construct the
+     * descriptors, have the same hashcode.
+     */
+    @Test
+    public void testExportsModifiersOrdering() throws Exception {
+        // important to use Set.of() (i.e. backed by immutable set) to reproduce the issue
+        final Set<Exports.Modifier> mods1 = Set.of(Exports.Modifier.SYNTHETIC, Exports.Modifier.MANDATED);
+        final ModuleDescriptor desc1 = createModuleDescriptor(null, null, mods1);
+
+        // create the same module descriptor again and this time just change the order of the
+        // "exports" modifiers' Set.
+
+        // important to use Set.of() (i.e. backed by immutable set) to reproduce the issue
+        final Set<Exports.Modifier> mods2 = Set.of(Exports.Modifier.MANDATED, Exports.Modifier.SYNTHETIC);
+        final ModuleDescriptor desc2 = createModuleDescriptor(null, null, mods2);
+
+        // basic verification of the modifiers themselves before we check the module descriptors
+        assertEquals(mods1, mods2, "Modifiers were expected to be equal");
+
+        // now verify the module descriptors
+        assertEquals(desc1, desc2, "Module descriptors were expected to be equal");
+        assertEquals(desc1.compareTo(desc2), 0, "compareTo was expected to return" +
+                " 0 for module descriptors that are equal");
+        System.out.println(desc1 + " hashcode = " + desc1.hashCode());
+        System.out.println(desc2 + " hashcode = " + desc2.hashCode());
+        assertEquals(desc1.hashCode(), desc2.hashCode(), "Module descriptor hashcodes" +
+                " were expected to be equal");
+    }
+
+    /**
+     * Verifies that two "equal" module descriptors which only differ in the order of
+     * {@link ModuleDescriptor.Requires.Modifier requires modifiers}, that were used to construct the
+     * descriptors, have the same hashcode.
+     */
+    @Test
+    public void testRequiresModifiersOrdering() throws Exception {
+        // important to use Set.of() (i.e. backed by immutable set) to reproduce the issue
+        final Set<Requires.Modifier> mods1 = Set.of(Requires.Modifier.SYNTHETIC, Requires.Modifier.MANDATED);
+        final ModuleDescriptor desc1 = createModuleDescriptor(null, mods1, null);
+
+        // create the same module descriptor again and this time just change the order of the
+        // "exports" modifiers' Set.
+
+        // important to use Set.of() (i.e. backed by immutable set) to reproduce the issue
+        final Set<Requires.Modifier> mods2 = Set.of(Requires.Modifier.MANDATED, Requires.Modifier.SYNTHETIC);
+        final ModuleDescriptor desc2 = createModuleDescriptor(null, mods2, null);
+
+        // basic verification of the modifiers themselves before we check the module descriptors
+        assertEquals(mods1, mods2, "Modifiers were expected to be equal");
+
+        // now verify the module descriptors
+        assertEquals(desc1, desc2, "Module descriptors were expected to be equal");
+        assertEquals(desc1.compareTo(desc2), 0, "compareTo was expected to return" +
+                " 0 for module descriptors that are equal");
+        System.out.println(desc1 + " hashcode = " + desc1.hashCode());
+        System.out.println(desc2 + " hashcode = " + desc2.hashCode());
+        assertEquals(desc1.hashCode(), desc2.hashCode(), "Module descriptor hashcodes" +
+                " were expected to be equal");
+    }
+
     // Returns a ModuleDescriptor parsed out of the module-info.class of the passed Module
     private static ModuleDescriptor fromModuleInfoClass(Module module) throws IOException {
         try (InputStream moduleInfo = module.getResourceAsStream("module-info.class")) {
@@ -73,4 +168,23 @@
             return ModuleDescriptor.read(moduleInfo);
         }
     }
+
+    // creates a module descriptor with passed (optional) opens/exports/requires modifiers
+    private static ModuleDescriptor createModuleDescriptor(
+            Set<Opens.Modifier> opensModifiers,
+            Set<Requires.Modifier> reqsModifiers,
+            Set<Exports.Modifier> expsModifiers) {
+
+        final ModuleDescriptor.Builder builder = ModuleDescriptor.newModule("foobar");
+        if (opensModifiers != null) {
+            builder.opens(opensModifiers, "a.p1", Set.of("a.m1"));
+        }
+        if (reqsModifiers != null) {
+            builder.requires(reqsModifiers, "a.m2");
+        }
+        if (expsModifiers != null) {
+            builder.exports(expsModifiers, "a.b.c", Set.of("a.m3"));
+        }
+        return builder.build();
+    }
 }
diff --git a/test/jdk/java/lang/ref/ReachabilityFenceTest.java b/test/jdk/java/lang/ref/ReachabilityFenceTest.java
index 4ddc9e0..9dde3f6 100644
--- a/test/jdk/java/lang/ref/ReachabilityFenceTest.java
+++ b/test/jdk/java/lang/ref/ReachabilityFenceTest.java
@@ -27,11 +27,11 @@
  *
  * @requires vm.opt.DeoptimizeALot != true
  *
- * @run main/othervm -Xint                   -Dpremature=false ReachabilityFenceTest
- * @run main/othervm -XX:TieredStopAtLevel=1 -Dpremature=true  ReachabilityFenceTest
- * @run main/othervm -XX:TieredStopAtLevel=2 -Dpremature=true  ReachabilityFenceTest
- * @run main/othervm -XX:TieredStopAtLevel=3 -Dpremature=true  ReachabilityFenceTest
- * @run main/othervm -XX:TieredStopAtLevel=4 -Dpremature=true  ReachabilityFenceTest
+ * @run main/othervm -Xint                           -Dpremature=false ReachabilityFenceTest
+ * @run main/othervm -Xbatch -XX:TieredStopAtLevel=1 -Dpremature=true  ReachabilityFenceTest
+ * @run main/othervm -Xbatch -XX:TieredStopAtLevel=2 -Dpremature=true  ReachabilityFenceTest
+ * @run main/othervm -Xbatch -XX:TieredStopAtLevel=3 -Dpremature=true  ReachabilityFenceTest
+ * @run main/othervm -Xbatch -XX:TieredStopAtLevel=4 -Dpremature=true  ReachabilityFenceTest
  */
 
 import java.lang.ref.Reference;
@@ -54,7 +54,7 @@
      * the object cannot be finalized. There is no sense running a positive test when premature finalization
      * is not expected. It is a job for negative test to verify that invariant.
      *
-     * The test methods should be appropriately compiled, therefore we do several iterations.
+     * The test methods should be appropriately compiled, therefore we do several iterations and run with -Xbatch.
      */
 
     // Enough to OSR and compile
diff --git a/test/jdk/java/lang/reflect/Proxy/ClassRestrictions.java b/test/jdk/java/lang/reflect/Proxy/ClassRestrictions.java
index ba5b407..6f6dcb4 100644
--- a/test/jdk/java/lang/reflect/Proxy/ClassRestrictions.java
+++ b/test/jdk/java/lang/reflect/Proxy/ClassRestrictions.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,13 +22,13 @@
  */
 
 /* @test
- * @bug 4227192 8004928 8072656
+ * @bug 4227192 8004928 8072656 8319436
  * @summary This is a test of the restrictions on the parameters that may
  * be passed to the Proxy.getProxyClass method.
  * @author Peter Jones
  *
  * @build ClassRestrictions
- * @run main ClassRestrictions
+ * @run junit ClassRestrictions
  */
 
 import java.io.File;
@@ -37,6 +37,13 @@
 import java.net.URLClassLoader;
 import java.net.URL;
 import java.nio.file.Paths;
+import java.util.List;
+import java.util.stream.Stream;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+import static org.junit.jupiter.api.Assertions.*;
 
 public class ClassRestrictions {
 
@@ -52,129 +59,65 @@
         void foo();
     }
 
-    public static final String nonPublicIntrfaceName = "java.util.zip.ZipConstants";
+    private static final String TEST_CLASSES = System.getProperty("test.classes", ".");
+    private static final ClassLoader LOADER = ClassRestrictions.class.getClassLoader();
 
-    public static void main(String[] args) {
+    static Stream<List<Class<?>>> badProxyInterfaces() {
+        return Stream.of(
+                List.of(Object.class),          // proxy interface cannot be a class
+                List.of(int.class),             // proxy interface can't be primitive type
+                List.of(Bar.class, Bar.class),  // cannot have repeated interfaces
+                // two proxy interfaces have the method of same method name but different return type
+                List.of(Bar.class, Baz.class)
+        );
+    }
 
-        System.err.println(
-            "\nTest of restrictions on parameters to Proxy.getProxyClass\n");
+    /*
+     * Test cases for illegal proxy interfaces
+     */
+    @ParameterizedTest
+    @MethodSource("badProxyInterfaces")
+    void testForName(List<Class<?>> interfaces) {
+        assertThrows(IllegalArgumentException.class, () -> Proxy.getProxyClass(LOADER, interfaces.toArray(Class[]::new)));
+    }
 
-        try {
-            ClassLoader loader = ClassRestrictions.class.getClassLoader();
-            Class<?>[] interfaces;
-            Class<?> proxyClass;
+    private static final String nonPublicIntrfaceName = "java.util.zip.ZipConstants";
 
-            /*
-             * All of the Class objects in the interfaces array must represent
-             * interfaces, not classes or primitive types.
-             */
-            try {
-                interfaces = new Class<?>[] { Object.class };
-                proxyClass = Proxy.getProxyClass(loader, interfaces);
-                throw new Error(
-                    "proxy class created with java.lang.Object as interface");
-            } catch (IllegalArgumentException e) {
-                e.printStackTrace();
-                System.err.println();
-                // assume exception is for intended failure
-            }
-            try {
-                interfaces = new Class<?>[] { Integer.TYPE };
-                proxyClass = Proxy.getProxyClass(loader, interfaces);
-                throw new Error(
-                    "proxy class created with int.class as interface");
-            } catch (IllegalArgumentException e) {
-                e.printStackTrace();
-                System.err.println();
-                // assume exception is for intended failure
-            }
+    /*
+     * All non-public interfaces must be in the same package.
+     */
+    @Test
+    void testNonPublicIntfs() throws Exception {
+        var nonPublic1 = Bashful.class;
+        var nonPublic2 = Class.forName(nonPublicIntrfaceName);
+        assertFalse(Modifier.isPublic(nonPublic2.getModifiers()),
+            "Interface " + nonPublicIntrfaceName + " is public and need to be changed!");
+        var interfaces = new Class<?>[] { nonPublic1, nonPublic2 };
+        assertThrows(IllegalArgumentException.class, () -> Proxy.getProxyClass(LOADER, interfaces));
+    }
 
-            /*
-             * No two elements in the interfaces array may refer to identical
-             * Class objects.
-             */
-            try {
-                interfaces = new Class<?>[] { Bar.class, Bar.class };
-                proxyClass = Proxy.getProxyClass(loader, interfaces);
-                throw new Error(
-                    "proxy class created with repeated interfaces");
-            } catch (IllegalArgumentException e) {
-                e.printStackTrace();
-                System.err.println();
-                // assume exception is for intended failure
-            }
+    static Stream<ClassLoader> loaders() {
+        return Stream.of(null,
+                         ClassLoader.getPlatformClassLoader(),
+                         ClassLoader.getSystemClassLoader(),
+                         LOADER);
+    }
 
-            /*
-             * All of the interfaces types must be visible by name though the
-             * specified class loader.
-             */
-            String[] cpaths = System.getProperty("test.classes", ".")
-                                    .split(File.pathSeparator);
-            URL[] urls = new URL[cpaths.length];
-            for (int i=0; i < cpaths.length; i++) {
-                urls[i] = Paths.get(cpaths[i]).toUri().toURL();
-            }
-            ClassLoader altLoader = new URLClassLoader(urls, null);
-            Class altBarClass;
-            altBarClass = Class.forName(Bar.class.getName(), false, altLoader);
-            try {
-                interfaces = new Class<?>[] { altBarClass };
-                proxyClass = Proxy.getProxyClass(loader, interfaces);
-                throw new Error(
-                    "proxy class created with interface " +
-                    "not visible to class loader");
-            } catch (IllegalArgumentException e) {
-                e.printStackTrace();
-                System.err.println();
-                // assume exception is for intended failure
-            }
-
-            /*
-             * All non-public interfaces must be in the same package.
-             */
-            Class<?> nonPublic1 = Bashful.class;
-            Class<?> nonPublic2 = Class.forName(nonPublicIntrfaceName);
-            if (Modifier.isPublic(nonPublic2.getModifiers())) {
-                throw new Error(
-                    "Interface " + nonPublicIntrfaceName +
-                    " is public and need to be changed!");
-            }
-            try {
-                interfaces = new Class<?>[] { nonPublic1, nonPublic2 };
-                proxyClass = Proxy.getProxyClass(loader, interfaces);
-                throw new Error(
-                    "proxy class created with two non-public interfaces " +
-                    "in different packages");
-            } catch (IllegalArgumentException e) {
-                e.printStackTrace();
-                System.err.println();
-                // assume exception is for intended failure
-            }
-
-            /*
-             * No two interfaces may each have a method with the same name and
-             * parameter signature but different return type.
-             */
-            try {
-                interfaces = new Class<?>[] { Bar.class, Baz.class };
-                proxyClass = Proxy.getProxyClass(loader, interfaces);
-                throw new Error(
-                    "proxy class created with conflicting methods");
-            } catch (IllegalArgumentException e) {
-                e.printStackTrace();
-                System.err.println();
-                // assume exception is for intended failure
-            }
-
-            /*
-             * All components of this test have passed.
-             */
-            System.err.println("\nTEST PASSED");
-
-        } catch (Throwable e) {
-            System.err.println("\nTEST FAILED:");
-            e.printStackTrace();
-            throw new Error("TEST FAILED: ", e);
+    /*
+     * All of the interfaces types must be visible by name though the
+     * specified class loader.
+     */
+    @ParameterizedTest
+    @MethodSource("loaders")
+    void testNonVisibleInterface(ClassLoader loader) throws Exception {
+        String[] cpaths = TEST_CLASSES.split(File.pathSeparator);
+        URL[] urls = new URL[cpaths.length];
+        for (int i = 0; i < cpaths.length; i++) {
+            urls[i] = Paths.get(cpaths[i]).toUri().toURL();
         }
+        var altLoader = new URLClassLoader(urls, null);
+        var altBarClass = Class.forName(Bar.class.getName(), false, altLoader);
+        var interfaces = new Class<?>[]{ altBarClass };
+        assertThrows(IllegalArgumentException.class, () -> Proxy.getProxyClass(loader, interfaces));
     }
 }
diff --git a/test/jdk/java/net/HttpURLConnection/HttpURLConnectionExpectContinueTest.java b/test/jdk/java/net/HttpURLConnection/HttpURLConnectionExpectContinueTest.java
new file mode 100644
index 0000000..c9b8bc8
--- /dev/null
+++ b/test/jdk/java/net/HttpURLConnection/HttpURLConnectionExpectContinueTest.java
@@ -0,0 +1,443 @@
+/*
+ * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8054022
+ * @summary Verify that expect 100-continue doesn't hang
+ * @library /test/lib
+ * @run junit/othervm HttpURLConnectionExpectContinueTest
+ * @run junit/othervm -Djava.net.preferIPv4Stack=true HttpURLConnectionExpectContinueTest
+ * @run junit/othervm -Djava.net.preferIPv6Addresses=true HttpURLConnectionExpectContinueTest
+ */
+
+import jdk.test.lib.net.URIBuilder;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestInstance;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.*;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+@TestInstance(TestInstance.Lifecycle.PER_CLASS)
+public class HttpURLConnectionExpectContinueTest {
+
+    class Control {
+        volatile ServerSocket serverSocket = null;
+        volatile boolean stop = false;
+        volatile boolean respondWith100Continue = false;
+        volatile boolean write100ContinueTwice = false;
+        volatile String response = null;
+    }
+
+    private Thread serverThread = null;
+    private volatile Control control;
+    static final Logger logger;
+
+    static {
+        logger = Logger.getLogger("sun.net.www.protocol.http.HttpURLConnection");
+        logger.setLevel(Level.ALL);
+        Logger.getLogger("").getHandlers()[0].setLevel(Level.ALL);
+    }
+
+    @BeforeAll
+    public void startServerSocket() throws Exception {
+        Control control = this.control = new Control();
+
+        control.serverSocket = new ServerSocket();
+        control.serverSocket.setReuseAddress(true);
+        control.serverSocket.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
+        Runnable runnable = () -> {
+            while (!control.stop) {
+                try {
+                    Socket socket = control.serverSocket.accept();
+                    InputStream inputStream = socket.getInputStream();
+                    InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
+
+                    StringBuilder stringBuilder = new StringBuilder();
+
+                    // Read initial request
+                    byte b;
+                    while (true) {
+                        b = (byte) inputStreamReader.read();
+                        stringBuilder.append((char) b);
+
+                        if (stringBuilder.length() >= 4) {
+                            char[] lastBytes = new char[4];
+                            stringBuilder.getChars(
+                                    stringBuilder.length() - 4,
+                                    stringBuilder.length(), lastBytes, 0);
+                            if (Arrays.equals(lastBytes, new char[]{'\r', '\n', '\r', '\n'})) {
+                                break;
+                            }
+                        }
+                    }
+
+                    OutputStream outputStream = socket.getOutputStream();
+
+                    String header = stringBuilder.toString();
+                    String contentLengthString = "Content-Length:";
+
+                    // send 100 continue responses if set by test
+                    if (control.respondWith100Continue) {
+                        outputStream.write("HTTP/1.1 100 Continue\r\n\r\n".getBytes());
+                        outputStream.flush();
+                        if (control.write100ContinueTwice) {
+                            outputStream.write("HTTP/1.1 100 Continue\r\n\r\n".getBytes());
+                            outputStream.flush();
+                        }
+                    }
+
+                    // expect main request to be received
+                    int idx = header.indexOf(contentLengthString);
+
+                    if (idx >= 0) {
+                        String substr = header.substring(idx + contentLengthString.length());
+                        idx = substr.indexOf('\r');
+                        substr = substr.substring(0, idx);
+                        int contentLength = Integer.parseInt(substr.trim());
+
+                        StringBuilder contentLengthBuilder = new StringBuilder();
+                        for (int i = 0; i < contentLength; i++) {
+                            b = (byte) inputStreamReader.read();
+                            contentLengthBuilder.append((char) b);
+                        }
+
+                    } else {
+                        StringBuilder contentLengthBuilder = new StringBuilder();
+                        while (true) {
+                            b = (byte) inputStreamReader.read();
+                            contentLengthBuilder.append((char) b);
+
+                            if (contentLengthBuilder.length() >= 2) {
+                                char[] lastBytes = new char[2];
+                                contentLengthBuilder.getChars(
+                                        contentLengthBuilder.length() - 2,
+                                        contentLengthBuilder.length(), lastBytes, 0);
+                                if (Arrays.equals(lastBytes, new char[]{'\r', '\n'})) {
+                                    String lengthInHex =
+                                            contentLengthBuilder.substring(0, contentLengthBuilder.length() - 2);
+
+                                    int contentLength = Integer.parseInt(lengthInHex, 16);
+                                    char[] body = new char[contentLength];
+                                    inputStreamReader.read(body);
+                                    break;
+                                    // normally we have to parse more data,
+                                    // but for simplicity we expect no more chunks...
+                                }
+                            }
+                        }
+                    }
+
+                    // send response
+                    outputStream.write(control.response.getBytes());
+                    outputStream.flush();
+                } catch (SocketException e) {
+                    // ignore
+                } catch (IOException e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        };
+        serverThread = new Thread(runnable);
+        serverThread.start();
+    }
+
+    @AfterAll
+    public void stopServerSocket() throws Exception {
+        Control control = this.control;
+        control.stop = true;
+        control.serverSocket.close();
+        serverThread.join();
+    }
+
+    @Test
+    public void testNonChunkedRequestAndNoExpect100ContinueResponse() throws Exception {
+        String body = "testNonChunkedRequestAndNoExpect100ContinueResponse";
+        Control control = this.control;
+        control.response = "HTTP/1.1 200 OK\r\n" +
+                "Connection: close\r\n" +
+                "Content-Length: " + body.length() + "\r\n" +
+                "\r\n" +
+                body + "\r\n";
+        control.respondWith100Continue = false;
+        control.write100ContinueTwice = false;
+
+        HttpURLConnection connection = createConnection();
+        OutputStream outputStream = connection.getOutputStream();
+        outputStream.write(body.getBytes());
+        outputStream.close();
+
+        int responseCode = connection.getResponseCode();
+        String responseBody = new String(connection.getInputStream().readAllBytes(), StandardCharsets.UTF_8).strip();
+        System.err.println("response body: " + responseBody);
+        assertTrue(responseCode == 200,
+                String.format("Expected 200 response, instead received %s", responseCode));
+        assertTrue(body.equals(responseBody),
+                String.format("Expected response %s, instead received %s", body, responseBody));
+    }
+
+    @Test
+    public void testNonChunkedRequestWithExpect100ContinueResponse() throws Exception {
+        String body = "testNonChunkedRequestWithExpect100ContinueResponse";
+        Control control = this.control;
+        control.response = "HTTP/1.1 200 OK\r\n" +
+                "Connection: close\r\n" +
+                "Content-Length: " + body.length() + "\r\n" +
+                "\r\n" +
+                body + "\r\n";
+        control.respondWith100Continue = true;
+        control.write100ContinueTwice = false;
+
+        HttpURLConnection connection = createConnection();
+        OutputStream outputStream = connection.getOutputStream();
+        outputStream.write(body.getBytes());
+        outputStream.close();
+
+        int responseCode = connection.getResponseCode();
+        String responseBody = new String(connection.getInputStream().readAllBytes(), StandardCharsets.UTF_8).strip();
+        System.err.println("response body: " + responseBody);
+        assertTrue(responseCode == 200,
+                String.format("Expected 200 response, instead received %s", responseCode));
+        assertTrue(body.equals(responseBody),
+                String.format("Expected response %s, instead received %s", body, responseBody));
+    }
+
+    @Test
+    public void testNonChunkedRequestWithDoubleExpect100ContinueResponse() throws Exception {
+        String body = "testNonChunkedRequestWithDoubleExpect100ContinueResponse";
+        Control control = this.control;
+        control.response = "HTTP/1.1 200 OK\r\n" +
+                "Connection: close\r\n" +
+                "Content-Length: " + body.length() + "\r\n" +
+                "\r\n" +
+                body + "\r\n";
+        control.respondWith100Continue = true;
+        control.write100ContinueTwice = true;
+
+        HttpURLConnection connection = createConnection();
+        OutputStream outputStream = connection.getOutputStream();
+        outputStream.write(body.getBytes());
+        outputStream.close();
+
+        int responseCode = connection.getResponseCode();
+        String responseBody = new String(connection.getInputStream().readAllBytes(), StandardCharsets.UTF_8).strip();
+        System.err.println("response body: " + responseBody);
+        assertTrue(responseCode == 200,
+                String.format("Expected 200 response, instead received %s", responseCode));
+        assertTrue(body.equals(responseBody),
+                String.format("Expected response %s, instead received %s", body, responseBody));
+    }
+
+    @Test
+    public void testChunkedRequestAndNoExpect100ContinueResponse() throws Exception {
+        String body = "testChunkedRequestAndNoExpect100ContinueResponse";
+        Control control = this.control;
+        control.response = "HTTP/1.1 200 OK\r\n" +
+                "Connection: close\r\n" +
+                "Content-Length: " + body.length() + "\r\n" +
+                "\r\n" +
+                body + "\r\n";
+        control.respondWith100Continue = false;
+        control.write100ContinueTwice = false;
+
+        HttpURLConnection connection = createConnection();
+        connection.setChunkedStreamingMode(body.length() / 2);
+        OutputStream outputStream = connection.getOutputStream();
+        outputStream.write(body.getBytes());
+        outputStream.close();
+
+        int responseCode = connection.getResponseCode();
+        String responseBody = new String(connection.getInputStream().readAllBytes(), StandardCharsets.UTF_8).strip();
+        System.err.println("response body: " + responseBody);
+        assertTrue(responseCode == 200,
+                String.format("Expected 200 response, instead received %s", responseCode));
+        assertTrue(body.equals(responseBody),
+                String.format("Expected response %s, instead received %s", body, responseBody));
+    }
+
+    @Test
+    public void testChunkedRequestWithExpect100ContinueResponse() throws Exception {
+        String body = "testChunkedRequestWithExpect100ContinueResponse";
+        Control control = this.control;
+        control.response = "HTTP/1.1 200 OK\r\n" +
+                "Connection: close\r\n" +
+                "Content-Length: " + body.length() + "\r\n" +
+                "\r\n" +
+                body + "\r\n";
+        control.respondWith100Continue = true;
+        control.write100ContinueTwice = false;
+
+        HttpURLConnection connection = createConnection();
+        connection.setChunkedStreamingMode(body.length() / 2);
+        OutputStream outputStream = connection.getOutputStream();
+        outputStream.write(body.getBytes());
+        outputStream.close();
+
+        int responseCode = connection.getResponseCode();
+        String responseBody = new String(connection.getInputStream().readAllBytes(), StandardCharsets.UTF_8).strip();
+        System.err.println("response body: " + responseBody);
+        assertTrue(responseCode == 200,
+                String.format("Expected 200 response, instead received %s", responseCode));
+        assertTrue(body.equals(responseBody),
+                String.format("Expected response %s, instead received %s", body, responseBody));
+    }
+
+    @Test
+    public void testChunkedRequestWithDoubleExpect100ContinueResponse() throws Exception {
+        String body = "testChunkedRequestWithDoubleExpect100ContinueResponse";
+        Control control = this.control;
+        control.response = "HTTP/1.1 200 OK\r\n" +
+                "Connection: close\r\n" +
+                "Content-Length: " + body.length() + "\r\n" +
+                "\r\n" +
+                body + "\r\n";
+        control.respondWith100Continue = true;
+        control.write100ContinueTwice = true;
+
+        HttpURLConnection connection = createConnection();
+        connection.setChunkedStreamingMode(body.length() / 2);
+        OutputStream outputStream = connection.getOutputStream();
+        outputStream.write(body.getBytes());
+        outputStream.close();
+
+        int responseCode = connection.getResponseCode();
+        String responseBody = new String(connection.getInputStream().readAllBytes(), StandardCharsets.UTF_8).strip();
+        System.err.println("response body: " + responseBody);
+        assertTrue(responseCode == 200,
+                String.format("Expected 200 response, instead received %s", responseCode));
+        assertTrue(body.equals(responseBody),
+                String.format("Expected response %s, instead received %s", body, responseBody));
+    }
+
+    @Test
+    public void testFixedLengthRequestAndNoExpect100ContinueResponse() throws Exception {
+        String body = "testFixedLengthRequestAndNoExpect100ContinueResponse";
+        Control control = this.control;
+        control.response = "HTTP/1.1 200 OK\r\n" +
+                "Connection: close\r\n" +
+                "Content-Length: " + body.length() + "\r\n" +
+                "\r\n" +
+                body + "\r\n";
+        control.respondWith100Continue = false;
+        control.write100ContinueTwice = false;
+
+        HttpURLConnection connection = createConnection();
+        connection.setFixedLengthStreamingMode(body.length());
+        OutputStream outputStream = connection.getOutputStream();
+        outputStream.write(body.getBytes());
+        outputStream.close();
+
+        int responseCode = connection.getResponseCode();
+        String responseBody = new String(connection.getInputStream().readAllBytes(), StandardCharsets.UTF_8).strip();
+        System.err.println("response body: " + responseBody);
+        assertTrue(responseCode == 200,
+                String.format("Expected 200 response, instead received %s", responseCode));
+        assertTrue(body.equals(responseBody),
+                String.format("Expected response %s, instead received %s", body, responseBody));
+    }
+
+    @Test
+    public void testFixedLengthRequestWithExpect100ContinueResponse() throws Exception {
+        String body = "testFixedLengthRequestWithExpect100ContinueResponse";
+        Control control = this.control;
+        control.response = "HTTP/1.1 200 OK\r\n" +
+                "Connection: close\r\n" +
+                "Content-Length: " + body.length() + "\r\n" +
+                "\r\n" +
+                body + "\r\n";
+        control.respondWith100Continue = true;
+        control.write100ContinueTwice = false;
+
+        HttpURLConnection connection = createConnection();
+        connection.setFixedLengthStreamingMode(body.getBytes().length);
+        OutputStream outputStream = connection.getOutputStream();
+        outputStream.write(body.getBytes());
+        outputStream.close();
+
+        int responseCode = connection.getResponseCode();
+        String responseBody = new String(connection.getInputStream().readAllBytes(), StandardCharsets.UTF_8).strip();
+        System.err.println("response body: " + responseBody);
+        assertTrue(responseCode == 200,
+                String.format("Expected 200 response, instead received %s", responseCode));
+        assertTrue(body.equals(responseBody),
+                String.format("Expected response %s, instead received %s", body, responseBody));
+    }
+
+    @Test
+    public void testFixedLengthRequestWithDoubleExpect100ContinueResponse() throws Exception {
+        String body = "testFixedLengthRequestWithDoubleExpect100ContinueResponse";
+        Control control = this.control;
+        control.response = "HTTP/1.1 200 OK\r\n" +
+                "Connection: close\r\n" +
+                "Content-Length: " + body.length() + "\r\n" +
+                "\r\n" +
+                body + "\r\n";
+        control.respondWith100Continue = true;
+        control.write100ContinueTwice = true;
+
+        HttpURLConnection connection = createConnection();
+        connection.setFixedLengthStreamingMode(body.getBytes().length);
+        OutputStream outputStream = connection.getOutputStream();
+        outputStream.write(body.getBytes());
+        outputStream.close();
+
+        int responseCode = connection.getResponseCode();
+        String responseBody = new String(connection.getInputStream().readAllBytes(), StandardCharsets.UTF_8).strip();
+        System.err.println("response body: " + responseBody);
+        assertTrue(responseCode == 200,
+                String.format("Expected 200 response, instead received %s", responseCode));
+        assertTrue(body.equals(responseBody),
+                String.format("Expected response %s, instead received %s", body, responseBody));
+    }
+
+    // Creates a connection with all the common settings used in each test
+    private HttpURLConnection createConnection() throws Exception {
+        URL url = URIBuilder.newBuilder()
+                .scheme("http")
+                .loopback()
+                .port(control.serverSocket.getLocalPort())
+                .toURL();
+
+        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+        connection.setDoOutput(true);
+        connection.setReadTimeout(5000);
+        connection.setUseCaches(false);
+        connection.setInstanceFollowRedirects(false);
+        connection.setRequestMethod("POST");
+        connection.setRequestProperty("Connection", "Close");
+        connection.setRequestProperty("Expect", "100-Continue");
+
+        return connection;
+    }
+}
diff --git a/test/jdk/java/net/Inet6Address/serialize/Inet6AddressSerializationTest.java b/test/jdk/java/net/Inet6Address/serialize/Inet6AddressSerializationTest.java
index 4b1ffaf..c52884f 100644
--- a/test/jdk/java/net/Inet6Address/serialize/Inet6AddressSerializationTest.java
+++ b/test/jdk/java/net/Inet6Address/serialize/Inet6AddressSerializationTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -38,10 +38,16 @@
 import java.util.Enumeration;
 import java.util.List;
 
+import jdk.test.lib.Platform;
+import jdk.test.lib.NetworkConfiguration;
+
 /**
  * @test
  * @bug 8007373
  * @summary jdk7 backward compatibility serialization problem
+ * @library /test/lib
+ * @build jdk.test.lib.NetworkConfiguration
+ * @run main/othervm Inet6AddressSerializationTest
  */
 
 public class Inet6AddressSerializationTest {
@@ -177,12 +183,19 @@
                 .getNetworkInterfaces(); e.hasMoreElements();) {
             NetworkInterface netIF = e.nextElement();
             // Skip (Windows)Teredo Tunneling Pseudo-Interface
+            String dName = netIF.getDisplayName();
             if (isWindows) {
-                String dName = netIF.getDisplayName();
                 if (dName != null && dName.contains("Teredo")) {
                     continue;
                 }
             }
+            // skip awdl and llw interfaces on macosx
+            if (Platform.isOSX()) {
+                if((dName != null) &&
+                        ((dName.contains("awdl")) || (dName.contains("llw")))) {
+                        continue;
+                }
+            }
             for (Enumeration<InetAddress> iadrs = netIF.getInetAddresses(); iadrs
                     .hasMoreElements();) {
                 InetAddress iadr = iadrs.nextElement();
@@ -622,8 +635,8 @@
                         + deserializedNetworkInterface);
                 failed = true;
             }
-        } else if (!expectedNetworkInterface
-                .equals(deserializedNetworkInterface)) {
+        } else if (!NetworkConfiguration.isSameInterface(expectedNetworkInterface,
+                      deserializedNetworkInterface)) {
             System.err.println("Error checking "
                     + // versionStr +
                     " NetworkInterface, expected:" + expectedNetworkInterface
diff --git a/test/jdk/java/net/Socket/Timeouts.java b/test/jdk/java/net/Socket/Timeouts.java
index c2f2bf4..b809ffd 100644
--- a/test/jdk/java/net/Socket/Timeouts.java
+++ b/test/jdk/java/net/Socket/Timeouts.java
@@ -135,7 +135,7 @@
             long startMillis = millisTime();
             expectThrows(SocketTimeoutException.class, () -> s2.getInputStream().read());
             int timeout = s2.getSoTimeout();
-            checkDuration(startMillis, timeout-100, timeout+2000);
+            checkDuration(startMillis, timeout-100, timeout+20_000);
         });
     }
 
@@ -305,7 +305,7 @@
                 fail();
             } catch (SocketTimeoutException expected) {
                 int timeout = ss.getSoTimeout();
-                checkDuration(startMillis, timeout-100, timeout+2000);
+                checkDuration(startMillis, timeout-100, timeout+20_000);
             }
         }
     }
@@ -383,7 +383,7 @@
                 ss.accept().close();
                 fail();
             } catch (SocketException expected) {
-                checkDuration(startMillis, delay-100, delay+2000);
+                checkDuration(startMillis, delay-100, delay+20_000);
             }
         }
     }
@@ -403,7 +403,7 @@
             } catch (SocketTimeoutException expected) {
                 // accept should have blocked for 2 seconds
                 int timeout = ss.getSoTimeout();
-                checkDuration(startMillis, timeout-100, timeout+2000);
+                checkDuration(startMillis, timeout-100, timeout+20_000);
                 assertTrue(Thread.currentThread().isInterrupted());
             } finally {
                 Thread.interrupted(); // clear interrupt status
@@ -427,7 +427,7 @@
             } catch (SocketTimeoutException expected) {
                 // accept should have blocked for 4 seconds
                 int timeout = ss.getSoTimeout();
-                checkDuration(startMillis, timeout-100, timeout+2000);
+                checkDuration(startMillis, timeout-100, timeout+20_000);
                 assertTrue(Thread.currentThread().isInterrupted());
             } finally {
                 interrupter.cancel(true);
@@ -457,7 +457,7 @@
 
             // should get here in 4 seconds, not 8 seconds
             int timeout = ss.getSoTimeout();
-            checkDuration(startMillis, timeout-100, timeout+2000);
+            checkDuration(startMillis, timeout-100, timeout+20_000);
         } finally {
             pool.shutdown();
         }
@@ -499,7 +499,7 @@
 
             // should get here in 4 seconds, not 8 seconds
             int timeout = ss.getSoTimeout();
-            checkDuration(startMillis, timeout-100, timeout+2000);
+            checkDuration(startMillis, timeout-100, timeout+20_000);
         } finally {
             pool.shutdown();
         }
diff --git a/test/jdk/java/net/httpclient/AbstractThrowingPushPromises.java b/test/jdk/java/net/httpclient/AbstractThrowingPushPromises.java
index 2c15ec6..1bdbf6d 100644
--- a/test/jdk/java/net/httpclient/AbstractThrowingPushPromises.java
+++ b/test/jdk/java/net/httpclient/AbstractThrowingPushPromises.java
@@ -729,7 +729,7 @@
                 sharedClient == null ? null : sharedClient.toString();
         sharedClient = null;
         Thread.sleep(100);
-        AssertionError fail = TRACKER.check(500);
+        AssertionError fail = TRACKER.check(5000);
         try {
             http2TestServer.stop();
             https2TestServer.stop();
diff --git a/test/jdk/java/net/httpclient/AsFileDownloadTest.java b/test/jdk/java/net/httpclient/AsFileDownloadTest.java
index 890f070..96dc257 100644
--- a/test/jdk/java/net/httpclient/AsFileDownloadTest.java
+++ b/test/jdk/java/net/httpclient/AsFileDownloadTest.java
@@ -21,25 +21,6 @@
  * questions.
  */
 
-/*
- * @test
- * @summary Basic test for ofFileDownload
- * @bug 8196965 8302475
- * @modules java.base/sun.net.www.http
- *          java.net.http/jdk.internal.net.http.common
- *          java.net.http/jdk.internal.net.http.frame
- *          java.net.http/jdk.internal.net.http.hpack
- *          java.logging
- *          jdk.httpserver
- * @library /test/lib http2/server
- * @build Http2TestServer
- * @build jdk.test.lib.net.SimpleSSLContext
- * @build jdk.test.lib.Platform
- * @build jdk.test.lib.util.FileUtils
- * @run testng/othervm AsFileDownloadTest
- * @run testng/othervm/java.security.policy=AsFileDownloadTest.policy AsFileDownloadTest
- */
-
 import com.sun.net.httpserver.HttpExchange;
 import com.sun.net.httpserver.HttpHandler;
 import com.sun.net.httpserver.HttpServer;
@@ -81,6 +62,25 @@
 import static org.testng.Assert.assertTrue;
 import static org.testng.Assert.fail;
 
+/*
+ * @test
+ * @summary Basic test for ofFileDownload
+ * @bug 8196965 8302475
+ * @modules java.base/sun.net.www.http
+ *          java.net.http/jdk.internal.net.http.common
+ *          java.net.http/jdk.internal.net.http.frame
+ *          java.net.http/jdk.internal.net.http.hpack
+ *          java.logging
+ *          jdk.httpserver
+ * @library /test/lib http2/server
+ * @build Http2TestServer
+ * @build jdk.test.lib.net.SimpleSSLContext
+ * @build jdk.test.lib.Platform
+ * @build jdk.test.lib.util.FileUtils
+ * @run testng/othervm AsFileDownloadTest
+ * @run testng/othervm/java.security.policy=AsFileDownloadTest.policy AsFileDownloadTest
+ */
+
 public class AsFileDownloadTest {
 
     SSLContext sslContext;
@@ -267,8 +267,10 @@
     // -- Infrastructure
 
     static String serverAuthority(HttpServer server) {
-        return InetAddress.getLoopbackAddress().getHostName() + ":"
-                + server.getAddress().getPort();
+        final String hostIP = InetAddress.getLoopbackAddress().getHostAddress();
+        // escape for ipv6
+        final String h = hostIP.contains(":") ? "[" + hostIP + "]" : hostIP;
+        return h + ":" + server.getAddress().getPort();
     }
 
     @BeforeTest
diff --git a/test/jdk/java/net/httpclient/AsFileDownloadTest.policy b/test/jdk/java/net/httpclient/AsFileDownloadTest.policy
index 0f38171..79103ca 100644
--- a/test/jdk/java/net/httpclient/AsFileDownloadTest.policy
+++ b/test/jdk/java/net/httpclient/AsFileDownloadTest.policy
@@ -34,7 +34,8 @@
     permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.net.http.hpack";
     permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www.http";
 
-    permission java.net.SocketPermission "localhost:*", "accept,resolve";
+    permission java.net.SocketPermission "127.0.0.1:*", "accept,resolve";
+    permission java.net.SocketPermission "[::1]:*", "accept,resolve";
     permission java.lang.RuntimePermission "modifyThread";
 };
 
@@ -42,10 +43,15 @@
     permission java.io.FilePermission "${user.dir}${/}asFileDownloadTest.tmp.dir", "read,write";
     permission java.io.FilePermission "${user.dir}${/}asFileDownloadTest.tmp.dir/-", "read,write";
 
-    permission java.net.URLPermission "http://localhost:*/http1/afdt",   "POST";
-    permission java.net.URLPermission "https://localhost:*/https1/afdt", "POST";
-    permission java.net.URLPermission "http://localhost:*/http2/afdt",   "POST";
-    permission java.net.URLPermission "https://localhost:*/https2/afdt", "POST";
+    permission java.net.URLPermission "http://127.0.0.1:*/http1/afdt",   "POST";
+    permission java.net.URLPermission "https://127.0.0.1:*/https1/afdt", "POST";
+    permission java.net.URLPermission "http://127.0.0.1:*/http2/afdt",   "POST";
+    permission java.net.URLPermission "https://127.0.0.1:*/https2/afdt", "POST";
+    // ipv6
+    permission java.net.URLPermission "http://[::1]:*/http1/afdt",   "POST";
+    permission java.net.URLPermission "https://[::1]:*/https1/afdt", "POST";
+    permission java.net.URLPermission "http://[::1]:*/http2/afdt",   "POST";
+    permission java.net.URLPermission "https://[::1]:*/https2/afdt", "POST";
 
 
     // needed to grant permission to the HTTP/2 server
@@ -58,7 +64,8 @@
     permission java.util.logging.LoggingPermission "control";
 
     // needed to grant the HTTP servers
-    permission java.net.SocketPermission "localhost:*", "accept,resolve";
+    permission java.net.SocketPermission "127.0.0.1:*", "accept,resolve";
+    permission java.net.SocketPermission "[::1]:*", "accept,resolve";
 
     permission java.util.PropertyPermission "*", "read";
     permission java.lang.RuntimePermission "modifyThread";
diff --git a/test/jdk/java/net/httpclient/ByteArrayPublishers.java b/test/jdk/java/net/httpclient/ByteArrayPublishers.java
index 2ac62f2..114ebcd 100644
--- a/test/jdk/java/net/httpclient/ByteArrayPublishers.java
+++ b/test/jdk/java/net/httpclient/ByteArrayPublishers.java
@@ -25,7 +25,7 @@
  * @test
  * @bug 8222968
  * @summary ByteArrayPublisher is not thread-safe resulting in broken re-use of HttpRequests
- * @run main/othervm ByteArrayPublishers
+ * @run main/othervm -Dsun.net.httpserver.idleInterval=50000 ByteArrayPublishers
  */
 
 import java.net.InetAddress;
diff --git a/test/jdk/java/net/httpclient/FilePublisher/FilePublisherPermsTest1.policy b/test/jdk/java/net/httpclient/FilePublisher/FilePublisherPermsTest1.policy
index a133d4e..b32f230 100644
--- a/test/jdk/java/net/httpclient/FilePublisher/FilePublisherPermsTest1.policy
+++ b/test/jdk/java/net/httpclient/FilePublisher/FilePublisherPermsTest1.policy
@@ -34,19 +34,29 @@
     permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.net.http.hpack";
     permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www.http";
 
-    permission java.net.SocketPermission "localhost:*", "accept,resolve";
+    permission java.net.SocketPermission "127.0.0.1:*", "accept,resolve";
+    permission java.net.SocketPermission "[::1]:*", "accept,resolve";
     permission java.lang.RuntimePermission "modifyThread";
 };
 
 grant codeBase "file:${test.classes}/*" {
-    permission java.net.URLPermission "http://localhost:*/http1/echo", "POST";
-    permission java.net.URLPermission "https://localhost:*/https1/echo", "POST";
-    permission java.net.URLPermission "http://localhost:*/http2/echo", "POST";
-    permission java.net.URLPermission "https://localhost:*/https2/echo", "POST";
-    permission java.net.URLPermission "https://localhost:*/http1/echo", "GET";
-    permission java.net.URLPermission "https://localhost:*/https1/echo", "GET";
-    permission java.net.URLPermission "http://localhost:*/http2/echo", "GET";
-    permission java.net.URLPermission "https://localhost:*/https2/echo", "GET";
+    permission java.net.URLPermission "http://127.0.0.1:*/http1/echo", "POST";
+    permission java.net.URLPermission "https://127.0.0.1:*/https1/echo", "POST";
+    permission java.net.URLPermission "http://127.0.0.1:*/http2/echo", "POST";
+    permission java.net.URLPermission "https://127.0.0.1:*/https2/echo", "POST";
+    permission java.net.URLPermission "https://127.0.0.1:*/http1/echo", "GET";
+    permission java.net.URLPermission "https://127.0.0.1:*/https1/echo", "GET";
+    permission java.net.URLPermission "http://127.0.0.1:*/http2/echo", "GET";
+    permission java.net.URLPermission "https://127.0.0.1:*/https2/echo", "GET";
+    // ipv6
+    permission java.net.URLPermission "http://[::1]:*/http1/echo", "POST";
+    permission java.net.URLPermission "https://[::1]:*/https1/echo", "POST";
+    permission java.net.URLPermission "http://[::1]:*/http2/echo", "POST";
+    permission java.net.URLPermission "https://[::1]:*/https2/echo", "POST";
+    permission java.net.URLPermission "https://[::1]:*/http1/echo", "GET";
+    permission java.net.URLPermission "https://[::1]:*/https1/echo", "GET";
+    permission java.net.URLPermission "http://[::1]:*/http2/echo", "GET";
+    permission java.net.URLPermission "https://[::1]:*/https2/echo", "GET";
 
     // file permissions
     permission java.io.FilePermission "${user.dir}${/}defaultFile.txt", "read,write,delete";
@@ -69,7 +79,8 @@
     permission java.util.logging.LoggingPermission "control";
 
     // needed to grant the HTTP servers
-    permission java.net.SocketPermission "localhost:*", "accept,resolve";
+    permission java.net.SocketPermission "127.0.0.1:*", "accept,resolve";
+    permission java.net.SocketPermission "[::1]:*", "accept,resolve";
 
     permission java.util.PropertyPermission "*", "read";
     permission java.lang.RuntimePermission "modifyThread";
diff --git a/test/jdk/java/net/httpclient/FilePublisher/FilePublisherPermsTest2.policy b/test/jdk/java/net/httpclient/FilePublisher/FilePublisherPermsTest2.policy
index fdde92b..eac0256 100644
--- a/test/jdk/java/net/httpclient/FilePublisher/FilePublisherPermsTest2.policy
+++ b/test/jdk/java/net/httpclient/FilePublisher/FilePublisherPermsTest2.policy
@@ -36,19 +36,29 @@
     permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.net.http.hpack";
     permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www.http";
 
-    permission java.net.SocketPermission "localhost:*", "accept,resolve";
+    permission java.net.SocketPermission "127.0.0.1:*", "accept,resolve";
+    permission java.net.SocketPermission "[::1]:*", "accept,resolve";
     permission java.lang.RuntimePermission "modifyThread";
 };
 
 grant codeBase "file:${test.classes}/*" {
-    permission java.net.URLPermission "http://localhost:*/http1/echo", "POST";
-    permission java.net.URLPermission "https://localhost:*/https1/echo", "POST";
-    permission java.net.URLPermission "http://localhost:*/http2/echo", "POST";
-    permission java.net.URLPermission "https://localhost:*/https2/echo", "POST";
-    permission java.net.URLPermission "https://localhost:*/http1/echo", "GET";
-    permission java.net.URLPermission "https://localhost:*/https1/echo", "GET";
-    permission java.net.URLPermission "http://localhost:*/http2/echo", "GET";
-    permission java.net.URLPermission "https://localhost:*/https2/echo", "GET";
+    permission java.net.URLPermission "http://127.0.0.1:*/http1/echo", "POST";
+    permission java.net.URLPermission "https://127.0.0.1:*/https1/echo", "POST";
+    permission java.net.URLPermission "http://127.0.0.1:*/http2/echo", "POST";
+    permission java.net.URLPermission "https://127.0.0.1:*/https2/echo", "POST";
+    permission java.net.URLPermission "https://127.0.0.1:*/http1/echo", "GET";
+    permission java.net.URLPermission "https://127.0.0.1:*/https1/echo", "GET";
+    permission java.net.URLPermission "http://127.0.0.1:*/http2/echo", "GET";
+    permission java.net.URLPermission "https://127.0.0.1:*/https2/echo", "GET";
+    // ipv6
+    permission java.net.URLPermission "http://[::1]:*/http1/echo", "POST";
+    permission java.net.URLPermission "https://[::1]:*/https1/echo", "POST";
+    permission java.net.URLPermission "http://[::1]:*/http2/echo", "POST";
+    permission java.net.URLPermission "https://[::1]:*/https2/echo", "POST";
+    permission java.net.URLPermission "https://[::1]:*/http1/echo", "GET";
+    permission java.net.URLPermission "https://[::1]:*/https1/echo", "GET";
+    permission java.net.URLPermission "http://[::1]:*/http2/echo", "GET";
+    permission java.net.URLPermission "https://[::1]:*/https2/echo", "GET";
 
     // file permissions
     permission java.io.FilePermission "${user.dir}${/}defaultFile.txt", "read,write,delete";
@@ -74,7 +84,8 @@
     permission java.util.logging.LoggingPermission "control";
 
     // needed to grant the HTTP servers
-    permission java.net.SocketPermission "localhost:*", "accept,resolve";
+    permission java.net.SocketPermission "127.0.0.1:*", "accept,resolve";
+    permission java.net.SocketPermission "[::1]:*", "accept,resolve";
 
     permission java.util.PropertyPermission "*", "read";
     permission java.lang.RuntimePermission "modifyThread";
diff --git a/test/jdk/java/net/httpclient/FilePublisher/FilePublisherPermsTest3.policy b/test/jdk/java/net/httpclient/FilePublisher/FilePublisherPermsTest3.policy
index 4f7c4fe..e855d69 100644
--- a/test/jdk/java/net/httpclient/FilePublisher/FilePublisherPermsTest3.policy
+++ b/test/jdk/java/net/httpclient/FilePublisher/FilePublisherPermsTest3.policy
@@ -41,19 +41,29 @@
     permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.net.http.hpack";
     permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www.http";
 
-    permission java.net.SocketPermission "localhost:*", "accept,resolve";
+    permission java.net.SocketPermission "127.0.0.1:*", "accept,resolve";
+    permission java.net.SocketPermission "[::1]:*", "accept,resolve";
     permission java.lang.RuntimePermission "modifyThread";
 };
 
 grant codeBase "file:${test.classes}/*" {
-    permission java.net.URLPermission "http://localhost:*/http1/echo", "POST";
-    permission java.net.URLPermission "https://localhost:*/https1/echo", "POST";
-    permission java.net.URLPermission "http://localhost:*/http2/echo", "POST";
-    permission java.net.URLPermission "https://localhost:*/https2/echo", "POST";
-    permission java.net.URLPermission "https://localhost:*/http1/echo", "GET";
-    permission java.net.URLPermission "https://localhost:*/https1/echo", "GET";
-    permission java.net.URLPermission "http://localhost:*/http2/echo", "GET";
-    permission java.net.URLPermission "https://localhost:*/https2/echo", "GET";
+    permission java.net.URLPermission "http://127.0.0.1:*/http1/echo", "POST";
+    permission java.net.URLPermission "https://127.0.0.1:*/https1/echo", "POST";
+    permission java.net.URLPermission "http://127.0.0.1:*/http2/echo", "POST";
+    permission java.net.URLPermission "https://127.0.0.1:*/https2/echo", "POST";
+    permission java.net.URLPermission "https://127.0.0.1:*/http1/echo", "GET";
+    permission java.net.URLPermission "https://127.0.0.1:*/https1/echo", "GET";
+    permission java.net.URLPermission "http://127.0.0.1:*/http2/echo", "GET";
+    permission java.net.URLPermission "https://127.0.0.1:*/https2/echo", "GET";
+    // ipv6
+    permission java.net.URLPermission "http://[::1]:*/http1/echo", "POST";
+    permission java.net.URLPermission "https://[::1]:*/https1/echo", "POST";
+    permission java.net.URLPermission "http://[::1]:*/http2/echo", "POST";
+    permission java.net.URLPermission "https://[::1]:*/https2/echo", "POST";
+    permission java.net.URLPermission "https://[::1]:*/http1/echo", "GET";
+    permission java.net.URLPermission "https://[::1]:*/https1/echo", "GET";
+    permission java.net.URLPermission "http://[::1]:*/http2/echo", "GET";
+    permission java.net.URLPermission "https://[::1]:*/https2/echo", "GET";
 
     // file permissions
     permission java.io.FilePermission "${user.dir}${/}defaultFile.txt", "read,write,delete";
@@ -77,7 +87,8 @@
     permission java.util.logging.LoggingPermission "control";
 
     // needed to grant the HTTP servers
-    permission java.net.SocketPermission "localhost:*", "accept,resolve";
+    permission java.net.SocketPermission "127.0.0.1:*", "accept,resolve";
+    permission java.net.SocketPermission "[::1]:*", "accept,resolve";
 
     permission java.util.PropertyPermission "*", "read";
     permission java.lang.RuntimePermission "modifyThread";
diff --git a/test/jdk/java/net/httpclient/FilePublisher/FilePublisherTest.policy b/test/jdk/java/net/httpclient/FilePublisher/FilePublisherTest.policy
index 82f5178..0765c40 100644
--- a/test/jdk/java/net/httpclient/FilePublisher/FilePublisherTest.policy
+++ b/test/jdk/java/net/httpclient/FilePublisher/FilePublisherTest.policy
@@ -34,19 +34,29 @@
     permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.net.http.hpack";
     permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www.http";
 
-    permission java.net.SocketPermission "localhost:*", "accept,resolve";
+    permission java.net.SocketPermission "127.0.0.1:*", "accept,resolve";
+    permission java.net.SocketPermission "[::1]:*", "accept,resolve";
     permission java.lang.RuntimePermission "modifyThread";
 };
 
 grant codeBase "file:${test.classes}/*" {
-    permission java.net.URLPermission "http://localhost:*/http1/echo", "POST";
-    permission java.net.URLPermission "https://localhost:*/https1/echo", "POST";
-    permission java.net.URLPermission "http://localhost:*/http2/echo", "POST";
-    permission java.net.URLPermission "https://localhost:*/https2/echo", "POST";
-    permission java.net.URLPermission "https://localhost:*/http1/echo", "GET";
-    permission java.net.URLPermission "https://localhost:*/https1/echo", "GET";
-    permission java.net.URLPermission "http://localhost:*/http2/echo", "GET";
-    permission java.net.URLPermission "https://localhost:*/https2/echo", "GET";
+    permission java.net.URLPermission "http://127.0.0.1:*/http1/echo", "POST";
+    permission java.net.URLPermission "https://127.0.0.1:*/https1/echo", "POST";
+    permission java.net.URLPermission "http://127.0.0.1:*/http2/echo", "POST";
+    permission java.net.URLPermission "https://127.0.0.1:*/https2/echo", "POST";
+    permission java.net.URLPermission "https://127.0.0.1:*/http1/echo", "GET";
+    permission java.net.URLPermission "https://127.0.0.1:*/https1/echo", "GET";
+    permission java.net.URLPermission "http://127.0.0.1:*/http2/echo", "GET";
+    permission java.net.URLPermission "https://127.0.0.1:*/https2/echo", "GET";
+    // ipv6
+    permission java.net.URLPermission "http://[::1]:*/http1/echo", "POST";
+    permission java.net.URLPermission "https://[::1]:*/https1/echo", "POST";
+    permission java.net.URLPermission "http://[::1]:*/http2/echo", "POST";
+    permission java.net.URLPermission "https://[::1]:*/https2/echo", "POST";
+    permission java.net.URLPermission "https://[::1]:*/http1/echo", "GET";
+    permission java.net.URLPermission "https://[::1]:*/https1/echo", "GET";
+    permission java.net.URLPermission "http://[::1]:*/http2/echo", "GET";
+    permission java.net.URLPermission "https://[::1]:*/https2/echo", "GET";
 
     // file permissions
     permission java.io.FilePermission "${user.dir}${/}defaultFile.txt", "read,write,delete";
@@ -62,7 +72,8 @@
     permission java.util.logging.LoggingPermission "control";
 
     // needed to grant the HTTP servers
-    permission java.net.SocketPermission "localhost:*", "accept,resolve";
+    permission java.net.SocketPermission "127.0.0.1:*", "accept,resolve";
+    permission java.net.SocketPermission "[::1]:*", "accept,resolve";
 
     permission java.util.PropertyPermission "*", "read";
     permission java.lang.RuntimePermission "modifyThread";
diff --git a/test/jdk/java/net/httpclient/HttpServerAdapters.java b/test/jdk/java/net/httpclient/HttpServerAdapters.java
index 3029d37..2b0c6bb 100644
--- a/test/jdk/java/net/httpclient/HttpServerAdapters.java
+++ b/test/jdk/java/net/httpclient/HttpServerAdapters.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -227,6 +227,7 @@
         public abstract URI getRequestURI();
         public abstract String getRequestMethod();
         public abstract void close();
+        public abstract InetSocketAddress getRemoteAddress();
         public void serverPush(URI uri, HttpHeaders headers, byte[] body) {
             ByteArrayInputStream bais = new ByteArrayInputStream(body);
             serverPush(uri, headers, bais);
@@ -284,6 +285,12 @@
             }
             @Override
             public void close() { exchange.close(); }
+
+            @Override
+            public InetSocketAddress getRemoteAddress() {
+                return exchange.getRemoteAddress();
+            }
+
             @Override
             public URI getRequestURI() { return exchange.getRequestURI(); }
             @Override
@@ -339,6 +346,12 @@
             }
             @Override
             public void close() { exchange.close();}
+
+            @Override
+            public InetSocketAddress getRemoteAddress() {
+                return exchange.getRemoteAddress();
+            }
+
             @Override
             public URI getRequestURI() { return exchange.getRequestURI(); }
             @Override
@@ -517,8 +530,15 @@
         public abstract Version getVersion();
 
         public String serverAuthority() {
-            return InetAddress.getLoopbackAddress().getHostName() + ":"
-                    + getAddress().getPort();
+            InetSocketAddress address = getAddress();
+            String hostString = address.getHostString();
+            hostString = address.getAddress().isLoopbackAddress() || hostString.equals("localhost")
+                    ? address.getAddress().getHostAddress() // use the raw IP address, if loopback
+                    : hostString; // use whatever host string was used to construct the address
+            hostString = hostString.contains(":")
+                    ? "[" + hostString + "]"
+                    : hostString;
+            return hostString + ":" + address.getPort();
         }
 
         public static HttpTestServer of(HttpServer server) {
diff --git a/test/jdk/java/net/httpclient/LightWeightHttpServer.java b/test/jdk/java/net/httpclient/LightWeightHttpServer.java
index 54fa174..92603d5 100644
--- a/test/jdk/java/net/httpclient/LightWeightHttpServer.java
+++ b/test/jdk/java/net/httpclient/LightWeightHttpServer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -119,14 +119,21 @@
         System.out.println("HTTP server port = " + port);
         httpsport = httpsServer.getAddress().getPort();
         System.out.println("HTTPS server port = " + httpsport);
-        httproot = "http://localhost:" + port + "/";
-        httpsroot = "https://localhost:" + httpsport + "/";
+        httproot = "http://" + makeServerAuthority(httpServer.getAddress()) + "/";
+        httpsroot = "https://" + makeServerAuthority(httpsServer.getAddress()) + "/";
 
         proxy = new ProxyServer(0, false);
         proxyPort = proxy.getPort();
         System.out.println("Proxy port = " + proxyPort);
     }
 
+    private static String makeServerAuthority(final InetSocketAddress addr) {
+        final String hostIP = addr.getAddress().getHostAddress();
+        // escape for ipv6
+        final String h = hostIP.contains(":") ? "[" + hostIP + "]" : hostIP;
+        return h + ":" + addr.getPort();
+    }
+
     public static void stop() throws IOException {
         if (httpServer != null) {
             httpServer.stop(0);
diff --git a/test/jdk/java/net/httpclient/ManyRequests.java b/test/jdk/java/net/httpclient/ManyRequests.java
index f79d565..2963774 100644
--- a/test/jdk/java/net/httpclient/ManyRequests.java
+++ b/test/jdk/java/net/httpclient/ManyRequests.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,13 +32,13 @@
  * @compile ../../../com/sun/net/httpserver/LogFilter.java
  * @compile ../../../com/sun/net/httpserver/EchoHandler.java
  * @compile ../../../com/sun/net/httpserver/FileServerHandler.java
- * @run main/othervm/timeout=40 -Djdk.httpclient.HttpClient.log=ssl ManyRequests
- * @run main/othervm/timeout=40 -Dtest.insertDelay=true ManyRequests
- * @run main/othervm/timeout=40 -Dtest.chunkSize=64 ManyRequests
- * @run main/othervm/timeout=40 -Dtest.insertDelay=true -Dtest.chunkSize=64 ManyRequests
+ * @run main/othervm/timeout=40 -Djdk.httpclient.HttpClient.log=ssl,channel ManyRequests
+ * @run main/othervm/timeout=40 -Djdk.httpclient.HttpClient.log=channel -Dtest.insertDelay=true ManyRequests
+ * @run main/othervm/timeout=40 -Djdk.httpclient.HttpClient.log=channel -Dtest.chunkSize=64 ManyRequests
+ * @run main/othervm/timeout=40 -Djdk.httpclient.HttpClient.log=channel -Dtest.insertDelay=true -Dtest.chunkSize=64 ManyRequests
  * @summary Send a large number of requests asynchronously
  */
- // * @run main/othervm/timeout=40 -Djdk.httpclient.HttpClient.log=ssl ManyRequests
+ // * @run main/othervm/timeout=40 -Djdk.httpclient.HttpClient.log=ssl,channel ManyRequests
 
 import com.sun.net.httpserver.HttpsConfigurator;
 import com.sun.net.httpserver.HttpsParameters;
@@ -47,6 +47,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.net.ConnectException;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.URI;
@@ -54,13 +55,18 @@
 import java.net.http.HttpClient.Builder;
 import java.net.http.HttpRequest;
 import java.net.http.HttpRequest.BodyPublishers;
+import java.net.http.HttpResponse;
 import java.net.http.HttpResponse.BodyHandlers;
 import java.time.Duration;
 import java.util.Arrays;
 import java.util.Formatter;
 import java.util.HashMap;
 import java.util.LinkedList;
+import java.util.Map;
 import java.util.Random;
+import java.util.concurrent.CompletionException;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ThreadFactory;
@@ -68,17 +74,27 @@
 import java.util.logging.Logger;
 import java.util.logging.Level;
 import java.util.concurrent.CompletableFuture;
+import java.util.stream.Stream;
 import javax.net.ssl.SSLContext;
+
+import jdk.test.lib.Platform;
+import jdk.test.lib.RandomFactory;
 import jdk.test.lib.net.SimpleSSLContext;
+import jdk.test.lib.net.URIBuilder;
 
 public class ManyRequests {
 
-    volatile static int counter = 0;
+    static final int MAX_COUNT = 20;
+    static final int MAX_LIMIT = 40;
+    static final AtomicInteger COUNT = new AtomicInteger();
+    static final AtomicInteger LIMIT = new AtomicInteger(MAX_LIMIT);
+    static final Random RANDOM = RandomFactory.getRandom();
 
     public static void main(String[] args) throws Exception {
         Logger logger = Logger.getLogger("com.sun.net.httpserver");
         logger.setLevel(Level.ALL);
         logger.info("TEST");
+        Stream.of(Logger.getLogger("").getHandlers()).forEach((h) -> h.setLevel(Level.ALL));
         System.out.println("Sending " + REQUESTS
                          + " requests; delay=" + INSERT_DELAY
                          + ", chunks=" + CHUNK_SIZE
@@ -106,14 +122,14 @@
     }
 
     //static final int REQUESTS = 1000;
-    static final int REQUESTS = 20;
+    static final int REQUESTS = MAX_COUNT;
     static final boolean INSERT_DELAY = Boolean.getBoolean("test.insertDelay");
     static final int CHUNK_SIZE = Math.max(0,
            Integer.parseInt(System.getProperty("test.chunkSize", "0")));
     static final boolean XFIXED = Boolean.getBoolean("test.XFixed");
 
     static class TestEchoHandler extends EchoHandler {
-        final Random rand = jdk.test.lib.RandomFactory.getRandom();
+        final Random rand = RANDOM;
         @Override
         public void handle(HttpExchange e) throws IOException {
             System.out.println("Server: received " + e.getRequestURI());
@@ -139,60 +155,126 @@
         }
     }
 
+    static String now(long start) {
+        long elapsed = System.nanoTime() - start;
+        long ms = elapsed / 1000_000L;
+        long s = ms / 1000L;
+        if (s == 0) return ms + "ms: ";
+        return s + "s, " + (ms - s * 1000L) + "ms: ";
+    }
+
+    static String failure(Throwable t) {
+        String s = "\n\t failed: " + t;
+        for (t = t.getCause(); t != null ; t = t.getCause()) {
+            s = s + "\n\t\t  Caused by: " + t;
+        }
+        return s;
+    }
+
     static void test(HttpsServer server, HttpClient client) throws Exception {
         int port = server.getAddress().getPort();
-        URI baseURI = new URI("https://localhost:" + port + "/foo/x");
+
+        URI baseURI = URIBuilder.newBuilder()
+                .scheme("https")
+                .host(InetAddress.getLoopbackAddress().getHostName())
+                .port(port)
+                .path("/foo/x").build();
         server.createContext("/foo", new TestEchoHandler());
         server.start();
 
-        RequestLimiter limiter = new RequestLimiter(40);
-        Random rand = new Random();
-        CompletableFuture<?>[] results = new CompletableFuture<?>[REQUESTS];
-        HashMap<HttpRequest,byte[]> bodies = new HashMap<>();
+        // This loop implements a retry mechanism to work around an issue
+        // on some systems (observed on Windows 10) that seem to be trying to
+        // throttle the number of connections that can be made concurrently by
+        // rejecting connection attempts.
+        // On the first iteration of this loop, we will attempt 20 concurrent
+        // requests. If this fails with ConnectException, we will retry the
+        // 20 requests, but limiting the concurrency to 10 (LIMIT <- 10).
+        // If this fails again, the test will fail.
+        boolean done = false;
+        LOOP: do {
+            RequestLimiter limiter = new RequestLimiter(LIMIT.get());
+            Random rand = RANDOM;
+            CompletableFuture<?>[] results = new CompletableFuture<?>[REQUESTS];
+            Map<HttpRequest,byte[]> bodies = new ConcurrentHashMap<>();
 
-        for (int i=0; i<REQUESTS; i++) {
-            byte[] buf = new byte[(i+1)*CHUNK_SIZE+i+1];  // different size bodies
-            rand.nextBytes(buf);
-            URI uri = new URI(baseURI.toString() + String.valueOf(i+1));
-            HttpRequest r = HttpRequest.newBuilder(uri)
-                                       .header("XFixed", "true")
-                                       .POST(BodyPublishers.ofByteArray(buf))
-                                       .build();
-            bodies.put(r, buf);
+            long start = System.nanoTime();
 
-            results[i] =
-                limiter.whenOkToSend()
-                       .thenCompose((v) -> {
-                           System.out.println("Client: sendAsync: " + r.uri());
-                           return client.sendAsync(r, BodyHandlers.ofByteArray());
-                       })
-                       .thenCompose((resp) -> {
-                           limiter.requestComplete();
-                           if (resp.statusCode() != 200) {
-                               String s = "Expected 200, got: " + resp.statusCode();
-                               System.out.println(s + " from "
-                                                  + resp.request().uri().getPath());
-                               return completedWithIOException(s);
-                           } else {
-                               counter++;
-                               System.out.println("Result (" + counter + ") from "
-                                                   + resp.request().uri().getPath());
-                           }
-                           return CompletableFuture.completedStage(resp.body())
-                                      .thenApply((b) -> new Pair<>(resp, b));
-                       })
-                      .thenAccept((pair) -> {
-                          HttpRequest request = pair.t.request();
-                          byte[] requestBody = bodies.get(request);
-                          check(Arrays.equals(requestBody, pair.u),
-                                "bodies not equal:[" + bytesToHexString(requestBody)
-                                + "] [" + bytesToHexString(pair.u) + "]");
+            for (int i = 0; i < REQUESTS; i++) {
+                byte[] buf = new byte[(i + 1) * CHUNK_SIZE + i + 1];  // different size bodies
+                rand.nextBytes(buf);
+                URI uri = new URI(baseURI.toString() + String.valueOf(i + 1));
+                HttpRequest r = HttpRequest.newBuilder(uri)
+                        .header("XFixed", "true")
+                        .POST(BodyPublishers.ofByteArray(buf))
+                        .build();
+                bodies.put(r, buf);
 
-                      });
-        }
+                results[i] =
+                        limiter.whenOkToSend()
+                                .thenCompose((v) -> {
+                                    System.out.println("Client: sendAsync: " + r.uri());
+                                    return client.sendAsync(r, BodyHandlers.ofByteArray());
+                                })
+                                .handle((resp, t) -> {
+                                    limiter.requestComplete();
+                                    CompletionStage<Pair<HttpResponse<byte[]>, byte[]>> res;
+                                    String now = now(start);
+                                    if (t == null) {
+                                        if (resp.statusCode() != 200) {
+                                            String s = "Expected 200, got: " + resp.statusCode();
+                                            System.out.println(now + s + " from "
+                                                    + resp.request().uri().getPath());
+                                            res = completedWithIOException(s);
+                                            return res;
+                                        } else {
+                                            int counter = COUNT.incrementAndGet();
+                                            System.out.println(now + "Result (" + counter + ") from "
+                                                    + resp.request().uri().getPath());
+                                        }
+                                        res = CompletableFuture.completedStage(resp.body())
+                                                .thenApply((b) -> new Pair<>(resp, b));
+                                        return res;
+                                    } else {
+                                        int counter = COUNT.incrementAndGet();
+                                        System.out.println(now + "Result (" + counter + ") from "
+                                                + r.uri().getPath()
+                                                + failure(t));
+                                        res = CompletableFuture.failedFuture(t);
+                                        return res;
+                                    }
+                                })
+                                .thenCompose(c -> c)
+                                .thenAccept((pair) -> {
+                                    HttpRequest request = pair.t.request();
+                                    byte[] requestBody = bodies.get(request);
+                                    check(Arrays.equals(requestBody, pair.u),
+                                            "bodies not equal:[" + bytesToHexString(requestBody)
+                                                    + "] [" + bytesToHexString(pair.u) + "]");
 
-        // wait for them all to complete and throw exception in case of error
-        CompletableFuture.allOf(results).join();
+                                });
+            }
+
+            // wait for them all to complete and throw exception in case of err
+            try {
+                CompletableFuture.allOf(results).join();
+                done = true;
+            } catch (CompletionException e) {
+                if (!Platform.isWindows()) throw e;
+                if (LIMIT.get() < REQUESTS) throw e;
+                Throwable cause = e;
+                while ((cause = cause.getCause()) != null) {
+                    if (cause instanceof ConnectException) {
+                        // try again, limit concurrency by half
+                        COUNT.set(0);
+                        LIMIT.set(REQUESTS/2);
+                        System.out.println("*** Retrying due to " + cause);
+                        continue LOOP;
+                    }
+                }
+                throw e;
+            }
+        } while (!done);
+
     }
 
     static <T> CompletableFuture<T> completedWithIOException(String message) {
@@ -213,13 +295,7 @@
         return sb.toString();
     }
 
-    static final class Pair<T,U> {
-        Pair(T t, U u) {
-            this.t = t; this.u = u;
-        }
-        T t;
-        U u;
-    }
+    record Pair<T,U>(T t, U u) { }
 
     /**
      * A simple limiter for controlling the number of requests to be run in
diff --git a/test/jdk/java/net/httpclient/ManyRequests2.java b/test/jdk/java/net/httpclient/ManyRequests2.java
index b0eee6e..49e7f75 100644
--- a/test/jdk/java/net/httpclient/ManyRequests2.java
+++ b/test/jdk/java/net/httpclient/ManyRequests2.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,10 +33,14 @@
  * @compile ../../../com/sun/net/httpserver/EchoHandler.java
  * @compile ../../../com/sun/net/httpserver/FileServerHandler.java
  * @build ManyRequests ManyRequests2
- * @run main/othervm/timeout=40 -Dtest.XFixed=true ManyRequests2
- * @run main/othervm/timeout=40 -Dtest.XFixed=true -Dtest.insertDelay=true ManyRequests2
- * @run main/othervm/timeout=40 -Dtest.XFixed=true -Dtest.chunkSize=64 ManyRequests2
+ * @run main/othervm/timeout=40 -Dtest.XFixed=true
+ *                              -Djdk.httpclient.HttpClient.log=channel ManyRequests2
+ * @run main/othervm/timeout=40 -Dtest.XFixed=true -Dtest.insertDelay=true
+ *                              -Djdk.httpclient.HttpClient.log=channel ManyRequests2
+ * @run main/othervm/timeout=40 -Dtest.XFixed=true -Dtest.chunkSize=64
+ *                              -Djdk.httpclient.HttpClient.log=channel ManyRequests2
  * @run main/othervm/timeout=40 -Djdk.internal.httpclient.debug=true
+ *                              -Djdk.httpclient.HttpClient.log=channel
  *                              -Dtest.XFixed=true -Dtest.insertDelay=true
  *                              -Dtest.chunkSize=64 ManyRequests2
  * @summary Send a large number of requests asynchronously.
diff --git a/test/jdk/java/net/httpclient/ManyRequestsLegacy.java b/test/jdk/java/net/httpclient/ManyRequestsLegacy.java
index b8d2960..010c04c 100644
--- a/test/jdk/java/net/httpclient/ManyRequestsLegacy.java
+++ b/test/jdk/java/net/httpclient/ManyRequestsLegacy.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,10 +31,10 @@
  * @compile ../../../com/sun/net/httpserver/LogFilter.java
  * @compile ../../../com/sun/net/httpserver/EchoHandler.java
  * @compile ../../../com/sun/net/httpserver/FileServerHandler.java
- * @run main/othervm/timeout=40 ManyRequestsLegacy
- * @run main/othervm/timeout=40 -Dtest.insertDelay=true ManyRequestsLegacy
- * @run main/othervm/timeout=40 -Dtest.chunkSize=64 ManyRequestsLegacy
- * @run main/othervm/timeout=40 -Dtest.insertDelay=true
+ * @run main/othervm/timeout=80 -Dsun.net.httpserver.idleInterval=50000 ManyRequestsLegacy
+ * @run main/othervm/timeout=80 -Dtest.insertDelay=true -Dsun.net.httpserver.idleInterval=50000 ManyRequestsLegacy
+ * @run main/othervm/timeout=80 -Dtest.chunkSize=64 -Dsun.net.httpserver.idleInterval=50000 ManyRequestsLegacy
+ * @run main/othervm/timeout=80 -Dtest.insertDelay=true -Dsun.net.httpserver.idleInterval=50000
  *                              -Dtest.chunkSize=64 ManyRequestsLegacy
  * @summary Send a large number of requests asynchronously using the legacy
  *          URL.openConnection(), to help sanitize results of the test
@@ -43,6 +43,7 @@
 
 import javax.net.ssl.HttpsURLConnection;
 import javax.net.ssl.HostnameVerifier;
+
 import com.sun.net.httpserver.HttpsConfigurator;
 import com.sun.net.httpserver.HttpsParameters;
 import com.sun.net.httpserver.HttpsServer;
@@ -50,12 +51,18 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.net.ConnectException;
 import java.net.HttpURLConnection;
 import java.net.InetAddress;
 import java.net.URI;
 import java.net.URLConnection;
+import java.util.Map;
 import java.util.Optional;
 import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionException;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.stream.Collectors;
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLSession;
@@ -73,12 +80,20 @@
 import java.util.Random;
 import java.util.logging.Logger;
 import java.util.logging.Level;
+
+import jdk.test.lib.Platform;
+import jdk.test.lib.RandomFactory;
 import jdk.test.lib.net.SimpleSSLContext;
 import static java.net.Proxy.NO_PROXY;
 
 public class ManyRequestsLegacy {
 
-    volatile static int counter = 0;
+    static final int MAX_COUNT = 20;
+    static final int MAX_LIMIT = 40;
+    static final AtomicInteger COUNT = new AtomicInteger();
+    static final AtomicInteger LIMIT = new AtomicInteger(MAX_LIMIT);
+    static final Random RANDOM = RandomFactory.getRandom();
+
 
     public static void main(String[] args) throws Exception {
         Logger logger = Logger.getLogger("com.sun.net.httpserver");
@@ -110,7 +125,7 @@
     }
 
     //static final int REQUESTS = 1000;
-    static final int REQUESTS = 20;
+    static final int REQUESTS = MAX_COUNT;
     static final boolean INSERT_DELAY = Boolean.getBoolean("test.insertDelay");
     static final int CHUNK_SIZE = Math.max(0,
            Integer.parseInt(System.getProperty("test.chunkSize", "0")));
@@ -194,7 +209,7 @@
     }
 
     static class TestEchoHandler extends EchoHandler {
-        final Random rand = new Random();
+        final Random rand = RANDOM;
         @Override
         public void handle(HttpExchange e) throws IOException {
             System.out.println("Server: received " + e.getRequestURI());
@@ -220,60 +235,119 @@
         }
     }
 
+    static String now(long start) {
+        long elapsed = System.nanoTime() - start;
+        long ms = elapsed / 1000_000L;
+        long s = ms / 1000L;
+        if (s == 0) return ms + "ms: ";
+        return s + "s, " + (ms - s * 1000L) + "ms: ";
+    }
+
+    static String failure(Throwable t) {
+        String s = "\n\t failed: " + t;
+        for (t = t.getCause(); t != null ; t = t.getCause()) {
+            s = s + "\n\t\t  Caused by: " + t;
+        }
+        return s;
+    }
+
     static void test(HttpsServer server, LegacyHttpClient client) throws Exception {
         int port = server.getAddress().getPort();
         URI baseURI = new URI("https://localhost:" + port + "/foo/x");
         server.createContext("/foo", new TestEchoHandler());
         server.start();
 
-        RequestLimiter limiter = new RequestLimiter(40);
-        Random rand = new Random();
-        CompletableFuture<?>[] results = new CompletableFuture<?>[REQUESTS];
-        HashMap<HttpRequest,byte[]> bodies = new HashMap<>();
+        // This loop implements a retry mechanism to work around an issue
+        // on some systems (observed on Windows 10) that seem to be trying to
+        // throttle the number of connections that can be made concurrently by
+        // rejecting connection attempts.
+        // On the first iteration of this loop, we will attempt 20 concurrent
+        // requests. If this fails with ConnectException, we will retry the
+        // 20 requests, but limiting the concurrency to 10 (LIMIT <- 10).
+        // If this fails again, the test will fail.
+        boolean done = false;
+        LOOP: do {
+            RequestLimiter limiter = new RequestLimiter(LIMIT.get());
+            Random rand = RANDOM;
+            CompletableFuture<?>[] results = new CompletableFuture<?>[REQUESTS];
+            Map<HttpRequest,byte[]> bodies = new ConcurrentHashMap<>();
+            long start = System.nanoTime();
 
-        for (int i=0; i<REQUESTS; i++) {
-            byte[] buf = new byte[(i+1)*CHUNK_SIZE+i+1];  // different size bodies
-            rand.nextBytes(buf);
-            URI uri = new URI(baseURI.toString() + String.valueOf(i+1));
-            HttpRequest r = HttpRequest.newBuilder(uri)
-                                       .header("XFixed", "true")
-                                       .POST(BodyPublishers.ofByteArray(buf))
-                                       .build();
-            bodies.put(r, buf);
+            for (int i = 0; i < REQUESTS; i++) {
+                byte[] buf = new byte[(i + 1) * CHUNK_SIZE + i + 1];  // different size bodies
+                rand.nextBytes(buf);
+                URI uri = new URI(baseURI.toString() + String.valueOf(i + 1));
+                HttpRequest r = HttpRequest.newBuilder(uri)
+                        .header("XFixed", "true")
+                        .POST(BodyPublishers.ofByteArray(buf))
+                        .build();
+                bodies.put(r, buf);
 
-            results[i] =
-                limiter.whenOkToSend()
-                       .thenCompose((v) -> {
-                           System.out.println("Client: sendAsync: " + r.uri());
-                           return client.sendAsync(r, buf);
-                       })
-                       .thenCompose((resp) -> {
-                           limiter.requestComplete();
-                           if (resp.statusCode() != 200) {
-                               String s = "Expected 200, got: " + resp.statusCode();
-                               System.out.println(s + " from "
-                                                  + resp.request().uri().getPath());
-                               return completedWithIOException(s);
-                           } else {
-                               counter++;
-                               System.out.println("Result (" + counter + ") from "
-                                                   + resp.request().uri().getPath());
-                           }
-                           return CompletableFuture.completedStage(resp.body())
-                                      .thenApply((b) -> new Pair<>(resp, b));
-                       })
-                      .thenAccept((pair) -> {
-                          HttpRequest request = pair.t.request();
-                          byte[] requestBody = bodies.get(request);
-                          check(Arrays.equals(requestBody, pair.u),
-                                "bodies not equal:[" + bytesToHexString(requestBody)
-                                + "] [" + bytesToHexString(pair.u) + "]");
+                results[i] =
+                        limiter.whenOkToSend()
+                                .thenCompose((v) -> {
+                                    System.out.println("Client: sendAsync: " + r.uri());
+                                    return client.sendAsync(r, buf);
+                                })
+                                .handle((resp, t) -> {
+                                    limiter.requestComplete();
+                                    CompletionStage<Pair<HttpResponse<byte[]>, byte[]>> res;
+                                    String now = now(start);
+                                    if (t == null) {
+                                        if (resp.statusCode() != 200) {
+                                            String s = "Expected 200, got: " + resp.statusCode();
+                                            System.out.println(now + s + " from "
+                                                    + resp.request().uri().getPath());
+                                            res = completedWithIOException(s);
+                                            return res;
+                                        } else {
+                                            int counter = COUNT.incrementAndGet();
+                                            System.out.println(now + "Result (" + counter + ") from "
+                                                    + resp.request().uri().getPath());
+                                        }
+                                        res = CompletableFuture.completedStage(resp.body())
+                                                .thenApply((b) -> new Pair<>(resp, b));
+                                        return res;
+                                    } else {
+                                        int counter = COUNT.incrementAndGet();
+                                        System.out.println(now + "Result (" + counter + ") from "
+                                                + r.uri().getPath()
+                                                + failure(t));
+                                        res = CompletableFuture.failedFuture(t);
+                                        return res;
+                                    }
+                                })
+                                .thenCompose(c -> c)
+                                .thenAccept((pair) -> {
+                                    HttpRequest request = pair.t.request();
+                                    byte[] requestBody = bodies.get(request);
+                                    check(Arrays.equals(requestBody, pair.u),
+                                            "bodies not equal:[" + bytesToHexString(requestBody)
+                                                    + "] [" + bytesToHexString(pair.u) + "]");
 
-                      });
-        }
+                                });
+            }
 
-        // wait for them all to complete and throw exception in case of error
-        CompletableFuture.allOf(results).join();
+            try {
+                // wait for them all to complete and throw exception in case of error
+                CompletableFuture.allOf(results).join();
+                done = true;
+            } catch (CompletionException e) {
+                if (!Platform.isWindows()) throw e;
+                if (LIMIT.get() < REQUESTS) throw e;
+                Throwable cause = e;
+                while ((cause = cause.getCause()) != null) {
+                    if (cause instanceof ConnectException) {
+                        // try again, limit concurrency by half
+                        COUNT.set(0);
+                        LIMIT.set(REQUESTS/2);
+                        System.out.println("*** Retrying due to " + cause);
+                        continue LOOP;
+                    }
+                }
+                throw e;
+            }
+        } while (!done);
     }
 
     static <T> CompletableFuture<T> completedWithIOException(String message) {
@@ -294,13 +368,7 @@
         return sb.toString();
     }
 
-    static final class Pair<T,U> {
-        Pair(T t, U u) {
-            this.t = t; this.u = u;
-        }
-        T t;
-        U u;
-    }
+    record Pair<T,U>(T t, U u) { }
 
     /**
      * A simple limiter for controlling the number of requests to be run in
diff --git a/test/jdk/java/net/httpclient/PathSubscriber/ofFile.policy b/test/jdk/java/net/httpclient/PathSubscriber/ofFile.policy
index c5df09a..de879fe 100644
--- a/test/jdk/java/net/httpclient/PathSubscriber/ofFile.policy
+++ b/test/jdk/java/net/httpclient/PathSubscriber/ofFile.policy
@@ -45,19 +45,29 @@
     permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.net.http.hpack";
     permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www.http";
 
-    permission java.net.SocketPermission "localhost:*", "accept,resolve";
+    permission java.net.SocketPermission "127.0.0.1:*", "accept,resolve";
+    permission java.net.SocketPermission "[::1]:*", "accept,resolve";
     permission java.lang.RuntimePermission "modifyThread";
 };
 
 grant codeBase "file:${test.classes}/*" {
-    permission java.net.URLPermission "http://localhost:*/http1/echo", "POST";
-    permission java.net.URLPermission "https://localhost:*/https1/echo", "POST";
-    permission java.net.URLPermission "http://localhost:*/http2/echo", "POST";
-    permission java.net.URLPermission "https://localhost:*/https2/echo", "POST";
-    permission java.net.URLPermission "https://localhost:*/http1/echo", "GET";
-    permission java.net.URLPermission "https://localhost:*/https1/echo", "GET";
-    permission java.net.URLPermission "http://localhost:*/http2/echo", "GET";
-    permission java.net.URLPermission "https://localhost:*/https2/echo", "GET";
+    permission java.net.URLPermission "http://127.0.0.1:*/http1/echo", "POST";
+    permission java.net.URLPermission "https://127.0.0.1:*/https1/echo", "POST";
+    permission java.net.URLPermission "http://127.0.0.1:*/http2/echo", "POST";
+    permission java.net.URLPermission "https://127.0.0.1:*/https2/echo", "POST";
+    permission java.net.URLPermission "https://127.0.0.1:*/http1/echo", "GET";
+    permission java.net.URLPermission "https://127.0.0.1:*/https1/echo", "GET";
+    permission java.net.URLPermission "http://127.0.0.1:*/http2/echo", "GET";
+    permission java.net.URLPermission "https://127.0.0.1:*/https2/echo", "GET";
+    // ipv6
+    permission java.net.URLPermission "http://[::1]:*/http1/echo", "POST";
+    permission java.net.URLPermission "https://[::1]:*/https1/echo", "POST";
+    permission java.net.URLPermission "http://[::1]:*/http2/echo", "POST";
+    permission java.net.URLPermission "https://[::1]:*/https2/echo", "POST";
+    permission java.net.URLPermission "https://[::1]:*/http1/echo", "GET";
+    permission java.net.URLPermission "https://[::1]:*/https1/echo", "GET";
+    permission java.net.URLPermission "http://[::1]:*/http2/echo", "GET";
+    permission java.net.URLPermission "https://[::1]:*/https2/echo", "GET";
 
     // file permissions for test files
     permission java.io.FilePermission "${user.dir}${/}defaultFile.txt", "read,write,delete";
@@ -77,7 +87,8 @@
     permission java.util.logging.LoggingPermission "control";
 
     // needed to grant the HTTP servers
-    permission java.net.SocketPermission "localhost:*", "accept,resolve";
+    permission java.net.SocketPermission "127.0.0.1:*", "accept,resolve";
+    permission java.net.SocketPermission "[::1]:*", "accept,resolve";
 
     permission java.util.PropertyPermission "*", "read";
     permission java.lang.RuntimePermission "modifyThread";
diff --git a/test/jdk/java/net/httpclient/PathSubscriber/ofFileDownload.policy b/test/jdk/java/net/httpclient/PathSubscriber/ofFileDownload.policy
index a9dc881..3406838 100644
--- a/test/jdk/java/net/httpclient/PathSubscriber/ofFileDownload.policy
+++ b/test/jdk/java/net/httpclient/PathSubscriber/ofFileDownload.policy
@@ -45,19 +45,29 @@
     permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.net.http.hpack";
     permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www.http";
 
-    permission java.net.SocketPermission "localhost:*", "accept,resolve";
+    permission java.net.SocketPermission "127.0.0.1:*", "accept,resolve";
+    permission java.net.SocketPermission "[::1]:*", "accept,resolve";
     permission java.lang.RuntimePermission "modifyThread";
 };
 
 grant codeBase "file:${test.classes}/*" {
-    permission java.net.URLPermission "http://localhost:*/http1/echo", "POST";
-    permission java.net.URLPermission "https://localhost:*/https1/echo", "POST";
-    permission java.net.URLPermission "http://localhost:*/http2/echo", "POST";
-    permission java.net.URLPermission "https://localhost:*/https2/echo", "POST";
-    permission java.net.URLPermission "https://localhost:*/http1/echo", "GET";
-    permission java.net.URLPermission "https://localhost:*/https1/echo", "GET";
-    permission java.net.URLPermission "http://localhost:*/http2/echo", "GET";
-    permission java.net.URLPermission "https://localhost:*/https2/echo", "GET";
+    permission java.net.URLPermission "http://127.0.0.1:*/http1/echo", "POST";
+    permission java.net.URLPermission "https://127.0.0.1:*/https1/echo", "POST";
+    permission java.net.URLPermission "http://127.0.0.1:*/http2/echo", "POST";
+    permission java.net.URLPermission "https://127.0.0.1:*/https2/echo", "POST";
+    permission java.net.URLPermission "https://127.0.0.1:*/http1/echo", "GET";
+    permission java.net.URLPermission "https://127.0.0.1:*/https1/echo", "GET";
+    permission java.net.URLPermission "http://127.0.0.1:*/http2/echo", "GET";
+    permission java.net.URLPermission "https://127.0.0.1:*/https2/echo", "GET";
+    // ipv6
+    permission java.net.URLPermission "http://[::1]:*/http1/echo", "POST";
+    permission java.net.URLPermission "https://[::1]:*/https1/echo", "POST";
+    permission java.net.URLPermission "http://[::1]:*/http2/echo", "POST";
+    permission java.net.URLPermission "https://[::1]:*/https2/echo", "POST";
+    permission java.net.URLPermission "https://[::1]:*/http1/echo", "GET";
+    permission java.net.URLPermission "https://[::1]:*/https1/echo", "GET";
+    permission java.net.URLPermission "http://[::1]:*/http2/echo", "GET";
+    permission java.net.URLPermission "https://[::1]:*/https2/echo", "GET";
 
     // file permissions for test files
     permission java.io.FilePermission "${user.dir}${/}file.zip", "read,write";
@@ -74,7 +84,8 @@
     permission java.util.logging.LoggingPermission "control";
 
     // needed to grant the HTTP servers
-    permission java.net.SocketPermission "localhost:*", "accept,resolve";
+    permission java.net.SocketPermission "127.0.0.1:*", "accept,resolve";
+    permission java.net.SocketPermission "[::1]:*", "accept,resolve";
 
     permission java.util.PropertyPermission "*", "read";
     permission java.lang.RuntimePermission "modifyThread";
diff --git a/test/jdk/java/net/httpclient/RequestBodyTest.java b/test/jdk/java/net/httpclient/RequestBodyTest.java
index b323efd..805a5b49 100644
--- a/test/jdk/java/net/httpclient/RequestBodyTest.java
+++ b/test/jdk/java/net/httpclient/RequestBodyTest.java
@@ -21,24 +21,6 @@
  * questions.
  */
 
-/*
- * @test
- * @bug 8087112
- * @modules java.net.http
- *          java.logging
- *          jdk.httpserver
- * @library /test/lib
- * @compile ../../../com/sun/net/httpserver/LogFilter.java
- * @compile ../../../com/sun/net/httpserver/EchoHandler.java
- * @compile ../../../com/sun/net/httpserver/FileServerHandler.java
- * @build jdk.test.lib.net.SimpleSSLContext
- * @build LightWeightHttpServer
- * @build jdk.test.lib.Platform
- * @build jdk.test.lib.util.FileUtils
- * @run testng/othervm RequestBodyTest
- * @run testng/othervm/java.security.policy=RequestBodyTest.policy RequestBodyTest
- */
-
 import java.io.*;
 import java.net.URI;
 import java.net.http.HttpClient;
@@ -74,6 +56,23 @@
 import org.testng.annotations.Test;
 import static org.testng.Assert.*;
 
+/*
+ * @test
+ * @bug 8087112
+ * @modules java.net.http
+ *          java.logging
+ *          jdk.httpserver
+ * @library /test/lib
+ * @compile ../../../com/sun/net/httpserver/LogFilter.java
+ * @compile ../../../com/sun/net/httpserver/EchoHandler.java
+ * @compile ../../../com/sun/net/httpserver/FileServerHandler.java
+ * @build jdk.test.lib.net.SimpleSSLContext
+ * @build LightWeightHttpServer
+ * @build jdk.test.lib.Platform
+ * @build jdk.test.lib.util.FileUtils
+ * @run testng/othervm RequestBodyTest
+ * @run testng/othervm/java.security.policy=RequestBodyTest.policy RequestBodyTest
+ */
 public class RequestBodyTest {
 
     static final String fileroot = System.getProperty("test.src", ".") + "/docs";
diff --git a/test/jdk/java/net/httpclient/RequestBodyTest.policy b/test/jdk/java/net/httpclient/RequestBodyTest.policy
index d3797cf..0bfedf2 100644
--- a/test/jdk/java/net/httpclient/RequestBodyTest.policy
+++ b/test/jdk/java/net/httpclient/RequestBodyTest.policy
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 //
 // This code is free software; you can redistribute it and/or modify it
@@ -38,14 +38,17 @@
     permission java.io.FilePermission "${test.src}${/}docs${/}files${/}notsobigfile.txt", "read";
     permission java.io.FilePermission "RequestBodyTest.tmp", "read,write,delete";
 
-    permission java.net.URLPermission "http://localhost:*/echo/foo",   "POST";
-    permission java.net.URLPermission "https://localhost:*/echo/foo",  "POST";
+    permission java.net.URLPermission "http://127.0.0.1:*/echo/foo",   "POST";
+    permission java.net.URLPermission "https://127.0.0.1:*/echo/foo",  "POST";
+    permission java.net.URLPermission "http://[::1]:*/echo/foo",   "POST";
+    permission java.net.URLPermission "https://[::1]:*/echo/foo",  "POST";
 
     // for HTTP/1.1 server logging
     permission java.util.logging.LoggingPermission "control";
 
     // needed to grant the HTTP server
-    permission java.net.SocketPermission "localhost:*", "accept,resolve";
+    permission java.net.SocketPermission "127.0.0.1:*", "accept,resolve";
+    permission java.net.SocketPermission "[::1]:*", "accept,resolve";
 
     permission java.util.PropertyPermission "*", "read";
     permission java.lang.RuntimePermission "modifyThread";
diff --git a/test/jdk/java/net/httpclient/Response204V2Test.java b/test/jdk/java/net/httpclient/Response204V2Test.java
index 7711ba3..869fe7d 100644
--- a/test/jdk/java/net/httpclient/Response204V2Test.java
+++ b/test/jdk/java/net/httpclient/Response204V2Test.java
@@ -291,7 +291,7 @@
                 sharedClient == null ? null : sharedClient.toString();
         sharedClient = null;
         Thread.sleep(100);
-        AssertionError fail = TRACKER.check(500);
+        AssertionError fail = TRACKER.check(5000);
         try {
             http2TestServer.stop();
             https2TestServer.stop();
diff --git a/test/jdk/java/net/httpclient/SpecialHeadersTest.java b/test/jdk/java/net/httpclient/SpecialHeadersTest.java
index abfd997..da9e964 100644
--- a/test/jdk/java/net/httpclient/SpecialHeadersTest.java
+++ b/test/jdk/java/net/httpclient/SpecialHeadersTest.java
@@ -35,6 +35,7 @@
  * @library /test/lib http2/server
  * @build Http2TestServer HttpServerAdapters SpecialHeadersTest
  * @build jdk.test.lib.net.SimpleSSLContext
+ * @requires (vm.compMode != "Xcomp")
  * @run testng/othervm
  *       -Djdk.httpclient.HttpClient.log=requests,headers,errors
  *       SpecialHeadersTest
diff --git a/test/jdk/java/net/httpclient/dependent.policy b/test/jdk/java/net/httpclient/dependent.policy
index 2396a11..a7562f4 100644
--- a/test/jdk/java/net/httpclient/dependent.policy
+++ b/test/jdk/java/net/httpclient/dependent.policy
@@ -34,7 +34,8 @@
     permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.net.http.hpack";
     permission java.lang.RuntimePermission "accessClassInPackage.sun.net.www.http";
 
-    permission java.net.SocketPermission "localhost:*", "listen,accept,resolve";
+    permission java.net.SocketPermission "127.0.0.1:*", "listen,accept,resolve";
+    permission java.net.SocketPermission "[::1]:*", "listen,accept,resolve";
     permission java.lang.RuntimePermission "modifyThread";
 };
 
@@ -42,11 +43,15 @@
     permission java.io.FilePermission "${user.dir}${/}asFileDownloadTest.tmp.dir", "read,write";
     permission java.io.FilePermission "${user.dir}${/}asFileDownloadTest.tmp.dir/-", "read,write";
 
-    permission java.net.URLPermission "http://localhost:*/http1/-",   "GET,POST";
-    permission java.net.URLPermission "https://localhost:*/https1/-", "GET,POST";
-    permission java.net.URLPermission "http://localhost:*/http2/-",   "GET,POST";
-    permission java.net.URLPermission "https://localhost:*/https2/-", "GET,POST";
-
+    permission java.net.URLPermission "http://127.0.0.1:*/http1/-",   "GET,POST";
+    permission java.net.URLPermission "https://127.0.0.1:*/https1/-", "GET,POST";
+    permission java.net.URLPermission "http://127.0.0.1:*/http2/-",   "GET,POST";
+    permission java.net.URLPermission "https://127.0.0.1:*/https2/-", "GET,POST";
+    // ipv6
+    permission java.net.URLPermission "http://[::1]:*/http1/-",   "GET,POST";
+    permission java.net.URLPermission "https://[::1]:*/https1/-", "GET,POST";
+    permission java.net.URLPermission "http://[::1]:*/http2/-",   "GET,POST";
+    permission java.net.URLPermission "https://[::1]:*/https2/-", "GET,POST";
 
     // needed to grant permission to the HTTP/2 server
     permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.net.http.common";
@@ -58,7 +63,8 @@
     permission java.util.logging.LoggingPermission "control";
 
     // needed to grant the HTTP servers
-    permission java.net.SocketPermission "localhost:*", "listen,accept,resolve";
+    permission java.net.SocketPermission "127.0.0.1:*", "listen,accept,resolve";
+    permission java.net.SocketPermission "[::1]:*", "listen,accept,resolve";
 
     permission java.util.PropertyPermission "*", "read";
     permission java.lang.RuntimePermission "modifyThread";
diff --git a/test/jdk/java/net/httpclient/http2/ConnectionReuseTest.java b/test/jdk/java/net/httpclient/http2/ConnectionReuseTest.java
new file mode 100644
index 0000000..e60f203
--- /dev/null
+++ b/test/jdk/java/net/httpclient/http2/ConnectionReuseTest.java
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.net.InetSocketAddress;
+import java.net.URI;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
+import java.net.http.HttpResponse.BodyHandlers;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Stream;
+
+import javax.net.ssl.SSLContext;
+
+import jdk.test.lib.net.IPSupport;
+import jdk.test.lib.net.SimpleSSLContext;
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.Assumptions;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+import static java.net.http.HttpClient.Builder.NO_PROXY;
+import static java.net.http.HttpClient.Version.HTTP_2;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+/*
+ * @test
+ * @bug 8305906
+ * @summary verify that the HttpClient pools and reuses a connection for HTTP/2 requests
+ * @library /test/lib server/ ../
+ * @build jdk.test.lib.net.SimpleSSLContext HttpServerAdapters
+ *        ReferenceTracker jdk.test.lib.net.IPSupport
+ * @modules java.net.http/jdk.internal.net.http.common
+ *          java.net.http/jdk.internal.net.http.frame
+ *          java.net.http/jdk.internal.net.http.hpack
+ *          java.logging
+ *          java.base/sun.net.www.http
+ *          java.base/sun.net.www
+ *          java.base/sun.net
+ *
+ * @run junit/othervm ConnectionReuseTest
+ * @run junit/othervm -Djava.net.preferIPv6Addresses=true ConnectionReuseTest
+ */
+public class ConnectionReuseTest implements HttpServerAdapters {
+
+    private static SSLContext sslContext;
+    private static HttpTestServer http2_Server; // h2 server over HTTP
+    private static HttpTestServer https2_Server; // h2 server over HTTPS
+
+    @BeforeAll
+    public static void beforeAll() throws Exception {
+        if (IPSupport.preferIPv6Addresses()) {
+            IPSupport.printPlatformSupport(System.err); // for debug purposes
+            // this test is run with -Djava.net.preferIPv6Addresses=true, so skip (all) tests
+            // if IPv6 isn't supported on this host
+            Assumptions.assumeTrue(IPSupport.hasIPv6(), "Skipping tests - IPv6 is not supported");
+        }
+        sslContext = new SimpleSSLContext().get();
+        assertNotNull(sslContext, "Unexpected null sslContext");
+
+        http2_Server = HttpTestServer.of(
+                    new Http2TestServer("localhost", false, 0));
+        http2_Server.addHandler(new Handler(), "/");
+        http2_Server.start();
+        System.out.println("Started HTTP v2 server at " + http2_Server.serverAuthority());
+
+        https2_Server = HttpTestServer.of(
+                    new Http2TestServer("localhost", true, sslContext));
+        https2_Server.addHandler(new Handler(), "/");
+        https2_Server.start();
+        System.out.println("Started HTTPS v2 server at " + https2_Server.serverAuthority());
+    }
+
+    @AfterAll
+    public static void afterAll() {
+        if (https2_Server != null) {
+            System.out.println("Stopping server " + https2_Server);
+            https2_Server.stop();
+        }
+        if (http2_Server != null) {
+            System.out.println("Stopping server " + http2_Server);
+            http2_Server.stop();
+        }
+    }
+
+    private static Stream<Arguments> requestURIs() throws Exception {
+        final List<Arguments> arguments = new ArrayList<>();
+        // h2 over HTTPS
+        arguments.add(Arguments.of(new URI("https://" + https2_Server.serverAuthority() + "/")));
+        // h2 over HTTP
+        arguments.add(Arguments.of(new URI("http://" + http2_Server.serverAuthority() + "/")));
+        if (IPSupport.preferIPv6Addresses()) {
+            if (http2_Server.getAddress().getAddress().isLoopbackAddress()) {
+                // h2 over HTTP, use the short form of the host, in the request URI
+                arguments.add(Arguments.of(new URI("http://[::1]:" +
+                        http2_Server.getAddress().getPort() + "/")));
+            }
+        }
+        return arguments.stream();
+    }
+
+    /**
+     * Uses a single instance of a HttpClient and issues multiple requests to {@code requestURI}
+     * and expects that each of the request internally uses the same connection
+     */
+    @ParameterizedTest
+    @MethodSource("requestURIs")
+    public void testConnReuse(final URI requestURI) throws Throwable {
+        final HttpClient.Builder builder = HttpClient.newBuilder()
+                .proxy(NO_PROXY).sslContext(sslContext);
+        final HttpRequest req = HttpRequest.newBuilder().uri(requestURI)
+                .GET().version(HTTP_2).build();
+        final ReferenceTracker tracker = ReferenceTracker.INSTANCE;
+        Throwable testFailure = null;
+        HttpClient client = tracker.track(builder.build());
+        try {
+            String clientConnAddr = null;
+            for (int i = 1; i <= 5; i++) {
+                System.out.println("Issuing request(" + i + ") " + req);
+                final HttpResponse<String> resp = client.send(req, BodyHandlers.ofString());
+                assertEquals(200, resp.statusCode(), "unexpected response code");
+                final String respBody = resp.body();
+                System.out.println("Server side handler responded to a request from " + respBody);
+                assertNotEquals(Handler.UNKNOWN_CLIENT_ADDR, respBody,
+                        "server handler couldn't determine client address in request");
+                if (i == 1) {
+                    // for the first request we just keep track of the client connection address
+                    // that got used for this request
+                    clientConnAddr = respBody;
+                } else {
+                    // verify that the client connection used to issue the request is the same
+                    // as the previous request's client connection
+                    assertEquals(clientConnAddr, respBody, "HttpClient unexpectedly used a" +
+                            " different connection for request(" + i + ")");
+                }
+            }
+        } catch (Throwable t) {
+            testFailure = t;
+        } finally {
+            // dereference the client to allow the tracker to verify the resources
+            // have been released
+            client = null;
+            // wait for the client to be shutdown
+            final AssertionError trackerFailure = tracker.check(2000);
+            if (testFailure != null) {
+                if (trackerFailure != null) {
+                    // add the failure reported by the tracker as a suppressed
+                    // exception and throw the original test failure
+                    testFailure.addSuppressed(trackerFailure);
+                }
+                throw testFailure;
+            }
+            if (trackerFailure != null) {
+                // the test itself didn't fail but the tracker check failed.
+                // fail the test with this exception
+                throw trackerFailure;
+            }
+        }
+    }
+
+    private static final class Handler implements HttpTestHandler {
+
+        private static final String UNKNOWN_CLIENT_ADDR = "unknown";
+
+        @Override
+        public void handle(final HttpTestExchange t) throws IOException {
+            final InetSocketAddress clientAddr = t.getRemoteAddress();
+            System.out.println("Handling request " + t.getRequestURI() + " from " + clientAddr);
+            // we write out the client address into the response body
+            final byte[] responseBody = clientAddr == null
+                    ? UNKNOWN_CLIENT_ADDR.getBytes(StandardCharsets.UTF_8)
+                    : clientAddr.toString().getBytes(StandardCharsets.UTF_8);
+            t.sendResponseHeaders(200, responseBody.length);
+            try (final OutputStream os = t.getResponseBody()) {
+                os.write(responseBody);
+            }
+        }
+    }
+}
diff --git a/test/jdk/java/net/httpclient/http2/server/Http2TestServer.java b/test/jdk/java/net/httpclient/http2/server/Http2TestServer.java
index 33e5ade..ab756b5 100644
--- a/test/jdk/java/net/httpclient/http2/server/Http2TestServer.java
+++ b/test/jdk/java/net/httpclient/http2/server/Http2TestServer.java
@@ -81,8 +81,11 @@
     }
 
     public String serverAuthority() {
-        return InetAddress.getLoopbackAddress().getHostName() + ":"
-                + getAddress().getPort();
+        final InetSocketAddress inetSockAddr = getAddress();
+        final String hostIP = inetSockAddr.getAddress().getHostAddress();
+        // escape for ipv6
+        final String h = hostIP.contains(":") ? "[" + hostIP + "]" : hostIP;
+        return h + ":" + inetSockAddr.getPort();
     }
 
     public Http2TestServer(boolean secure,
@@ -124,6 +127,20 @@
         this(serverName, secure, port, exec, backlog, properties, context, false);
     }
 
+    public Http2TestServer(String serverName,
+                           boolean secure,
+                           int port,
+                           ExecutorService exec,
+                           int backlog,
+                           Properties properties,
+                           SSLContext context,
+                           boolean supportsHTTP11)
+        throws Exception
+    {
+        this(InetAddress.getLoopbackAddress(), serverName, secure, port, exec,
+                backlog, properties, context, supportsHTTP11);
+    }
+
     /**
      * Create a Http2Server listening on the given port. Currently needs
      * to know in advance whether incoming connections are plain TCP "h2c"
@@ -134,6 +151,7 @@
      *       "X-Magic", "HTTP/1.1 request received by HTTP/2 server",
      *       "X-Received-Body", <the request body>);
      *
+     * @param localAddr local address to bind to
      * @param serverName SNI servername
      * @param secure https or http
      * @param port listen port
@@ -146,7 +164,8 @@
      *        connection without the h2 ALPN. Otherwise, false to operate in
      *        HTTP/2 mode exclusively.
      */
-    public Http2TestServer(String serverName,
+    public Http2TestServer(InetAddress localAddr,
+                           String serverName,
                            boolean secure,
                            int port,
                            ExecutorService exec,
@@ -163,7 +182,7 @@
                this.sslContext = context;
            else
                this.sslContext = SSLContext.getDefault();
-            server = initSecure(port, backlog);
+            server = initSecure(localAddr, port, backlog);
         } else {
             this.sslContext = context;
             server = initPlaintext(port, backlog);
@@ -236,14 +255,14 @@
     }
 
 
-    final ServerSocket initSecure(int port, int backlog) throws Exception {
+    final ServerSocket initSecure(InetAddress localAddr, int port, int backlog) throws Exception {
         ServerSocketFactory fac;
         SSLParameters sslp = null;
         fac = sslContext.getServerSocketFactory();
         sslp = sslContext.getSupportedSSLParameters();
         SSLServerSocket se = (SSLServerSocket) fac.createServerSocket();
         se.setReuseAddress(false);
-        se.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0), backlog);
+        se.bind(new InetSocketAddress(localAddr, 0), backlog);
         if (supportsHTTP11) {
             sslp.setApplicationProtocols(new String[]{"h2", "http/1.1"});
         } else {
diff --git a/test/jdk/java/net/httpclient/security/0.policy b/test/jdk/java/net/httpclient/security/0.policy
index 32a1e54..2e2b458 100644
--- a/test/jdk/java/net/httpclient/security/0.policy
+++ b/test/jdk/java/net/httpclient/security/0.policy
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 //
 // This code is free software; you can redistribute it and/or modify it
@@ -29,7 +29,8 @@
     permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete";
     permission java.lang.RuntimePermission "modifyThread";
     permission java.util.logging.LoggingPermission "control", "";
-    permission java.net.SocketPermission "localhost:1024-", "accept,listen";
+    permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen";
+    permission java.net.SocketPermission "[::1]:1024-", "accept,listen";
     permission java.io.FilePermission "${test.src}${/}docs${/}-", "read";
     permission java.lang.RuntimePermission "createClassLoader";
 
@@ -39,8 +40,8 @@
 
 // For proxy only. Not being tested
 grant codebase "file:${test.classes}/proxydir/-" {
-    permission java.net.SocketPermission "localhost:1024-", "accept,listen,connect";
-    permission java.net.SocketPermission "localhost:1024-", "connect,resolve";
+    permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen,connect,resolve";
+    permission java.net.SocketPermission "[::1]:1024-", "accept,listen,connect,resolve";
 };
 
 
diff --git a/test/jdk/java/net/httpclient/security/1.policy b/test/jdk/java/net/httpclient/security/1.policy
index 3c5d96d..ee9e021 100644
--- a/test/jdk/java/net/httpclient/security/1.policy
+++ b/test/jdk/java/net/httpclient/security/1.policy
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 //
 // This code is free software; you can redistribute it and/or modify it
@@ -28,17 +28,19 @@
     permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete";
     permission java.lang.RuntimePermission "modifyThread";
     permission java.util.logging.LoggingPermission "control", "";
-    permission java.net.SocketPermission "localhost:1024-", "accept,listen";
+    permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen";
+    permission java.net.SocketPermission "[::1]:1024-", "accept,listen";
     permission java.io.FilePermission "${test.src}${/}docs${/}-", "read";
     permission java.lang.RuntimePermission "createClassLoader";
 
 
     // permissions specific to this test
-    permission java.net.URLPermission "http://localhost:${port.number}/files/foo.txt", "GET";
+    permission java.net.URLPermission "http://127.0.0.1:${port.number}/files/foo.txt", "GET";
+    permission java.net.URLPermission "http://[::1]:${port.number}/files/foo.txt", "GET";
 };
 
 // For proxy only. Not being tested
 grant codebase "file:${test.classes}/proxydir/-" {
-    permission java.net.SocketPermission "localhost:1024-", "accept,listen,connect";
-    permission java.net.SocketPermission "localhost:1024-", "connect,resolve";
+    permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen,connect,resolve";
+    permission java.net.SocketPermission "[::1]:1024-", "accept,listen,connect,resolve";
 };
diff --git a/test/jdk/java/net/httpclient/security/10.policy b/test/jdk/java/net/httpclient/security/10.policy
index f131a44..a83bf44 100644
--- a/test/jdk/java/net/httpclient/security/10.policy
+++ b/test/jdk/java/net/httpclient/security/10.policy
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 //
 // This code is free software; you can redistribute it and/or modify it
@@ -28,16 +28,18 @@
     permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete";
     permission java.lang.RuntimePermission "modifyThread";
     permission java.util.logging.LoggingPermission "control", "";
-    permission java.net.SocketPermission "localhost:1024-", "accept,listen";
+    permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen";
+    permission java.net.SocketPermission "[::1]:1024-", "accept,listen";
     permission java.io.FilePermission "${test.src}${/}docs${/}-", "read";
     permission java.lang.RuntimePermission "createClassLoader";
 
     // permissions specific to this test
-    permission java.net.URLPermission "http://localhost:${port.number}/files/foo.txt", "GET:*";
+    permission java.net.URLPermission "http://127.0.0.1:${port.number}/files/foo.txt", "GET:*";
+    permission java.net.URLPermission "http://[::1]:${port.number}/files/foo.txt", "GET:*";
 };
 
 // For proxy only. Not being tested
 grant codebase "file:${test.classes}/proxydir/-" {
-    permission java.net.SocketPermission "localhost:1024-", "accept,listen,connect";
-    permission java.net.SocketPermission "localhost:1024-", "connect,resolve";
+    permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen,connect,resolve";
+    permission java.net.SocketPermission "[::1]:1024-", "accept,listen,connect,resolve";
 };
diff --git a/test/jdk/java/net/httpclient/security/11.policy b/test/jdk/java/net/httpclient/security/11.policy
index 51fee36..f75fdcc 100644
--- a/test/jdk/java/net/httpclient/security/11.policy
+++ b/test/jdk/java/net/httpclient/security/11.policy
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 //
 // This code is free software; you can redistribute it and/or modify it
@@ -28,18 +28,26 @@
     permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete";
     permission java.lang.RuntimePermission "modifyThread";
     permission java.util.logging.LoggingPermission "control", "";
-    permission java.net.SocketPermission "localhost:1024-", "accept,listen";
+    permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen";
+    permission java.net.SocketPermission "[::1]:1024-", "accept,listen";
     permission java.io.FilePermission "${test.src}${/}docs${/}-", "read";
     permission java.lang.RuntimePermission "createClassLoader";
 
     // permissions specific to this test
-    permission java.net.URLPermission "http://localhost:${port.number}/files/foo.txt", "GET:*";
+    permission java.net.URLPermission "http://127.0.0.1:${port.number}/files/foo.txt", "GET:*";
+    permission java.net.URLPermission "socket://127.0.0.1:${port.number1}", "CONNECT";
+    // ipv6
+    permission java.net.URLPermission "http://[::1]:${port.number}/files/foo.txt", "GET:*";
+    permission java.net.URLPermission "socket://[::1]:${port.number1}", "CONNECT";
+    // this specific test uses a proxy configured to loopback address. the httpclient implementation
+    // during permissions check uses the InetAddress.hostString() API which can return resolved
+    // hostname, so we use include a permission for "localhost" to cover that case too
     permission java.net.URLPermission "socket://localhost:${port.number1}", "CONNECT";
 };
 
 
 // For proxy only. Not being tested
 grant codebase "file:${test.classes}/proxydir/-" {
-    permission java.net.SocketPermission "localhost:1024-", "accept,listen,connect";
-    permission java.net.SocketPermission "localhost:1024-", "connect,resolve";
+    permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen,connect,resolve";
+    permission java.net.SocketPermission "[::1]:1024-", "accept,listen,connect,resolve";
 };
diff --git a/test/jdk/java/net/httpclient/security/12.policy b/test/jdk/java/net/httpclient/security/12.policy
index 51fee36..f75fdcc 100644
--- a/test/jdk/java/net/httpclient/security/12.policy
+++ b/test/jdk/java/net/httpclient/security/12.policy
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 //
 // This code is free software; you can redistribute it and/or modify it
@@ -28,18 +28,26 @@
     permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete";
     permission java.lang.RuntimePermission "modifyThread";
     permission java.util.logging.LoggingPermission "control", "";
-    permission java.net.SocketPermission "localhost:1024-", "accept,listen";
+    permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen";
+    permission java.net.SocketPermission "[::1]:1024-", "accept,listen";
     permission java.io.FilePermission "${test.src}${/}docs${/}-", "read";
     permission java.lang.RuntimePermission "createClassLoader";
 
     // permissions specific to this test
-    permission java.net.URLPermission "http://localhost:${port.number}/files/foo.txt", "GET:*";
+    permission java.net.URLPermission "http://127.0.0.1:${port.number}/files/foo.txt", "GET:*";
+    permission java.net.URLPermission "socket://127.0.0.1:${port.number1}", "CONNECT";
+    // ipv6
+    permission java.net.URLPermission "http://[::1]:${port.number}/files/foo.txt", "GET:*";
+    permission java.net.URLPermission "socket://[::1]:${port.number1}", "CONNECT";
+    // this specific test uses a proxy configured to loopback address. the httpclient implementation
+    // during permissions check uses the InetAddress.hostString() API which can return resolved
+    // hostname, so we use include a permission for "localhost" to cover that case too
     permission java.net.URLPermission "socket://localhost:${port.number1}", "CONNECT";
 };
 
 
 // For proxy only. Not being tested
 grant codebase "file:${test.classes}/proxydir/-" {
-    permission java.net.SocketPermission "localhost:1024-", "accept,listen,connect";
-    permission java.net.SocketPermission "localhost:1024-", "connect,resolve";
+    permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen,connect,resolve";
+    permission java.net.SocketPermission "[::1]:1024-", "accept,listen,connect,resolve";
 };
diff --git a/test/jdk/java/net/httpclient/security/14.policy b/test/jdk/java/net/httpclient/security/14.policy
index 0a6562b..39bdbea 100644
--- a/test/jdk/java/net/httpclient/security/14.policy
+++ b/test/jdk/java/net/httpclient/security/14.policy
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 //
 // This code is free software; you can redistribute it and/or modify it
@@ -28,17 +28,19 @@
     permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete";
     permission java.lang.RuntimePermission "modifyThread";
     permission java.util.logging.LoggingPermission "control", "";
-    permission java.net.SocketPermission "localhost:1024-", "accept,listen";
+    permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen";
+    permission java.net.SocketPermission "[::1]:1024-", "accept,listen";
     permission java.io.FilePermission "${test.src}${/}docs${/}-", "read";
     permission java.lang.RuntimePermission "createClassLoader";
 
 
     // permissions specific to this test
-    permission java.net.URLPermission "http://localhost:*/files/foo.txt", "GET";
+    permission java.net.URLPermission "http://127.0.0.1:*/files/foo.txt", "GET";
+    permission java.net.URLPermission "http://[::1]:*/files/foo.txt", "GET";
 };
 
 // For proxy only. Not being tested
 grant codebase "file:${test.classes}/proxydir/-" {
-    permission java.net.SocketPermission "localhost:1024-", "accept,listen,connect";
-    permission java.net.SocketPermission "localhost:1024-", "connect,resolve";
+    permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen,connect,resolve";
+    permission java.net.SocketPermission "[::1]:1024-", "accept,listen,connect,resolve";
 };
diff --git a/test/jdk/java/net/httpclient/security/15.policy b/test/jdk/java/net/httpclient/security/15.policy
index 6fa7a0d..ba6b9fe 100644
--- a/test/jdk/java/net/httpclient/security/15.policy
+++ b/test/jdk/java/net/httpclient/security/15.policy
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 //
 // This code is free software; you can redistribute it and/or modify it
@@ -28,12 +28,14 @@
     permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete";
     permission java.lang.RuntimePermission "modifyThread";
     permission java.util.logging.LoggingPermission "control", "";
-    permission java.net.SocketPermission "localhost:1024-", "accept,listen";
+    permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen";
+    permission java.net.SocketPermission "[::1]:1024-", "accept,listen";
     permission java.io.FilePermission "${test.src}${/}docs${/}-", "read";
     permission java.lang.RuntimePermission "createClassLoader";
 
     // permissions specific to this test
-    permission java.net.URLPermission "http://localhost:*/files/foo.txt", "GET:*";
+    permission java.net.URLPermission "http://127.0.0.1:*/files/foo.txt", "GET:*";
+    permission java.net.URLPermission "http://[::1]:*/files/foo.txt", "GET:*";
 
     // Test checks for this explicitly
     permission java.lang.RuntimePermission "foobar";
@@ -42,6 +44,6 @@
 
 // For proxy only. Not being tested
 grant codebase "file:${test.classes}/proxydir/-" {
-    permission java.net.SocketPermission "localhost:1024-", "accept,listen,connect";
-    permission java.net.SocketPermission "localhost:1024-", "connect,resolve";
+    permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen,connect,resolve";
+    permission java.net.SocketPermission "[::1]:1024-", "accept,listen,connect,resolve";
 };
diff --git a/test/jdk/java/net/httpclient/security/16.policy b/test/jdk/java/net/httpclient/security/16.policy
index 5d9939f..7d755cf 100644
--- a/test/jdk/java/net/httpclient/security/16.policy
+++ b/test/jdk/java/net/httpclient/security/16.policy
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 //
 // This code is free software; you can redistribute it and/or modify it
@@ -29,17 +29,19 @@
     permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete";
     permission java.lang.RuntimePermission "modifyThread";
     permission java.util.logging.LoggingPermission "control", "";
-    permission java.net.SocketPermission "localhost:1024-", "accept,listen";
+    permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen";
+    permission java.net.SocketPermission "[::1]:1024-", "accept,listen";
     permission java.io.FilePermission "${test.src}${/}docs${/}-", "read";
     permission java.lang.RuntimePermission "createClassLoader";
 
 
     // permissions specific to this test
-    permission java.net.URLPermission "http://localhost:${port.number}/files/foo.txt", "GET:Host";
+    permission java.net.URLPermission "http://127.0.0.1:${port.number}/files/foo.txt", "GET:Host";
+    permission java.net.URLPermission "http://[::1]:${port.number}/files/foo.txt", "GET:Host";
 };
 
 // For proxy only. Not being tested
 grant codebase "file:${test.classes}/proxydir/-" {
-    permission java.net.SocketPermission "localhost:1024-", "accept,listen,connect";
-    permission java.net.SocketPermission "localhost:1024-", "connect,resolve";
+    permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen,connect,resolve";
+    permission java.net.SocketPermission "[::1]:1024-", "accept,listen,connect,resolve";
 };
diff --git a/test/jdk/java/net/httpclient/security/17.policy b/test/jdk/java/net/httpclient/security/17.policy
index ae26c85..92ee7f3 100644
--- a/test/jdk/java/net/httpclient/security/17.policy
+++ b/test/jdk/java/net/httpclient/security/17.policy
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 //
 // This code is free software; you can redistribute it and/or modify it
@@ -28,18 +28,20 @@
     permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete";
     permission java.lang.RuntimePermission "modifyThread";
     permission java.util.logging.LoggingPermission "control", "";
-    permission java.net.SocketPermission "localhost:1024-", "accept,listen";
+    permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen";
+    permission java.net.SocketPermission "[::1]:1024-", "accept,listen";
     permission java.io.FilePermission "${test.src}${/}docs${/}-", "read";
     permission java.lang.RuntimePermission "createClassLoader";
 
 
     // permissions specific to this test
-    permission java.net.URLPermission "http://localhost:${port.number}/files/foo.txt", "GET:Host";
+    permission java.net.URLPermission "http://127.0.0.1:${port.number}/files/foo.txt", "GET:Host";
+    permission java.net.URLPermission "http://[::1]:${port.number}/files/foo.txt", "GET:Host";
     permission java.net.URLPermission "http://foohost:123/files/foo.txt", "GET:Host";
 };
 
 // For proxy only. Not being tested
 grant codebase "file:${test.classes}/proxydir/-" {
-    permission java.net.SocketPermission "localhost:1024-", "accept,listen,connect";
-    permission java.net.SocketPermission "localhost:1024-", "connect,resolve";
+    permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen,connect,resolve";
+    permission java.net.SocketPermission "[::1]:1024-", "accept,listen,connect,resolve";
 };
diff --git a/test/jdk/java/net/httpclient/security/2.policy b/test/jdk/java/net/httpclient/security/2.policy
index 4d7f859..b69c589 100644
--- a/test/jdk/java/net/httpclient/security/2.policy
+++ b/test/jdk/java/net/httpclient/security/2.policy
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 //
 // This code is free software; you can redistribute it and/or modify it
@@ -28,17 +28,19 @@
     permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete";
     permission java.lang.RuntimePermission "modifyThread";
     permission java.util.logging.LoggingPermission "control", "";
-    permission java.net.SocketPermission "localhost:1024-", "accept,listen";
+    permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen";
+    permission java.net.SocketPermission "[::1]:1024-", "accept,listen";
     permission java.io.FilePermission "${test.src}${/}docs${/}-", "read";
     permission java.lang.RuntimePermission "createClassLoader";
 
 
     // permissions specific to this test
-    permission java.net.URLPermission "http://localhost:*/files/*", "GET";
+    permission java.net.URLPermission "http://127.0.0.1:*/files/*", "GET";
+    permission java.net.URLPermission "http://[::1]:*/files/*", "GET";
 };
 
 // For proxy only. Not being tested
 grant codebase "file:${test.classes}/proxydir/-" {
-    permission java.net.SocketPermission "localhost:1024-", "accept,listen,connect";
-    permission java.net.SocketPermission "localhost:1024-", "connect,resolve";
+    permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen,connect,resolve";
+    permission java.net.SocketPermission "[::1]:1024-", "accept,listen,connect,resolve";
 };
diff --git a/test/jdk/java/net/httpclient/security/3.policy b/test/jdk/java/net/httpclient/security/3.policy
index 8183784..32383fe 100644
--- a/test/jdk/java/net/httpclient/security/3.policy
+++ b/test/jdk/java/net/httpclient/security/3.policy
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 //
 // This code is free software; you can redistribute it and/or modify it
@@ -28,17 +28,19 @@
     permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete";
     permission java.lang.RuntimePermission "modifyThread";
     permission java.util.logging.LoggingPermission "control", "";
-    permission java.net.SocketPermission "localhost:1024-", "accept,listen";
+    permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen";
+    permission java.net.SocketPermission "[::1]:1024-", "accept,listen";
     permission java.io.FilePermission "${test.src}${/}docs${/}-", "read";
     permission java.lang.RuntimePermission "createClassLoader";
 
 
     // permissions specific to this test
-    permission java.net.URLPermission "http://localhost:*/redirect/foo.txt", "GET";
+    permission java.net.URLPermission "http://127.0.0.1:*/redirect/foo.txt", "GET";
+    permission java.net.URLPermission "http://[::1]:*/redirect/foo.txt", "GET";
 };
 
 // For proxy only. Not being tested
 grant codebase "file:${test.classes}/proxydir/-" {
-    permission java.net.SocketPermission "localhost:1024-", "accept,listen,connect";
-    permission java.net.SocketPermission "localhost:1024-", "connect,resolve";
+    permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen,connect,resolve";
+    permission java.net.SocketPermission "[::1]:1024-", "accept,listen,connect,resolve";
 };
diff --git a/test/jdk/java/net/httpclient/security/4.policy b/test/jdk/java/net/httpclient/security/4.policy
index 5ea9284..7973c76 100644
--- a/test/jdk/java/net/httpclient/security/4.policy
+++ b/test/jdk/java/net/httpclient/security/4.policy
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 //
 // This code is free software; you can redistribute it and/or modify it
@@ -28,18 +28,22 @@
     permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete";
     permission java.lang.RuntimePermission "modifyThread";
     permission java.util.logging.LoggingPermission "control", "";
-    permission java.net.SocketPermission "localhost:1024-", "accept,listen";
+    permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen";
+    permission java.net.SocketPermission "[::1]:1024-", "accept,listen";
     permission java.io.FilePermission "${test.src}${/}docs${/}-", "read";
     permission java.lang.RuntimePermission "createClassLoader";
 
 
     // permissions specific to this test
-    permission java.net.URLPermission "http://localhost:*/redirect/foo.txt", "GET";
-    permission java.net.URLPermission "http://localhost:*/redirect/bar.txt", "GET";
+    permission java.net.URLPermission "http://127.0.0.1:*/redirect/foo.txt", "GET";
+    permission java.net.URLPermission "http://127.0.0.1:*/redirect/bar.txt", "GET";
+    // ipv6
+    permission java.net.URLPermission "http://[::1]:*/redirect/foo.txt", "GET";
+    permission java.net.URLPermission "http://[::1]:*/redirect/bar.txt", "GET";
 };
 
 // For proxy only. Not being tested
 grant codebase "file:${test.classes}/proxydir/-" {
-    permission java.net.SocketPermission "localhost:1024-", "accept,listen,connect";
-    permission java.net.SocketPermission "localhost:1024-", "connect,resolve";
+    permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen,connect,resolve";
+    permission java.net.SocketPermission "[::1]:1024-", "accept,listen,connect,resolve";
 };
diff --git a/test/jdk/java/net/httpclient/security/5.policy b/test/jdk/java/net/httpclient/security/5.policy
index b20917a..0b480f9 100644
--- a/test/jdk/java/net/httpclient/security/5.policy
+++ b/test/jdk/java/net/httpclient/security/5.policy
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 //
 // This code is free software; you can redistribute it and/or modify it
@@ -28,17 +28,19 @@
     permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete";
     permission java.lang.RuntimePermission "modifyThread";
     permission java.util.logging.LoggingPermission "control", "";
-    permission java.net.SocketPermission "localhost:1024-", "accept,listen";
+    permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen";
+    permission java.net.SocketPermission "[::1]:1024-", "accept,listen";
     permission java.io.FilePermission "${test.src}${/}docs${/}-", "read";
     permission java.lang.RuntimePermission "createClassLoader";
 
 
     // permissions specific to this test
-    permission java.net.URLPermission "http://localhost:*/redirect/bar.txt", "GET";
+    permission java.net.URLPermission "http://127.0.0.1:*/redirect/bar.txt", "GET";
+    permission java.net.URLPermission "http://[::1]:*/redirect/bar.txt", "GET";
 };
 
 // For proxy only. Not being tested
 grant codebase "file:${test.classes}/proxydir/-" {
-    permission java.net.SocketPermission "localhost:1024-", "accept,listen,connect";
-    permission java.net.SocketPermission "localhost:1024-", "connect,resolve";
+    permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen,connect,resolve";
+    permission java.net.SocketPermission "[::1]:1024-", "accept,listen,connect,resolve";
 };
diff --git a/test/jdk/java/net/httpclient/security/6.policy b/test/jdk/java/net/httpclient/security/6.policy
index f535b51..80d2838 100644
--- a/test/jdk/java/net/httpclient/security/6.policy
+++ b/test/jdk/java/net/httpclient/security/6.policy
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 //
 // This code is free software; you can redistribute it and/or modify it
@@ -28,17 +28,19 @@
     permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete";
     permission java.lang.RuntimePermission "modifyThread";
     permission java.util.logging.LoggingPermission "control", "";
-    permission java.net.SocketPermission "localhost:1024-", "accept,listen";
+    permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen";
+    permission java.net.SocketPermission "[::1]:1024-", "accept,listen";
     permission java.io.FilePermission "${test.src}${/}docs${/}-", "read";
     permission java.lang.RuntimePermission "createClassLoader";
 
 
     // permissions specific to this test
-    permission java.net.URLPermission "http://localhost:*/files/foo.txt", "POST";
+    permission java.net.URLPermission "http://127.0.0.1:*/files/foo.txt", "POST";
+    permission java.net.URLPermission "http://[::1]:*/files/foo.txt", "POST";
 };
 
 // For proxy only. Not being tested
 grant codebase "file:${test.classes}/proxydir/-" {
-    permission java.net.SocketPermission "localhost:1024-", "accept,listen,connect";
-    permission java.net.SocketPermission "localhost:1024-", "connect,resolve";
+    permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen,connect,resolve";
+    permission java.net.SocketPermission "[::1]:1024-", "accept,listen,connect,resolve";
 };
diff --git a/test/jdk/java/net/httpclient/security/7.policy b/test/jdk/java/net/httpclient/security/7.policy
index 29564ef..8fddf36 100644
--- a/test/jdk/java/net/httpclient/security/7.policy
+++ b/test/jdk/java/net/httpclient/security/7.policy
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 //
 // This code is free software; you can redistribute it and/or modify it
@@ -28,17 +28,20 @@
     permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete";
     permission java.lang.RuntimePermission "modifyThread";
     permission java.util.logging.LoggingPermission "control", "";
-    permission java.net.SocketPermission "localhost:1024-", "accept,listen";
+    permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen";
+    permission java.net.SocketPermission "[::1]:1024-", "accept,listen";
     permission java.io.FilePermission "${test.src}${/}docs${/}-", "read";
     permission java.lang.RuntimePermission "createClassLoader";
 
 
     // permissions specific to this test
-    permission java.net.URLPermission "http://localhost:*/files/foo.txt", "GET:X-Bar";
+    permission java.net.URLPermission "http://127.0.0.1:*/files/foo.txt", "GET:X-Bar";
+    permission java.net.URLPermission "http://[::1]:*/files/foo.txt", "GET:X-Bar";
+
 };
 
 // For proxy only. Not being tested
 grant codebase "file:${test.classes}/proxydir/-" {
-    permission java.net.SocketPermission "localhost:1024-", "accept,listen,connect";
-    permission java.net.SocketPermission "localhost:1024-", "connect,resolve";
+    permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen,connect,resolve";
+    permission java.net.SocketPermission "[::1]:1024-", "accept,listen,connect,resolve";
 };
diff --git a/test/jdk/java/net/httpclient/security/8.policy b/test/jdk/java/net/httpclient/security/8.policy
index 7a2cd1b..4bc507b 100644
--- a/test/jdk/java/net/httpclient/security/8.policy
+++ b/test/jdk/java/net/httpclient/security/8.policy
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 //
 // This code is free software; you can redistribute it and/or modify it
@@ -28,17 +28,19 @@
     permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete";
     permission java.lang.RuntimePermission "modifyThread";
     permission java.util.logging.LoggingPermission "control", "";
-    permission java.net.SocketPermission "localhost:1024-", "accept,listen";
+    permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen";
+    permission java.net.SocketPermission "[::1]:1024-", "accept,listen";
     permission java.io.FilePermission "${test.src}${/}docs${/}-", "read";
     permission java.lang.RuntimePermission "createClassLoader";
 
 
     // permissions specific to this test
-    permission java.net.URLPermission "http://localhost:*/files/foo.txt", "GET:X-Foo1,X-Foo,X-Bar";
+    permission java.net.URLPermission "http://127.0.0.1:*/files/foo.txt", "GET:X-Foo1,X-Foo,X-Bar";
+    permission java.net.URLPermission "http://[::1]:*/files/foo.txt", "GET:X-Foo1,X-Foo,X-Bar";
 };
 
 // For proxy only. Not being tested
 grant codebase "file:${test.classes}/proxydir/-" {
-    permission java.net.SocketPermission "localhost:1024-", "accept,listen,connect";
-    permission java.net.SocketPermission "localhost:1024-", "connect,resolve";
+    permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen,connect,resolve";
+    permission java.net.SocketPermission "[::1]:1024-", "accept,listen,connect,resolve";
 };
diff --git a/test/jdk/java/net/httpclient/security/9.policy b/test/jdk/java/net/httpclient/security/9.policy
index 79cdee7..ce7336c 100644
--- a/test/jdk/java/net/httpclient/security/9.policy
+++ b/test/jdk/java/net/httpclient/security/9.policy
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 //
 // This code is free software; you can redistribute it and/or modify it
@@ -28,17 +28,19 @@
     permission java.io.FilePermission "${test.classes}${/}-", "read,write,delete";
     permission java.lang.RuntimePermission "modifyThread";
     permission java.util.logging.LoggingPermission "control", "";
-    permission java.net.SocketPermission "localhost:1024-", "accept,listen";
+    permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen";
+    permission java.net.SocketPermission "[::1]:1024-", "accept,listen";
     permission java.io.FilePermission "${test.src}${/}docs${/}-", "read";
     permission java.lang.RuntimePermission "createClassLoader";
 
 
     // permissions specific to this test
-    permission java.net.URLPermission "http://localhost:*/files/foo.txt", "GET:*";
+    permission java.net.URLPermission "http://127.0.0.1:*/files/foo.txt", "GET:*";
+    permission java.net.URLPermission "http://[::1]:*/files/foo.txt", "GET:*";
 };
 
 // For proxy only. Not being tested
 grant codebase "file:${test.classes}/proxydir/-" {
-    permission java.net.SocketPermission "localhost:1024-", "accept,listen,connect";
-    permission java.net.SocketPermission "localhost:1024-", "connect,resolve";
+    permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen,connect,resolve";
+    permission java.net.SocketPermission "[::1]:1024-", "accept,listen,connect,resolve";
 };
diff --git a/test/jdk/java/net/httpclient/security/Security.java b/test/jdk/java/net/httpclient/security/Security.java
index fc2fcd1..5e6566d 100644
--- a/test/jdk/java/net/httpclient/security/Security.java
+++ b/test/jdk/java/net/httpclient/security/Security.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -103,6 +103,7 @@
     static String httproot, fileuri, fileroot, redirectroot;
     static List<HttpClient> clients = new LinkedList<>();
     static URI uri;
+    static String serverAuthority;
 
     interface ThrowingRunnable { void run() throws Throwable; }
 
@@ -201,56 +202,56 @@
         return new TestAndResult[] {
             // (0) policy does not have permission for file. Should fail
             TestAndResult.of(true, () -> { // Policy 0
-                URI u = URI.create("http://localhost:" + port + "/files/foo.txt");
+                URI u = URI.create("http://" + serverAuthority + "/files/foo.txt");
                 HttpRequest request = HttpRequest.newBuilder(u).GET().build();
                 HttpResponse<?> response = client.send(request, ofString());
                 System.out.println("Received response:" + response);
             }),
             // (1) policy has permission for file URL
             TestAndResult.of(false, () -> { //Policy 1
-                URI u = URI.create("http://localhost:" + port + "/files/foo.txt");
+                URI u = URI.create("http://" + serverAuthority + "/files/foo.txt");
                 HttpRequest request = HttpRequest.newBuilder(u).GET().build();
                 HttpResponse<?> response = client.send(request, ofString());
                 System.out.println("Received response:" + response);
             }),
             // (2) policy has permission for all file URLs under /files
             TestAndResult.of(false, () -> { // Policy 2
-                URI u = URI.create("http://localhost:" + port + "/files/foo.txt");
+                URI u = URI.create("http://" + serverAuthority + "/files/foo.txt");
                 HttpRequest request = HttpRequest.newBuilder(u).GET().build();
                 HttpResponse<?> response = client.send(request, ofString());
                 System.out.println("Received response:" + response);
             }),
             // (3) policy has permission for first URL but not redirected URL
             TestAndResult.of(true, () -> { // Policy 3
-                URI u = URI.create("http://localhost:" + port + "/redirect/foo.txt");
+                URI u = URI.create("http://" + serverAuthority + "/redirect/foo.txt");
                 HttpRequest request = HttpRequest.newBuilder(u).GET().build();
                 HttpResponse<?> response = client.send(request, ofString());
                 System.out.println("Received response:" + response);
             }),
             // (4) policy has permission for both first URL and redirected URL
             TestAndResult.of(false, () -> { // Policy 4
-                URI u = URI.create("http://localhost:" + port + "/redirect/foo.txt");
+                URI u = URI.create("http://" + serverAuthority + "/redirect/foo.txt");
                 HttpRequest request = HttpRequest.newBuilder(u).GET().build();
                 HttpResponse<?> response = client.send(request, ofString());
                 System.out.println("Received response:" + response);
             }),
             // (5) policy has permission for redirected but not first URL
             TestAndResult.of(true, () -> { // Policy 5
-                URI u = URI.create("http://localhost:" + port + "/redirect/foo.txt");
+                URI u = URI.create("http://" + serverAuthority + "/redirect/foo.txt");
                 HttpRequest request = HttpRequest.newBuilder(u).GET().build();
                 HttpResponse<?> response = client.send(request, ofString());
                 System.out.println("Received response:" + response);
             }),
             // (6) policy has permission for file URL, but not method
             TestAndResult.of(true, () -> { //Policy 6
-                URI u = URI.create("http://localhost:" + port + "/files/foo.txt");
+                URI u = URI.create("http://" + serverAuthority + "/files/foo.txt");
                 HttpRequest request = HttpRequest.newBuilder(u).GET().build();
                 HttpResponse<?> response = client.send(request, ofString());
                 System.out.println("Received response:" + response);
             }),
             // (7) policy has permission for file URL, method, but not header
             TestAndResult.of(true, () -> { //Policy 7
-                URI u = URI.create("http://localhost:" + port + "/files/foo.txt");
+                URI u = URI.create("http://" + serverAuthority + "/files/foo.txt");
                 HttpRequest request = HttpRequest.newBuilder(u)
                                                  .header("X-Foo", "bar")
                                                  .GET()
@@ -260,7 +261,7 @@
             }),
             // (8) policy has permission for file URL, method and header
             TestAndResult.of(false, () -> { //Policy 8
-                URI u = URI.create("http://localhost:" + port + "/files/foo.txt");
+                URI u = URI.create("http://" + serverAuthority + "/files/foo.txt");
                 HttpRequest request = HttpRequest.newBuilder(u)
                                                  .header("X-Foo", "bar")
                                                  .GET()
@@ -270,7 +271,7 @@
             }),
             // (9) policy has permission for file URL, method and header
             TestAndResult.of(false, () -> { //Policy 9
-                URI u = URI.create("http://localhost:" + port + "/files/foo.txt");
+                URI u = URI.create("http://" + serverAuthority + "/files/foo.txt");
                 HttpRequest request = HttpRequest.newBuilder(u)
                                                  .headers("X-Foo", "bar", "X-Bar", "foo")
                                                  .GET()
@@ -292,7 +293,7 @@
             }),
             // (13) async version of test 0
             TestAndResult.of(true, () -> { // Policy 0
-                URI u = URI.create("http://localhost:" + port + "/files/foo.txt");
+                URI u = URI.create("http://" + serverAuthority + "/files/foo.txt");
                 HttpRequest request = HttpRequest.newBuilder(u).GET().build();
                 try {
                     HttpResponse<?> response = client.sendAsync(request, ofString()).get();
@@ -307,14 +308,14 @@
             }),
             // (14) async version of test 1
             TestAndResult.of(false, () -> { //Policy 1
-                URI u = URI.create("http://localhost:" + port + "/files/foo.txt");
+                URI u = URI.create("http://" + serverAuthority + "/files/foo.txt");
                 HttpRequest request = HttpRequest.newBuilder(u).GET().build();
                 try {
                     HttpResponse<?> response = client.sendAsync(request, ofString()).get();
                     System.out.println("Received response:" + response);
                 } catch (ExecutionException e) {
-                    if (e.getCause() instanceof SecurityException) {
-                        throw (SecurityException)e.getCause();
+                    if (e.getCause() instanceof SecurityException se) {
+                        throw se;
                     } else {
                         throw new RuntimeException(e);
                     }
@@ -323,7 +324,7 @@
             // (15) check that user provided unprivileged code running on a worker
             //      thread does not gain ungranted privileges.
             TestAndResult.of(true, () -> { //Policy 12
-                URI u = URI.create("http://localhost:" + port + "/files/foo.txt");
+                URI u = URI.create("http://" + serverAuthority + "/files/foo.txt");
                 HttpRequest request = HttpRequest.newBuilder(u).GET().build();
                 HttpResponse.BodyHandler<String> sth = ofString();
 
@@ -369,18 +370,18 @@
                     System.out.println("Received response:" + response);
                 } catch (CompletionException e) {
                     Throwable t = e.getCause();
-                    if (t instanceof SecurityException)
-                        throw (SecurityException)t;
+                    if (t instanceof SecurityException se)
+                        throw se;
                     else if ((t instanceof IOException)
-                              && (t.getCause() instanceof SecurityException))
-                        throw ((SecurityException)t.getCause());
+                              && (t.getCause() instanceof SecurityException se))
+                        throw se;
                     else
                         throw new RuntimeException(t);
                 }
             }),
             // (16) allowed to set Host header but does not have permission
             TestAndResult.of(true, () -> { //Policy 16
-                URI u = URI.create("http://localhost:" + port + "/files/foo.txt");
+                URI u = URI.create("http://" + serverAuthority + "/files/foo.txt");
                 HttpRequest request = HttpRequest.newBuilder(u)
                         .header("Host", "foohost:123")
                         .GET().build();
@@ -389,7 +390,7 @@
             }),
             // (17) allowed to set Host header and does have permission
             TestAndResult.of(false, () -> { //Policy 17
-                URI u = URI.create("http://localhost:" + port + "/files/foo.txt");
+                URI u = URI.create("http://" + serverAuthority + "/files/foo.txt");
                 HttpRequest request = HttpRequest.newBuilder(u)
                         .header("Host", "foohost:123")
                         .GET().build();
@@ -426,14 +427,13 @@
         }
         System.out.println("Proxy port, p:" + p);
 
-        InetSocketAddress addr = new InetSocketAddress(InetAddress.getLoopbackAddress(),
-                                                       p);
+        InetSocketAddress addr = new InetSocketAddress(InetAddress.getLoopbackAddress(), p);
         HttpClient cl = HttpClient.newBuilder()
                                     .proxy(ProxySelector.of(addr))
                                     .build();
         clients.add(cl);
 
-        URI u = URI.create("http://localhost:" + port + "/files/foo.txt");
+        URI u = URI.create("http://" + serverAuthority + "/files/foo.txt");
         HttpRequest request = HttpRequest.newBuilder(u)
                                          .headers("X-Foo", "bar", "X-Bar", "foo")
                                          .build();
@@ -498,13 +498,20 @@
                 throw new RuntimeException("Error wrong port");
             System.out.println("Port was assigned by Driver");
         }
-        System.out.println("HTTP server port = " + port);
-        httproot = "http://localhost:" + port + "/files/";
-        redirectroot = "http://localhost:" + port + "/redirect/";
+        serverAuthority = makeServerAuthority(addr.getAddress().getHostAddress(), port);
+        System.out.println("HTTP server started at " + serverAuthority);
+        httproot = "http://" + serverAuthority + "/files/";
+        redirectroot = "http://" + serverAuthority + "/redirect/";
         uri = new URI(httproot);
         fileuri = httproot + "foo.txt";
     }
 
+    private static String makeServerAuthority(final String host, final int port) {
+        // escape for ipv6
+        final String h = host.contains(":") ? "[" + host + "]" : host;
+        return h + ":" + port;
+    }
+
     static class RedirectHandler implements HttpHandler {
 
         String root;
diff --git a/test/jdk/java/nio/channels/DatagramChannel/Connect.java b/test/jdk/java/nio/channels/DatagramChannel/Connect.java
index 5b2bbea..082a323 100644
--- a/test/jdk/java/nio/channels/DatagramChannel/Connect.java
+++ b/test/jdk/java/nio/channels/DatagramChannel/Connect.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
 
 /* @test
  * @bug 4313882 7183800
+ * @run main/othervm Connect
  * @summary Test DatagramChannel's send and receive methods
  */
 
@@ -30,18 +31,28 @@
 import java.net.*;
 import java.nio.*;
 import java.nio.channels.*;
-import java.nio.charset.*;
+import java.time.Instant;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.CompletionException;
 import java.util.stream.Stream;
 
+import static java.nio.charset.StandardCharsets.US_ASCII;
+
 public class Connect {
 
-    static PrintStream log = System.err;
+    static final PrintStream err = System.err;
+    static final String TIME_STAMP = Instant.now().toString();
+    static final String MESSAGE = "Hello " + TIME_STAMP;
+    static final String OTHER = "Hey " + TIME_STAMP;
+    static final String RESPONSE = "Hi " + TIME_STAMP;
+    static final int MAX = Math.max(256, MESSAGE.getBytes(US_ASCII).length + 16);
 
     public static void main(String[] args) throws Exception {
+        assert MAX > MESSAGE.getBytes(US_ASCII).length;
+        assert MAX > OTHER.getBytes(US_ASCII).length;
+        assert MAX > RESPONSE.getBytes(US_ASCII).length;
         test();
     }
 
@@ -99,41 +110,62 @@
 
         public void run() {
             try {
-                ByteBuffer bb = ByteBuffer.allocateDirect(256);
-                bb.put("hello".getBytes());
+                byte[] bytes = MESSAGE.getBytes(US_ASCII);
+                ByteBuffer bb = ByteBuffer.allocateDirect(MAX);
+                bb.put(bytes);
                 bb.flip();
-                log.println("Initiator connecting to " + connectSocketAddress);
+                err.println("Initiator connecting to: " + connectSocketAddress);
                 dc.connect(connectSocketAddress);
+                err.println("Initiator bound to: " + dc.getLocalAddress());
 
                 // Send a message
-                log.println("Initiator attempting to write to Responder at " + connectSocketAddress.toString());
+                err.println("Initiator attempting to write to Responder at " + connectSocketAddress);
                 dc.write(bb);
 
                 // Try to send to some other address
                 try {
                     int port = dc.socket().getLocalPort();
                     InetAddress loopback = InetAddress.getLoopbackAddress();
-                    InetSocketAddress otherAddress = new InetSocketAddress(loopback, (port == 3333 ? 3332 : 3333));
-                    log.println("Testing if Initiator throws AlreadyConnectedException" + otherAddress.toString());
-                    dc.send(bb, otherAddress);
+                    try (DatagramChannel other = DatagramChannel.open()) {
+                        InetSocketAddress otherAddress = new InetSocketAddress(loopback, 0);
+                        other.bind(otherAddress);
+                        err.println("Testing if Initiator throws AlreadyConnectedException");
+                        otherAddress = (InetSocketAddress) other.getLocalAddress();
+                        assert port != otherAddress.getPort();
+                        assert !connectSocketAddress.equals(otherAddress);
+                        err.printf("Initiator sending \"%s\" to other address %s%n", OTHER, otherAddress);
+                        dc.send(ByteBuffer.wrap(OTHER.getBytes(US_ASCII)), otherAddress);
+                    }
                     throw new RuntimeException("Initiator allowed send to other address while already connected");
                 } catch (AlreadyConnectedException ace) {
                     // Correct behavior
+                    err.println("Initiator got expected " + ace);
                 }
 
-                // Read a reply
-                bb.flip();
-                log.println("Initiator waiting to read");
-                dc.read(bb);
-                bb.flip();
-                CharBuffer cb = StandardCharsets.US_ASCII.
-                        newDecoder().decode(bb);
-                log.println("Initiator received from Responder at " + connectSocketAddress + ": " + cb);
+                // wait for response
+                while (true) {
+                    // zero out buffer
+                    bb.clear();
+                    bb.put(new byte[bb.remaining()]);
+                    bb.flip();
+
+                    // Read a reply
+                    err.println("Initiator waiting to read");
+                    dc.read(bb);
+                    bb.flip();
+                    CharBuffer cb = US_ASCII.newDecoder().decode(bb);
+                    err.println("Initiator received from Responder at " + connectSocketAddress + ": " + cb);
+                    if (!RESPONSE.equals(cb.toString())) {
+                        err.println("Initiator received unexpected message: continue waiting");
+                        continue;
+                    }
+                    break;
+                }
             } catch (Exception ex) {
-                log.println("Initiator threw exception: " + ex);
+                err.println("Initiator threw exception: " + ex);
                 throw new RuntimeException(ex);
             } finally {
-                log.println("Initiator finished");
+                err.println("Initiator finished");
             }
         }
 
@@ -156,26 +188,37 @@
         }
 
         public void run() {
+            ByteBuffer bb = ByteBuffer.allocateDirect(MAX);
             try {
-                // Listen for a message
-                ByteBuffer bb = ByteBuffer.allocateDirect(100);
-                log.println("Responder waiting to receive");
-                SocketAddress sa = dc.receive(bb);
-                bb.flip();
-                CharBuffer cb = StandardCharsets.US_ASCII.
-                        newDecoder().decode(bb);
-                log.println("Responder received from Initiator at" + sa +  ": " + cb);
+                while (true) {
+                    // Listen for a message
+                    err.println("Responder waiting to receive");
+                    SocketAddress sa = dc.receive(bb);
+                    bb.flip();
+                    CharBuffer cb = US_ASCII.
+                            newDecoder().decode(bb);
+                    err.println("Responder received from Initiator at " + sa + ": " + cb);
+                    if (!MESSAGE.equals(cb.toString())) {
+                        err.println("Responder received unexpected message: continue waiting");
+                        bb.clear();
+                        continue;
+                    }
 
-                // Reply to sender
-                dc.connect(sa);
-                bb.flip();
-                log.println("Responder attempting to write: " + dc.getRemoteAddress().toString());
-                dc.write(bb);
+                    // Reply to sender
+                    dc.connect(sa);
+                    bb.clear();
+                    bb.put(RESPONSE.getBytes(US_ASCII));
+                    bb.flip();
+                    err.println("Responder attempting to write: " + dc.getRemoteAddress());
+                    dc.write(bb);
+                    bb.flip();
+                    break;
+                }
             } catch (Exception ex) {
-                log.println("Responder threw exception: " + ex);
+                err.println("Responder threw exception: " + ex);
                 throw new RuntimeException(ex);
             } finally {
-                log.println("Responder finished");
+                err.println("Responder finished");
             }
         }
 
diff --git a/test/jdk/java/nio/file/attribute/BasicFileAttributeView/CreationTime.java b/test/jdk/java/nio/file/attribute/BasicFileAttributeView/CreationTime.java
index 16898fe..c1df9ab 100644
--- a/test/jdk/java/nio/file/attribute/BasicFileAttributeView/CreationTime.java
+++ b/test/jdk/java/nio/file/attribute/BasicFileAttributeView/CreationTime.java
@@ -22,10 +22,10 @@
  */
 
 /* @test
- * @bug 8011536
+ * @bug 8011536 8316304
  * @summary Basic test for creationTime attribute on platforms/file systems
  *     that support it.
- * @library ../..
+ * @library ../.. /test/lib
  */
 
 import java.nio.file.Path;
@@ -34,6 +34,8 @@
 import java.time.Instant;
 import java.io.IOException;
 
+import jdk.test.lib.Platform;
+
 public class CreationTime {
 
     private static final java.io.PrintStream err = System.err;
@@ -81,7 +83,13 @@
                 supportsCreationTimeRead = true;
                 supportsCreationTimeWrite = true;
             }
+        } else if (Platform.isLinux()) {
+            // Creation time read depends on statx system call support
+            supportsCreationTimeRead = CreationTimeHelper.linuxIsCreationTimeSupported();
+            // Creation time updates are not supported on Linux
+            supportsCreationTimeWrite = false;
         }
+        System.out.println("supportsCreationTimeRead == " + supportsCreationTimeRead);
 
         /**
          * If the creation-time attribute is supported then change the file's
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/malloc/malloclock04/TestDescription.java b/test/jdk/java/nio/file/attribute/BasicFileAttributeView/CreationTimeHelper.java
similarity index 70%
rename from test/hotspot/jtreg/vmTestbase/gc/lock/malloc/malloclock04/TestDescription.java
rename to test/jdk/java/nio/file/attribute/BasicFileAttributeView/CreationTimeHelper.java
index d70a82a..1b8d5bc 100644
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/malloc/malloclock04/TestDescription.java
+++ b/test/jdk/java/nio/file/attribute/BasicFileAttributeView/CreationTimeHelper.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2023, Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -20,17 +20,12 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+public class CreationTimeHelper {
 
+    static {
+        System.loadLibrary("CreationTimeHelper");
+    }
 
-/*
- * @test
- * @key stress randomness
- *
- * @summary converted from VM Testbase gc/lock/malloc/malloclock04.
- * VM Testbase keywords: [gc, stress, stressopt, nonconcurrent]
- *
- * @library /vmTestbase
- *          /test/lib
- * @run main/othervm/native -XX:-UseGCOverheadLimit gc.lock.LockerTest -gp1 class -lockers malloc
- */
-
+    // Helper so as to determine 'statx' support on the runtime system
+    static native boolean linuxIsCreationTimeSupported();
+}
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnireflock04/TestDescription.java b/test/jdk/java/nio/file/attribute/BasicFileAttributeView/libCreationTimeHelper.c
similarity index 68%
copy from test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnireflock04/TestDescription.java
copy to test/jdk/java/nio/file/attribute/BasicFileAttributeView/libCreationTimeHelper.c
index 8e61aa3..6a2fc74 100644
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnireflock04/TestDescription.java
+++ b/test/jdk/java/nio/file/attribute/BasicFileAttributeView/libCreationTimeHelper.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2023, Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -20,17 +20,19 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+#include "jni.h"
+#if defined(__linux__)
+#include <dlfcn.h>
+#endif
 
-
-/*
- * @test
- * @key stress randomness
- *
- * @summary converted from VM Testbase gc/lock/jniref/jnireflock04.
- * VM Testbase keywords: [gc, stress, stressopt, nonconcurrent, quick]
- *
- * @library /vmTestbase
- *          /test/lib
- * @run main/othervm/native -XX:-UseGCOverheadLimit gc.lock.LockerTest -gp1 class -lockers jniRef
- */
-
+// static native boolean linuxIsCreationTimeSupported()
+JNIEXPORT jboolean JNICALL
+Java_CreationTimeHelper_linuxIsCreationTimeSupported(JNIEnv *env, jclass cls)
+{
+#if defined(__linux__)
+    void* statx_func = dlsym(RTLD_DEFAULT, "statx");
+    return statx_func != NULL ? JNI_TRUE : JNI_FALSE;
+#else
+    return JNI_FALSE;
+#endif
+}
diff --git a/test/jdk/java/security/KeyStore/PKCS12/Utils.java b/test/jdk/java/security/KeyStore/PKCS12/Utils.java
index 67286bd..2213139 100644
--- a/test/jdk/java/security/KeyStore/PKCS12/Utils.java
+++ b/test/jdk/java/security/KeyStore/PKCS12/Utils.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -59,11 +59,14 @@
 
     public static OutputAnalyzer executeKeytoolCommand(String[] command,
             int exitCode) {
-        String[] keytoolCmd = new String[command.length + 1];
+        String[] keytoolCmd = new String[command.length + 3];
         OutputAnalyzer output = null;
         try {
             keytoolCmd[0] = JDKToolFinder.getJDKTool(KEYTOOL);
-            System.arraycopy(command, 0, keytoolCmd, 1, command.length);
+            // Ensure the keytool process is always ran under English locale
+            keytoolCmd[1] = "-J-Duser.language=en";
+            keytoolCmd[2] = "-J-Duser.country=US";
+            System.arraycopy(command, 0, keytoolCmd, 3, command.length);
             output = ProcessTools.executeCommand(keytoolCmd);
             output.shouldHaveExitValue(exitCode);
             out.println("Executed keytool command sucessfully:"
diff --git a/test/jdk/java/security/cert/CertPathBuilder/akiExt/AKISerialNumber.java b/test/jdk/java/security/cert/CertPathBuilder/akiExt/AKISerialNumber.java
index e8ab65d..53db87c 100644
--- a/test/jdk/java/security/cert/CertPathBuilder/akiExt/AKISerialNumber.java
+++ b/test/jdk/java/security/cert/CertPathBuilder/akiExt/AKISerialNumber.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -118,6 +118,8 @@
         PKIXBuilderParameters params = new PKIXBuilderParameters
             (Collections.singleton(anchor), sel);
         params.setRevocationEnabled(false);
+        // Set date to 2024-01-01 to satisfy cert constraints
+        params.setDate(new java.util.Date(1704067200000l));
 
         ArrayList<X509Certificate> certs = new ArrayList<>();
         certs.add(intCert);
diff --git a/test/jdk/java/util/Currency/Bug4512215.java b/test/jdk/java/util/Currency/Bug4512215.java
deleted file mode 100644
index 2e2a78c..0000000
--- a/test/jdk/java/util/Currency/Bug4512215.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-/*
- * @test
- * @bug 4512215 4818420 4819436
- * @summary Updated currency data.
- */
-
-import java.util.Currency;
-import java.util.Locale;
-
-public class Bug4512215 {
-
-    public static void main(String[] args) throws Exception {
-        testCurrencyDefined("XBD", -1);
-        testCountryCurrency("TJ", "TJS", 2);
-        testCountryCurrency("FO", "DKK", 2);
-        testCountryCurrency("FK", "FKP", 2);
-
-        testCountryCurrency("AF", "AFN", 2);    // changed from "AFA"
-
-        // Newsletter V-5 on ISO 3166-1 (2002-05-20)
-        testCountryCurrency("TL", "USD", 2);    // successor to TP/TPE
-
-        // Newsletter V-8 on ISO 3166-1 (2003-07-23)
-        testCountryCurrency("CS", "CSD", 2);    // successor to YU/YUM
-    }
-
-    private static void testCountryCurrency(String country, String currencyCode,
-            int digits) {
-        testCurrencyDefined(currencyCode, digits);
-        Currency currency = Currency.getInstance(new Locale("", country));
-        if (!currency.getCurrencyCode().equals(currencyCode)) {
-            throw new RuntimeException("[" + country
-                    + "] expected: " + currencyCode
-                    + "; got: " + currency.getCurrencyCode());
-        }
-    }
-
-    private static void testCurrencyDefined(String currencyCode, int digits) {
-        Currency currency = Currency.getInstance(currencyCode);
-        if (currency.getDefaultFractionDigits() != digits) {
-            throw new RuntimeException("[" + currencyCode
-                    + "] expected: " + digits
-                    + "; got: " + currency.getDefaultFractionDigits());
-        }
-    }
-}
diff --git a/test/jdk/java/util/Currency/Bug6807534.java b/test/jdk/java/util/Currency/Bug6807534.java
deleted file mode 100644
index 073518d..0000000
--- a/test/jdk/java/util/Currency/Bug6807534.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-/*
- * @test
- * @bug 6807534
- * @summary check whether the default implementation of
- *    CurrencNameProvider.getDisplayName(String, Locale) throws appropriate
- *    exceptions when necessary.
- */
-
-import java.util.Locale;
-import java.util.spi.CurrencyNameProvider;
-
-public class Bug6807534 {
-
-    static final CurrencyNameProvider cnp = new CurrencyNameProviderImpl();
-
-    public static void main(String[] args) throws Exception {
-        // test for NullPointerException (currencyCode)
-        try {
-            cnp.getDisplayName(null, Locale.US);
-            throwException("NPE was not thrown with null currencyCode");
-        } catch (NullPointerException npe) {}
-
-        // test for NullPointerException (locale)
-        try {
-            cnp.getDisplayName("USD", null);
-            throwException("NPE was not thrown with null locale");
-        } catch (NullPointerException npe) {}
-
-        // test for IllegalArgumentException (illegal currencyCode)
-        try {
-            cnp.getDisplayName("INVALID", Locale.US);
-            throwException("IllegalArgumentException was not thrown with invalid currency code");
-        } catch (IllegalArgumentException iae) {}
-        try {
-            cnp.getDisplayName("inv", Locale.US);
-            throwException("IllegalArgumentException was not thrown with invalid currency code");
-        } catch (IllegalArgumentException iae) {}
-
-        // test for IllegalArgumentException (non-supported locale)
-        try {
-            cnp.getDisplayName("USD", Locale.JAPAN);
-            throwException("IllegalArgumentException was not thrown with non-supported locale");
-        } catch (IllegalArgumentException iae) {}
-    }
-
-    static void throwException(String msg) {
-        throw new RuntimeException("test failed. "+msg);
-    }
-
-    static class CurrencyNameProviderImpl extends CurrencyNameProvider {
-        // dummy implementation
-        public String getSymbol(String currencyCode, Locale locale) {
-            return "";
-        }
-
-        public Locale[] getAvailableLocales() {
-            Locale[] avail = new Locale[1];
-            avail[0] = Locale.US;
-            return avail;
-        }
-    }
-}
diff --git a/test/jdk/java/util/Currency/Bug8154295.java b/test/jdk/java/util/Currency/Bug8154295.java
deleted file mode 100644
index 356d00b..0000000
--- a/test/jdk/java/util/Currency/Bug8154295.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-/*
- * @test
- * @bug 8154295
- * @summary Check getNumericCodeAsString() method which returns numeric code as a 3 digit String.
- */
-
-import java.util.Currency;
-
-public class Bug8154295 {
-
-    public static void main(String[] args) {
-
-        String numericCode = Currency.getInstance("AFA").getNumericCodeAsString();
-        if (!numericCode.equals("004")) { //should return "004" (a 3 digit string)
-           throw new RuntimeException("[Expected 004, "
-                + "found "+numericCode+" for AFA]");
-        }
-
-        numericCode = Currency.getInstance("AUD").getNumericCodeAsString();
-        if (!numericCode.equals("036")) { //should return "036" (a 3 digit string)
-            throw new RuntimeException("[Expected 036, "
-                + "found "+numericCode+" for AUD]");
-        }
-
-        numericCode = Currency.getInstance("USD").getNumericCodeAsString();
-        if (!numericCode.equals("840")) {// should return "840" (a 3 digit string)
-            throw new RuntimeException("[Expected 840, "
-                + "found "+numericCode+" for USD]");
-        }
-
-    }
-
-}
diff --git a/test/jdk/java/util/Currency/CNPGetDisplayName.java b/test/jdk/java/util/Currency/CNPGetDisplayName.java
new file mode 100644
index 0000000..af399be
--- /dev/null
+++ b/test/jdk/java/util/Currency/CNPGetDisplayName.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2010, 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6807534
+ * @summary check whether the default implementation of
+ *    CurrencyNameProvider.getDisplayName(String, Locale) throws appropriate
+ *    exceptions when necessary.
+ * @run junit CNPGetDisplayName
+ */
+
+import java.util.Locale;
+import java.util.spi.CurrencyNameProvider;
+import java.util.stream.Stream;
+
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+public class CNPGetDisplayName {
+
+    static final CurrencyNameProvider cnp = new CurrencyNameProviderImpl();
+
+    /**
+     * Tests that the currency name provider throws a NullPointerException
+     * under the expected circumstances.
+     */
+    @ParameterizedTest
+    @MethodSource("nullArgProvider")
+    public void NPETest(String currencyCode, Locale locale, String err) {
+        assertThrows(NullPointerException.class,
+                () -> cnp.getDisplayName(currencyCode, locale), err);
+    }
+
+    /**
+     * Tests that the currency name provider throws a IllegalArgumentException
+     * under the expected circumstances.
+     */
+    @ParameterizedTest
+    @MethodSource("illegalArgProvider")
+    public void IAETest(String currencyCode, Locale locale, String err) {
+        assertThrows(IllegalArgumentException.class,
+                () -> cnp.getDisplayName(currencyCode, locale), err);
+    }
+
+    private static Stream<Arguments> nullArgProvider() {
+        return Stream.of(
+                Arguments.of(null, Locale.US,
+                        "NPE was not thrown with null currencyCode"),
+                Arguments.of("USD", null,
+                        "NPE was not thrown with null locale")
+        );
+    }
+
+    private static Stream<Arguments> illegalArgProvider() {
+        return Stream.of(
+                Arguments.of("INVALID", Locale.US,
+                        "IAE was not thrown with invalid currency code"),
+                Arguments.of("inv", Locale.US,
+                        "IAE was not thrown with invalid currency code"),
+                Arguments.of("USD", Locale.JAPAN,
+                        "IllegalArgumentException was not thrown with non-supported locale")
+        );
+    }
+
+    static class CurrencyNameProviderImpl extends CurrencyNameProvider {
+        // dummy implementation
+        public String getSymbol(String currencyCode, Locale locale) {
+            return "";
+        }
+
+        public Locale[] getAvailableLocales() {
+            Locale[] avail = new Locale[1];
+            avail[0] = Locale.US;
+            return avail;
+        }
+    }
+}
diff --git a/test/jdk/java/util/Currency/CheckDataVersion.java b/test/jdk/java/util/Currency/CheckDataVersion.java
index 204a80a..ba18677 100644
--- a/test/jdk/java/util/Currency/CheckDataVersion.java
+++ b/test/jdk/java/util/Currency/CheckDataVersion.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -20,15 +20,21 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-/**
- *
- *
- * Check the consistency between the regression tests and the currency data in the JRE
+
+
+/*
+  Check the consistency between the regression tests and the currency
+  data in the JRE. This class is used by other test classes.
  */
 
-import java.io.*;
-import java.lang.reflect.*;
-import java.security.*;
+import java.io.BufferedReader;
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.util.Currency;
 
 class CheckDataVersion {
diff --git a/test/jdk/java/util/Currency/CurrencyTest.java b/test/jdk/java/util/Currency/CurrencyTest.java
index ad7c596..256e6ee 100644
--- a/test/jdk/java/util/Currency/CurrencyTest.java
+++ b/test/jdk/java/util/Currency/CurrencyTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -20,6 +20,7 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+
 /*
  * @test
  * @bug 4290801 4692419 4693631 5101540 5104960 6296410 6336600 6371531
@@ -28,6 +29,7 @@
  * @summary Basic tests for Currency class.
  * @modules java.base/java.util:open
  *          jdk.localedata
+ * @run junit CurrencyTest
  */
 
 import java.io.ByteArrayInputStream;
@@ -38,198 +40,232 @@
 import java.time.LocalTime;
 import java.time.ZoneId;
 import java.time.ZonedDateTime;
+import java.util.ArrayList;
 import java.util.Currency;
+import java.util.List;
 import java.util.Locale;
+import java.util.stream.Stream;
+
+import org.junit.jupiter.api.Disabled;
+import org.junit.jupiter.api.Nested;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
 
 
 public class CurrencyTest {
 
-    public static void main(String[] args) throws Exception {
+    // 'tablea1.txt' should be up-to-date before testing
+    @Test
+    public void dataVersionTest() {
         CheckDataVersion.check();
-        testCurrencyCodeValidation();
-        testLocaleMapping();
-        testSymbols();
-        testFractionDigits();
-        testSerialization();
-        testDisplayNames();
-        testFundsCodes();
     }
 
-    static void testCurrencyCodeValidation() {
-        // test creation of some valid currencies
-        testValidCurrency("USD");
-        testValidCurrency("EUR");
-        testValidCurrency("GBP");
-        testValidCurrency("JPY");
-        testValidCurrency("CNY");
-        testValidCurrency("CHF");
-
-        // test creation of some fictitious currencies
-        testInvalidCurrency("AQD");
-        testInvalidCurrency("US$");
-        testInvalidCurrency("\u20AC");
-    }
-
-    static void testValidCurrency(String currencyCode) {
-        Currency currency1 = Currency.getInstance(currencyCode);
-        Currency currency2 = Currency.getInstance(currencyCode);
-        if (currency1 != currency2) {
-            throw new RuntimeException("Didn't get same instance for same currency code");
+    @Nested
+    class CodeValidationTests {
+        // Calling getInstance() on equal currency codes should return equal currencies
+        @ParameterizedTest
+        @MethodSource("validCurrencies")
+        public void validCurrencyTest(String currencyCode) {
+            compareCurrencies(currencyCode);
         }
-        if (!currency1.getCurrencyCode().equals(currencyCode)) {
-            throw new RuntimeException("Currency code changed");
+
+        private static Stream<String> validCurrencies() {
+            return Stream.of("USD", "EUR", "GBP", "JPY", "CNY", "CHF");
+        }
+
+        // Calling getInstance() with an invalid currency code should throw an IAE
+        @ParameterizedTest
+        @MethodSource("invalidCurrencies")
+        public void invalidCurrencyTest(String currencyCode) {
+            assertThrows(IllegalArgumentException.class, () ->
+                    Currency.getInstance(currencyCode), "getInstance() did not throw IAE");
+        }
+
+        private static Stream<String> invalidCurrencies() {
+            return Stream.of("AQD", "US$", "\u20AC");
         }
     }
 
-    static void testInvalidCurrency(String currencyCode) {
-        boolean gotException = false;
-        try {
-            Currency currency = Currency.getInstance(currencyCode);
-        } catch (IllegalArgumentException e) {
-            gotException = true;
+    @Nested
+    class FundsCodesTests {
+        // Calling getInstance() on equal currency codes should return equal currencies
+        @ParameterizedTest
+        @MethodSource("fundsCodes")
+        public void validCurrencyTest(String currencyCode) {
+            compareCurrencies(currencyCode);
         }
-        if (!gotException) {
-            throw new RuntimeException("didn't get specified exception");
+
+        // Verify a currency has the expected fractional digits
+        @ParameterizedTest
+        @MethodSource("fundsCodes")
+        public void fractionDigitTest(String currencyCode, int expectedFractionDigits) {
+            compareFractionDigits(currencyCode, expectedFractionDigits);
+        }
+
+        // Verify a currency has the expected numeric code
+        @ParameterizedTest
+        @MethodSource("fundsCodes")
+        public void numericCodeTest(String currencyCode, int ignored, int expectedNumeric) {
+            int numeric = Currency.getInstance(currencyCode).getNumericCode();
+            assertEquals(numeric, expectedNumeric, String.format(
+                    "Wrong numeric code for currency %s, expected %s, got %s",
+                    currencyCode, expectedNumeric, numeric));
+        }
+
+        private static Stream<Arguments> fundsCodes() {
+            return Stream.of(
+                    Arguments.of("BOV", 2, 984), Arguments.of("CHE", 2, 947),
+                    Arguments.of("CHW", 2, 948), Arguments.of("CLF", 4, 990),
+                    Arguments.of("COU", 2, 970), Arguments.of("MXV", 2, 979),
+                    Arguments.of("USN", 2, 997), Arguments.of("UYI", 0, 940)
+            );
         }
     }
 
-    static void testLocaleMapping() {
+    @Nested
+    class LocaleMappingTests {
+
         // very basic test: most countries have their own currency, and then
         // their currency code is an extension of their country code.
-        Locale[] locales = Locale.getAvailableLocales();
-        int goodCountries = 0;
-        int ownCurrencies = 0;
-        for (int i = 0; i < locales.length; i++) {
-            Locale locale = locales[i];
-            String ctryCode = locale.getCountry();
-            int ctryLength = ctryCode.length();
-            if (ctryLength == 0 ||
-                ctryLength == 3 || // UN M.49 code
-                ctryCode.matches("AA|Q[M-Z]|X[A-JL-Z]|ZZ" + // user defined codes, excluding "XK" (Kosovo)
-                                 "AC|CP|DG|EA|EU|FX|IC|SU|TA|UK")) { // exceptional reservation codes
-                boolean gotException = false;
-                try {
-                    Currency.getInstance(locale);
-                } catch (IllegalArgumentException e) {
-                    gotException = true;
-                }
-                if (!gotException) {
-                    throw new RuntimeException("didn't get specified exception");
-                }
-            } else {
-                goodCountries++;
-                Currency currency = Currency.getInstance(locale);
-                if (currency.getCurrencyCode().indexOf(locale.getCountry()) == 0) {
-                    ownCurrencies++;
+        @Test
+        public void localeMappingTest() {
+            Locale[] locales = Locale.getAvailableLocales();
+            int goodCountries = 0;
+            int ownCurrencies = 0;
+            for (Locale locale : locales) {
+                String ctryCode = locale.getCountry();
+                int ctryLength = ctryCode.length();
+                if (ctryLength == 0 ||
+                        ctryLength == 3 || // UN M.49 code
+                        ctryCode.matches("AA|Q[M-Z]|X[A-JL-Z]|ZZ" + // user defined codes, excluding "XK" (Kosovo)
+                                "AC|CP|DG|EA|EU|FX|IC|SU|TA|UK")) { // exceptional reservation codes
+                    assertThrows(IllegalArgumentException.class, () -> Currency.getInstance(locale), "Did not throw IAE");
+                } else {
+                    goodCountries++;
+                    Currency currency = Currency.getInstance(locale);
+                    if (currency.getCurrencyCode().indexOf(locale.getCountry()) == 0) {
+                        ownCurrencies++;
+                    }
                 }
             }
-        }
-        System.out.println("Countries tested: " + goodCountries +
-                ", own currencies: " + ownCurrencies);
-        if (ownCurrencies < (goodCountries / 2 + 1)) {
-            throw new RuntimeException("suspicious: not enough countries have their own currency.");
+            System.out.println("Countries tested: " + goodCountries +
+                    ", own currencies: " + ownCurrencies);
+            if (ownCurrencies < (goodCountries / 2 + 1)) {
+                throw new RuntimeException("suspicious: not enough countries have their own currency.");
+            }
         }
 
-        // check a few countries that don't change their currencies too often
-        String[] country1 = {"US", "CA", "JP", "CN", "SG", "CH"};
-        String[] currency1 = {"USD", "CAD", "JPY", "CNY", "SGD", "CHF"};
-        for (int i = 0; i < country1.length; i++) {
-            checkCountryCurrency(country1[i], currency1[i]);
+        // Check an invalid country code
+        @Test
+        public void invalidCountryTest() {
+            assertThrows(IllegalArgumentException.class, ()->
+                    Currency.getInstance(new Locale("", "EU")), "Did not throw IAE");
+        }
+
+        // Ensure a selection of countries have the expected currency
+        @ParameterizedTest
+        @MethodSource({"countryProvider", "switchedOverCountries"})
+        public void countryCurrencyTest(String countryCode, String expected) {
+            Locale locale = new Locale("", countryCode);
+            Currency currency = Currency.getInstance(locale);
+            String code = (currency != null) ? currency.getCurrencyCode() : null;
+            assertEquals(expected, code, generateErrMsg(
+                    "currency for", locale.getDisplayCountry(), expected, code));
+        }
+
+        private static Stream<Arguments> countryProvider() {
+            return Stream.of(
+                    // Check country that does not have a currency
+                    Arguments.of("AQ", null),
+                    // Check some countries that don't change their currencies often
+                    Arguments.of("US", "USD"),
+                    Arguments.of("CA", "CAD"),
+                    Arguments.of("JP", "JPY"),
+                    Arguments.of("CN", "CNY"),
+                    Arguments.of("SG", "SGD"),
+                    Arguments.of("CH", "CHF")
+            );
         }
 
         /*
-        * check currency changes
-        * In current implementation, there is no data of old currency and transition date at jdk/make/data/currency/CurrencyData.properties.
-        * So, all the switch data arrays are empty. In the future, if data of old currency and transition date are necessary for any country, the
-        * arrays here can be updated so that the program can check the currency switch.
-        */
-        String[] switchOverCtry = {};
-        String[] switchOverOld = {};
-        String[] switchOverNew = {};
-        String[] switchOverTZ = {};
-        int[] switchOverYear = {};
-        int[] switchOverMonth = {}; // java.time APIs accept month starting from 1 i.e. 01 for January
-        int[] switchOverDay = {};
+         * Check Currency Changes
+         * In the current implementation, there is no data of old currency and transition
+         * date at jdk/src/java.base/share/data/currency/CurrencyData.properties.
+         * So, all the switch data arrays are empty. In the future, if data of old
+         * currency and transition date are necessary for any country, the
+         * arrays here can be updated so that the program can check the currency switch.
+         */
+        private static List<Arguments> switchedOverCountries() {
+            List<Arguments> switched = new ArrayList<Arguments>();
+            String[] switchOverCtry = {};
+            String[] switchOverOld = {};
+            String[] switchOverNew = {};
+            String[] switchOverTZ = {};
+            int[] switchOverYear = {};
+            int[] switchOverMonth = {}; // java.time APIs accept month starting from 1 i.e. 01 for January
+            int[] switchOverDay = {};
 
-        for (int i = 0; i < switchOverCtry.length; i++) {
-            ZoneId zoneId = ZoneId.of(switchOverTZ[i]);
-            ZonedDateTime zonedDateAndTime  = ZonedDateTime.of(LocalDate.of(switchOverYear[i], switchOverMonth[i], switchOverDay[i]),
-                                                  LocalTime.MIDNIGHT, zoneId);
-            ZonedDateTime currentZonedDateAndTime =  ZonedDateTime.now(zoneId);
-            checkCountryCurrency(switchOverCtry[i], (currentZonedDateAndTime.isAfter(zonedDateAndTime) ||
-                        currentZonedDateAndTime.isEqual(zonedDateAndTime)) ? switchOverNew[i] : switchOverOld[i]);
-        }
-
-        // check a country code which doesn't have a currency
-        checkCountryCurrency("AQ", null);
-
-        // check an invalid country code
-        boolean gotException = false;
-        try {
-            Currency.getInstance(new Locale("", "EU"));
-        } catch (IllegalArgumentException e) {
-            gotException = true;
-        }
-        if (!gotException) {
-            throw new RuntimeException("didn't get specified exception.");
+            for (int i = 0; i < switchOverCtry.length; i++) {
+                ZoneId zoneId = ZoneId.of(switchOverTZ[i]);
+                ZonedDateTime zonedDateAndTime  = ZonedDateTime.of(LocalDate.of(
+                        switchOverYear[i], switchOverMonth[i], switchOverDay[i]), LocalTime.MIDNIGHT, zoneId);
+                ZonedDateTime currentZonedDateAndTime =  ZonedDateTime.now(zoneId);
+                switched.add(Arguments.of(switchOverCtry[i], (currentZonedDateAndTime.isAfter(zonedDateAndTime)
+                        || currentZonedDateAndTime.isEqual(zonedDateAndTime)) ? switchOverNew[i] : switchOverOld[i]));
+            }
+            return switched;
         }
     }
 
-    static void checkCountryCurrency(String countryCode, String expected) {
-        Locale locale = new Locale("", countryCode);
-        Currency currency = Currency.getInstance(locale);
-        String code = (currency != null) ? currency.getCurrencyCode() : null;
-        if (!(expected == null ? code == null : expected.equals(code))) {
-            throw new RuntimeException("Wrong currency for " +
-                    locale.getDisplayCountry() +
-                    ": expected " + expected + ", got " + code);
-        }
+    // NON-NESTED TESTS
+
+    // Ensure selection of currencies have the correct fractional digits
+    @ParameterizedTest
+    @MethodSource("expectedFractionsProvider")
+    public void fractionDigitsTest(String currencyCode, int expectedFractionDigits) {
+        compareFractionDigits(currencyCode, expectedFractionDigits);
     }
 
-    static void testSymbols() {
-        testSymbol("USD", Locale.US, "$");
-        testSymbol("EUR", Locale.GERMANY, "\u20AC");
-        testSymbol("USD", Locale.PRC, "US$");
+    private static Stream<Arguments> expectedFractionsProvider() {
+        return Stream.of(
+                Arguments.of("USD", 2), Arguments.of("EUR", 2),
+                Arguments.of("JPY", 0), Arguments.of("XDR", -1),
+                Arguments.of("BHD", 3), Arguments.of("IQD", 3),
+                Arguments.of("JOD", 3), Arguments.of("KWD", 3),
+                Arguments.of("LYD", 3), Arguments.of("OMR", 3),
+                Arguments.of("TND", 3),
+
+                // Old and New Turkish Lira
+                Arguments.of("TRL", 0), Arguments.of("TRY", 2)
+        );
     }
 
-    static void testSymbol(String currencyCode, Locale locale, String expectedSymbol) {
+    // Ensure selection of currencies have the expected symbol
+    @ParameterizedTest
+    @MethodSource("symbolProvider")
+    public void symbolTest(String currencyCode, Locale locale, String expectedSymbol) {
         String symbol = Currency.getInstance(currencyCode).getSymbol(locale);
-        if (!symbol.equals(expectedSymbol)) {
-            throw new RuntimeException("Wrong symbol for currency " +
-                    currencyCode +": expected " + expectedSymbol +
-                    ", got " + symbol);
-        }
+        assertEquals(symbol, expectedSymbol, generateErrMsg(
+                "symbol for", currencyCode, expectedSymbol, symbol));
     }
 
-    static void testFractionDigits() {
-        testFractionDigits("USD", 2);
-        testFractionDigits("EUR", 2);
-        testFractionDigits("JPY", 0);
-        testFractionDigits("XDR", -1);
-
-        testFractionDigits("BHD", 3);
-        testFractionDigits("IQD", 3);
-        testFractionDigits("JOD", 3);
-        testFractionDigits("KWD", 3);
-        testFractionDigits("LYD", 3);
-        testFractionDigits("OMR", 3);
-        testFractionDigits("TND", 3);
-
-        // Turkish Lira
-        testFractionDigits("TRL", 0);
-        testFractionDigits("TRY", 2);
+    private static Stream<Arguments> symbolProvider() {
+        return Stream.of(
+                Arguments.of("USD", Locale.US, "$"),
+                Arguments.of("EUR", Locale.GERMANY, "\u20AC"),
+                Arguments.of("USD", Locale.PRC, "US$")
+        );
     }
 
-    static void testFractionDigits(String currencyCode, int expectedFractionDigits) {
-        int digits = Currency.getInstance(currencyCode).getDefaultFractionDigits();
-        if (digits != expectedFractionDigits) {
-            throw new RuntimeException("Wrong number of fraction digits for currency " +
-                    currencyCode +": expected " + expectedFractionDigits +
-                    ", got " + digits);
-        }
-    }
-
-    static void testSerialization() throws Exception {
+    // Ensure serialization does not break class invariant.
+    // Currency should be able to round-trip and remain the same value.
+    @Test
+    public void serializationTest() throws Exception {
         Currency currency1 = Currency.getInstance("DEM");
 
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
@@ -241,74 +277,66 @@
         ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
         ObjectInputStream iStream = new ObjectInputStream(bais);
         Currency currency2 = (Currency) iStream.readObject();
-
-        if (currency1 != currency2) {
-            throw new RuntimeException("serialization breaks class invariant");
-        }
+        assertEquals(currency1, currency2, "serialization breaks class invariant");
     }
 
-    static void testDisplayNames() {
-        // null argument test
-        try {
-            testDisplayName("USD", null, "");
-            throw new RuntimeException("getDisplayName(NULL) did not throw an NPE.");
-        } catch (NullPointerException npe) {}
-
-        testDisplayName("USD", Locale.ENGLISH, "US Dollar");
-        testDisplayName("FRF", Locale.FRENCH, "franc fran\u00e7ais");
-        testDisplayName("DEM", Locale.GERMAN, "Deutsche Mark");
-        testDisplayName("ESP", new Locale("es"), "peseta espa\u00f1ola");
-        testDisplayName("ITL", new Locale("it"), "lira italiana");
-        testDisplayName("JPY", Locale.JAPANESE, "\u65e5\u672c\u5186");
-        testDisplayName("KRW", Locale.KOREAN, "\ub300\ud55c\ubbfc\uad6d \uc6d0");
-        testDisplayName("SEK", new Locale("sv"), "svensk krona");
-        testDisplayName("CNY", Locale.SIMPLIFIED_CHINESE, "\u4eba\u6c11\u5e01");
-        testDisplayName("TWD", Locale.TRADITIONAL_CHINESE, "\u65b0\u53f0\u5e63");
+    // Ensure getInstance() throws null when passed a null locale
+    @Test
+    public void nullDisplayNameTest() {
+        assertThrows(NullPointerException.class, ()->
+                Currency.getInstance("USD").getDisplayName(null));
     }
 
-    static void testDisplayName(String currencyCode, Locale locale, String expectedName) {
+    // Ensure a selection of currencies/locale combos have the correct display name
+    @ParameterizedTest
+    @MethodSource("displayNameProvider")
+    public void displayNameTest(String currencyCode, Locale locale, String expectedName) {
         String name = Currency.getInstance(currencyCode).getDisplayName(locale);
-        if (!name.equals(expectedName)) {
-            throw new RuntimeException("Wrong display name for currency " +
-                    currencyCode +": expected '" + expectedName +
-                    "', got '" + name + "'");
-        }
-    }
-    static void testFundsCodes() {
-        testValidCurrency("BOV");
-        testValidCurrency("CHE");
-        testValidCurrency("CHW");
-        testValidCurrency("CLF");
-        testValidCurrency("COU");
-        testValidCurrency("MXV");
-        testValidCurrency("USN");
-        testValidCurrency("UYI");
-
-        testFractionDigits("BOV", 2);
-        testFractionDigits("CHE", 2);
-        testFractionDigits("CHW", 2);
-        testFractionDigits("CLF", 4);
-        testFractionDigits("COU", 2);
-        testFractionDigits("MXV", 2);
-        testFractionDigits("USN", 2);
-        testFractionDigits("UYI", 0);
-
-        testNumericCode("BOV", 984);
-        testNumericCode("CHE", 947);
-        testNumericCode("CHW", 948);
-        testNumericCode("CLF", 990);
-        testNumericCode("COU", 970);
-        testNumericCode("MXV", 979);
-        testNumericCode("USN", 997);
-        testNumericCode("UYI", 940);
+        assertEquals(name, expectedName, generateErrMsg(
+                "display name for", currencyCode, expectedName, name));
     }
 
-    static void testNumericCode(String currencyCode, int expectedNumeric) {
-        int numeric = Currency.getInstance(currencyCode).getNumericCode();
-        if (numeric != expectedNumeric) {
-            throw new RuntimeException("Wrong numeric code for currency " +
-                    currencyCode +": expected " + expectedNumeric +
-                    ", got " + numeric);
-        }
+    private static Stream<Arguments> displayNameProvider() {
+        return Stream.of(
+                Arguments.of("USD", Locale.ENGLISH, "US Dollar"),
+                Arguments.of("FRF", Locale.FRENCH, "franc fran\u00e7ais"),
+                Arguments.of("DEM", Locale.GERMAN, "Deutsche Mark"),
+                Arguments.of("ESP", new Locale("es"), "peseta espa\u00f1ola"),
+                Arguments.of("ITL", Locale.ITALIAN, "lira italiana"),
+                Arguments.of("JPY", Locale.JAPANESE, "\u65e5\u672c\u5186"),
+                Arguments.of("KRW", Locale.KOREAN, "\ub300\ud55c\ubbfc\uad6d \uc6d0"),
+                Arguments.of("SEK", new Locale("sv"), "svensk krona"),
+                Arguments.of("CNY", Locale.SIMPLIFIED_CHINESE, "\u4eba\u6c11\u5e01"),
+                Arguments.of("TWD", Locale.TRADITIONAL_CHINESE, "\u65b0\u53f0\u5e63")
+        );
+    }
+
+    // HELPER FUNCTIONS
+
+    // A Currency instance returned from getInstance() should always be
+    // equal if supplied the same currencyCode. getCurrencyCode() should
+    // always be equal to the currencyCode used to create the Currency.
+    private static void compareCurrencies(String currencyCode) {
+        Currency currency1 = Currency.getInstance(currencyCode);
+        Currency currency2 = Currency.getInstance(currencyCode);
+        assertEquals(currency1, currency2, "Didn't get same instance for same currency code");
+        assertEquals(currency1.getCurrencyCode(), currencyCode, "getCurrencyCode()" +
+                " did not return the expected value");
+    }
+
+    // Ensures the getDefaultFractionDigits() method returns the expected amount
+    private static void compareFractionDigits(String currencyCode,
+                                              int expectedFractionDigits) {
+        int digits = Currency.getInstance(currencyCode).getDefaultFractionDigits();
+        assertEquals(digits, expectedFractionDigits, generateErrMsg(
+                "number of fraction digits for currency",
+                currencyCode, Integer.toString(expectedFractionDigits), Integer.toString(digits)));
+    }
+
+    // Used for logging on failing tests
+    private static String generateErrMsg(String subject, String currency,
+                                         String expected, String got) {
+        return String.format("Wrong %s %s: expected '%s', got '%s'",
+                subject, currency, expected, got);
     }
 }
diff --git a/test/jdk/java/util/Currency/NoMinorUnitCurrenciesTest.java b/test/jdk/java/util/Currency/NoMinorUnitCurrenciesTest.java
new file mode 100644
index 0000000..1fe9c8b
--- /dev/null
+++ b/test/jdk/java/util/Currency/NoMinorUnitCurrenciesTest.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4512215 4818420 4819436 8310923
+ * @summary Test currencies without minor units.
+ * @run junit NoMinorUnitCurrenciesTest
+ */
+
+import java.util.Currency;
+import java.util.stream.Stream;
+
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class NoMinorUnitCurrenciesTest {
+
+    /**
+     * Spot check some minor undefined currencies and ensure their default fraction
+     * digits are not 2.
+     */
+    @ParameterizedTest
+    @MethodSource("minorUndefined")
+    public void checkFractionDigits(String currencyCode, int digits) {
+        Currency currency = Currency.getInstance(currencyCode);
+        assertEquals(currency.getCurrencyCode(), currencyCode);
+        assertEquals(currency.getDefaultFractionDigits(), digits, String.format(
+                "[%s] expected: %s; got: %s", currencyCode, digits, currency.getDefaultFractionDigits()));
+    }
+
+    // Currencies from the minorUndefined key of CurrencyData.properties
+    // (These are currencies without minor units)
+    private static Stream<Arguments> minorUndefined() {
+        return Stream.of(
+                Arguments.of("XBD", -1),
+                Arguments.of("XAG", -1),
+                Arguments.of("XAU", -1),
+                Arguments.of("XBA", -1),
+                Arguments.of("XBB", -1)
+        );
+    }
+}
diff --git a/test/jdk/java/util/Currency/NumCodeAsStringTest.java b/test/jdk/java/util/Currency/NumCodeAsStringTest.java
new file mode 100644
index 0000000..8bec085
--- /dev/null
+++ b/test/jdk/java/util/Currency/NumCodeAsStringTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8154295
+ * @summary Check getNumericCodeAsString() method which returns numeric code as a 3 digit String.
+ * @run junit NumCodeAsStringTest
+ */
+
+import java.util.Currency;
+import java.util.stream.Stream;
+
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class NumCodeAsStringTest {
+
+    /**
+     * Ensure getNumericCodeAsString() returns the correct 3-digit numeric code
+     * for the associated currency Code.
+     */
+    @ParameterizedTest
+    @MethodSource("codeProvider")
+    public void checkNumCodeTest(String currCode, String expectedNumCode) {
+        String actualNumCode = Currency.getInstance(currCode).getNumericCodeAsString();
+        assertEquals(expectedNumCode, actualNumCode, String.format(
+                "Expected: %s, but got: %s, for %s", expectedNumCode, actualNumCode, currCode));
+    }
+
+    private static Stream<Arguments> codeProvider() {
+        return Stream.of(
+                Arguments.of("AFA", "004"),
+                Arguments.of("AUD", "036"),
+                Arguments.of("USD", "840")
+        );
+    }
+}
diff --git a/test/jdk/java/util/Currency/PropertiesTest.sh b/test/jdk/java/util/Currency/PropertiesTest.sh
deleted file mode 100644
index 6e8bbc2..0000000
--- a/test/jdk/java/util/Currency/PropertiesTest.sh
+++ /dev/null
@@ -1,144 +0,0 @@
-#!/bin/sh
-
-# Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-# @test
-# @bug 6332666 6863624 7180362 8003846 8074350 8074351 8130246 8149735 7102969
-#      8157138 8190904
-# @summary tests the capability of replacing the currency data with user
-#     specified currency properties file
-# @build PropertiesTest
-# @run shell/timeout=600 PropertiesTest.sh
-
-if [ "${TESTSRC}" = "" ]
-then
-  echo "TESTSRC not set.  Test cannot execute.  Failed."
-  exit 1
-fi
-echo "TESTSRC=${TESTSRC}"
-if [ "${TESTJAVA}" = "" ]
-then
-  echo "TESTJAVA not set.  Test cannot execute.  Failed."
-  exit 1
-fi
-echo "TESTJAVA=${TESTJAVA}"
-if [ "${TESTCLASSES}" = "" ]
-then
-  echo "TESTCLASSES not set.  Test cannot execute.  Failed."
-  exit 1
-fi
-echo "TESTCLASSES=${TESTCLASSES}"
-echo "CLASSPATH=${CLASSPATH}"
-
-# set platform-dependent variables
-OS=`uname -s`
-case "$OS" in
-  Linux | Darwin | AIX )
-    PS=":"
-    FS="/"
-    ;;
-  Windows* )
-    PS=";"
-    FS="/"
-    ;;
-  CYGWIN*|MSYS*|MINGW* )
-    PS=";"
-    FS="/"
-    TESTJAVA=`cygpath -u ${TESTJAVA}`
-    ;;
-  * )
-    echo "Unrecognized system!"
-    exit 1;
-    ;;
-esac
-
-failures=0
-
-run() {
-    echo ''
-    ${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -cp ${TESTCLASSES} $* 2>&1
-    if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
-}
-
-PROPS=${TESTSRC}${FS}currency.properties
-
-
-# Dump built-in currency data
-
-run PropertiesTest -d dump1
-if [ ! -f dump1 ]; then  echo "file dump1 not created. Test cannot execute.  Failed."; exit 1; fi
-
-# Dump built-in currency data + overrides in properties file specified
-# by system property.
-
-run -Djava.util.currency.data=${PROPS} PropertiesTest -d dump2
-if [ ! -f dump2 ]; then  echo "file dump2 not created. Test cannot execute.  Failed."; exit 1; fi
-run PropertiesTest -c dump1 dump2 ${PROPS}
-
-
-# Dump built-in currency data + overrides in properties file copied into
-# JRE image.
-
-# Make a private copy of the jdk so we can write to the properties file location
-# without disturbing other users, including concurrently executing tests.
-WRITABLEJDK=.${FS}testjava
-cp -H -R $TESTJAVA $WRITABLEJDK || exit 1
-PROPLOCATION=${WRITABLEJDK}${FS}lib
-chmod -R u+w $WRITABLEJDK || exit 1
-cp ${PROPS} $PROPLOCATION || exit 1
-echo "Properties location: ${PROPLOCATION}"
-
-# run
-echo ''
-${WRITABLEJDK}${FS}bin${FS}java ${TESTVMOPTS} -cp ${TESTCLASSES} PropertiesTest -d dump3
-if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
-if [ ! -f dump3 ]; then  echo "file dump3 not created. Test cannot execute.  Failed."; exit 1; fi
-
-# run bug7102969 test
-echo ''
-${WRITABLEJDK}${FS}bin${FS}java ${TESTVMOPTS} -cp ${TESTCLASSES} PropertiesTest bug7102969
-if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
-
-# run bug8157138 test
-echo ''
-${WRITABLEJDK}${FS}bin${FS}java ${TESTVMOPTS} -cp ${TESTCLASSES} PropertiesTest bug8157138
-if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
-
-# run bug8190904 test
-echo ''
-${WRITABLEJDK}${FS}bin${FS}java ${TESTVMOPTS} -cp ${TESTCLASSES} PropertiesTest bug8190904
-if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
-
-# Cleanup
-rm -rf $WRITABLEJDK
-
-# compare the two dump files
-run PropertiesTest -c dump1 dump3 ${PROPS}
-
-
-# Results
-echo ''
-if [ $failures -gt 0 ];
-  then echo "$failures tests failed";
-  else echo "All tests passed"; fi
-exit $failures
diff --git a/test/jdk/java/util/Currency/PropertiesTestRun.java b/test/jdk/java/util/Currency/PropertiesTestRun.java
new file mode 100644
index 0000000..6f2ea28
--- /dev/null
+++ b/test/jdk/java/util/Currency/PropertiesTestRun.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6332666 6863624 7180362 8003846 8074350 8074351 8130246 8149735 7102969
+ *      8157138 8190904 8210410
+ * @summary Tests the capability of replacing the currency data with a user
+ *          specified currency properties file in lib directory (old way) or
+ *          via the system property in the cmdline (new way).
+ * @library /test/lib
+ * @build PropertiesTest
+ * @run junit PropertiesTestRun
+ */
+
+import jdk.test.lib.Utils;
+import jdk.test.lib.process.ProcessTools;
+
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
+
+import java.util.Arrays;
+import java.util.stream.Stream;
+
+import static org.junit.jupiter.api.Assertions.fail;
+
+public class PropertiesTestRun {
+
+    // String paths used for the cmdline processes
+    private static final String TEST_JDK = Utils.TEST_JDK;
+    private static final String TEST_PROPS =
+            Utils.TEST_SRC+Utils.FILE_SEPARATOR+"currency.properties";
+    private static final String WRITABLE_JDK =
+            "."+Utils.FILE_SEPARATOR+"WRITABLE_JDK";
+    private static final String WRITABLE_JDK_LIB =
+            WRITABLE_JDK+Utils.FILE_SEPARATOR+"lib";
+    private static final String WRITABLE_JDK_BIN =
+            WRITABLE_JDK+Utils.FILE_SEPARATOR+"bin";
+    private static final String WRITABLE_JDK_JAVA_PATH =
+            WRITABLE_JDK_BIN + Utils.FILE_SEPARATOR + "java";
+
+    // Create a writable JDK and set up dumps 1-3
+    @BeforeAll
+    static void setUp() throws Throwable {
+        // Create separate JDK to supersede currencies via lib directory
+        createWritableJDK();
+        // Create dump without user defined prop file
+        executeTestJDKMethod("PropertiesTest", "-d", "dump1");
+        // Create dump with user defined prop file (via system property)
+        executeTestJDKMethod("-Djava.util.currency.data="+TEST_PROPS,
+                "PropertiesTest", "-d", "dump2");
+        // Create dump with user defined prop file (via lib)
+        executeWritableJDKMethod("PropertiesTest", "-d", "dump3");
+    }
+
+    // Need to create a separate JDK to insert the user defined properties file
+    // into the lib folder. Create separate JDK to not disturb current TEST JDK.
+    private static void createWritableJDK() throws Throwable {
+        // Copy Test JDK into a separate JDK folder
+        executeProcess(new String[]{"cp", "-H", "-R", TEST_JDK, WRITABLE_JDK});
+        // Make the separate JDK writable
+        executeProcess(new String[]{"chmod", "-R", "u+w", WRITABLE_JDK_LIB});
+        // Copy the properties file into the writable JDK lib folder
+        executeProcess(new String[]{"cp", TEST_PROPS, WRITABLE_JDK_LIB});
+    }
+
+    // Compares the dumped output is expected between the default currencies
+    // and the user-defined custom currencies
+    @Test
+    void compareDumps() throws Throwable {
+        // Compare dump (from sys prop)
+        executeTestJDKMethod("PropertiesTest", "-c", "dump1", "dump2",
+                TEST_PROPS);
+        // Compare dump (from lib)
+        executeTestJDKMethod("PropertiesTest", "-c", "dump1", "dump3",
+                TEST_PROPS);
+    }
+
+    // Launch a test from PropertiesTest. See PropertiesTest.java for more
+    // detail regarding a specific test that was launched.
+    @ParameterizedTest
+    @MethodSource("PropertiesTestMethods")
+    void launchPropertiesTests(String methodName) throws Throwable {
+        // Test via both the lib and system property
+        executeWritableJDKMethod("PropertiesTest", methodName);
+        executeTestJDKMethod("-Djava.util.currency.data="+TEST_PROPS,
+                "PropertiesTest", methodName);
+    }
+
+    private static Stream<String> PropertiesTestMethods() {
+        return Stream.of("bug7102969", "bug8157138", "bug8190904");
+    }
+
+    // Launch a PropertiesTest method using the TEST JDK
+    private static void executeTestJDKMethod(String... params) throws Throwable {
+        int exitStatus = ProcessTools.executeTestJvm(params).getExitValue();
+        if (exitStatus != 0) {
+            fail("Process started with: " + Arrays.toString(params) + " failed");
+        }
+    }
+
+    // Launch a PropertiesTest method using the WRITABLE JDK
+    private static void executeWritableJDKMethod(String... params) throws Throwable {
+        // Need to include WritableJDK javapath, TEST JDK classpath
+        String[] allParams = new String[3+params.length+Utils.getTestJavaOpts().length];
+        // We don't use executeTestJvm() because we want to point to separate JDK java path
+        allParams[0] = WRITABLE_JDK_JAVA_PATH;
+        allParams[1] = "-cp";
+        allParams[2] = System.getProperty("java.class.path");
+        // Add test.vm.opts and test.java.opts
+        System.arraycopy(Utils.getTestJavaOpts(), 0, allParams, 3,
+                Utils.getTestJavaOpts().length);
+        // Add the rest of the actual arguments
+        System.arraycopy(params, 0, allParams, Utils.getTestJavaOpts().length+3,
+                params.length);
+        // Launch the actual test method with all parameters set
+        executeProcess(allParams);
+    }
+
+    // Execute a process and fail if the command is not successful
+    private static void executeProcess(String[] params) throws Throwable {
+        System.out.println("Command line: " + Arrays.toString(params));
+        int exitStatus = ProcessTools.executeProcess(params).getExitValue();
+        if (exitStatus != 0) {
+            fail("Process started with: " + Arrays.toString(params) + " failed");
+        }
+    }
+
+    @AfterAll
+    static void tearDown() throws Throwable {
+        // Remove the copied writable JDK image from scratch folder
+        executeProcess(new String[]{"rm", "-rf", WRITABLE_JDK});
+    }
+}
diff --git a/test/jdk/java/util/Currency/ValidateISO4217.java b/test/jdk/java/util/Currency/ValidateISO4217.java
index 1644153..3d2bae0 100644
--- a/test/jdk/java/util/Currency/ValidateISO4217.java
+++ b/test/jdk/java/util/Currency/ValidateISO4217.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -20,293 +20,303 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
+
 /*
  * @test
  * @bug 4691089 4819436 4942982 5104960 6544471 6627549 7066203 7195759
  *      8039317 8074350 8074351 8145952 8187946 8193552 8202026 8204269
- *      8208746 8209775 8264792 8274658 8283277 8296239
+ *      8208746 8209775 8264792 8274658 8283277 8296239 8321480
  * @summary Validate ISO 4217 data for Currency class.
  * @modules java.base/java.util:open
  *          jdk.localedata
+ * @run junit ValidateISO4217
  */
 
-/*
- * ############################################################################
- *
- *  ValidateISO4217 is a tool to detect differences between the latest ISO 4217
- *  data and Java's currency data which is based on ISO 4217.
- *  If there is a difference, the following file which includes currency data
- *  may need to be updated.
- *      src/share/classes/java/util/CurrencyData.properties
- *
- * ############################################################################
- *
- * 1) Make a golden-data file.
- *      From BSi's ISO4217 data (TABLE A1.doc), extract four (or eight, if currency is changing)
- *      fields and save as ./tablea1.txt.
- *        <Country code>\t<Currency code>\t<Numeric code>\t<Minor unit>[\t<Cutover Date>\t<new Currency code>\t<new Numeric code>\t<new Minor unit>]
- *      The Cutover Date is given in SimpleDateFormat's 'yyyy-MM-dd-HH-mm-ss' format in the GMT time zone.
- *
- * 2) Compile ValidateISO4217.java
- *
- * 3) Execute ValidateISO4217 as follows:
- *      java ValidateISO4217
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Currency;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.TimeZone;
+
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * This class tests the latest ISO 4217 data and Java's currency data which is
+ * based on ISO 4217. The golden-data file (ISO 4217 data) 'tablea1.txt' has the following
+ * format: <Country code>\t<Currency code>\t<Numeric code>\t<Minor unit>[\t<Cutover Date>\t<new Currency code>\t<new Numeric code>\t<new Minor unit>]
+ * The Cutover Date is given in SimpleDateFormat's 'yyyy-MM-dd-HH-mm-ss' format in the GMT time zone.
  */
-
-import java.io.*;
-import java.text.*;
-import java.util.*;
-
 public class ValidateISO4217 {
 
-    static final int ALPHA_NUM = 26;
-
-    static final byte UNDEFINED = 0;
-    static final byte DEFINED = 1;
-    static final byte SKIPPED = 2;
-
-    /* input files */
-    static final String datafile = "tablea1.txt";
-
-    /* alpha2-code table */
-    static byte[] codes = new byte[ALPHA_NUM * ALPHA_NUM];
-
-    static final String[][] additionalCodes = {
-        /* Defined in ISO 4217 list, but don't have code and minor unit info. */
-        {"AQ", "", "", "0"},    // Antarctica
-
-        /*
-         * Defined in ISO 4217 list, but don't have code and minor unit info in
-         * it. On the other hand, both code and minor unit are defined in
-         * .properties file. I don't know why, though.
-         */
-        {"GS", "GBP", "826", "2"},      // South Georgia And The South Sandwich Islands
-
-        /* Not defined in ISO 4217 list, but defined in .properties file. */
-        {"AX", "EUR", "978", "2"},      // \u00c5LAND ISLANDS
-        {"PS", "ILS", "376", "2"},      // Palestinian Territory, Occupied
-
-        /* Not defined in ISO 4217 list, but added in ISO 3166 country code list */
-        {"JE", "GBP", "826", "2"},      // Jersey
-        {"GG", "GBP", "826", "2"},      // Guernsey
-        {"IM", "GBP", "826", "2"},      // Isle of Man
-        {"BL", "EUR", "978", "2"},      // Saint Barthelemy
-        {"MF", "EUR", "978", "2"},      // Saint Martin
-
-        /* Defined neither in ISO 4217 nor ISO 3166 list */
-        {"XK", "EUR", "978", "2"},      // Kosovo
+    // Input golden-data file
+    private static final File dataFile = new File(System.getProperty(
+            "test.src", "."), "tablea1.txt");
+    // Code statuses
+    private static final byte UNDEFINED = 0;
+    private static final byte DEFINED = 1;
+    private static final byte SKIPPED = 2;
+    private static final byte TESTED = 4;
+    private static final int ALPHA_NUM = 26;
+    // An alpha2 code table which maps the status of a country
+    private static final byte[] codes = new byte[ALPHA_NUM * ALPHA_NUM];
+    // Codes derived from ISO4217 golden-data file
+    private static final List<Arguments> ISO4217Codes = new ArrayList<Arguments>();
+    // Additional codes not from the ISO4217 golden-data file
+    private static final List<Arguments> additionalCodes = new ArrayList<Arguments>();
+    // Currencies to test (derived from ISO4217Codes and additionalCodes)
+    private static final Set<Currency> testCurrencies = new HashSet<>();
+    // Codes that are obsolete, do not have related country, extra currency
+    private static final String otherCodes =
+            "ADP-AFA-ATS-AYM-AZM-BEF-BGL-BOV-BYB-BYR-CHE-CHW-CLF-COU-CUC-CYP-"
+                    + "DEM-EEK-ESP-FIM-FRF-GHC-GRD-GWP-HRK-IEP-ITL-LTL-LUF-LVL-MGF-MRO-MTL-MXV-MZM-NLG-"
+                    + "PTE-ROL-RUR-SDD-SIT-SLL-SKK-SRG-STD-TMM-TPE-TRL-VEF-UYI-USN-USS-VEB-VED-"
+                    + "XAG-XAU-XBA-XBB-XBC-XBD-XDR-XFO-XFU-XPD-XPT-XSU-XTS-XUA-XXX-"
+                    + "YUM-ZMK-ZWD-ZWN-ZWR";
+    private static final String[][] extraCodes = {
+            /* Defined in ISO 4217 list, but don't have code and minor unit info. */
+            {"AQ", "", "", "0"},    // Antarctica
+            /*
+             * Defined in ISO 4217 list, but don't have code and minor unit info in
+             * it. On the other hand, both code and minor unit are defined in
+             * .properties file. I don't know why, though.
+             */
+            {"GS", "GBP", "826", "2"},      // South Georgia And The South Sandwich Islands
+            /* Not defined in ISO 4217 list, but defined in .properties file. */
+            {"AX", "EUR", "978", "2"},      // \u00c5LAND ISLANDS
+            {"PS", "ILS", "376", "2"},      // Palestinian Territory, Occupied
+            /* Not defined in ISO 4217 list, but added in ISO 3166 country code list */
+            {"JE", "GBP", "826", "2"},      // Jersey
+            {"GG", "GBP", "826", "2"},      // Guernsey
+            {"IM", "GBP", "826", "2"},      // Isle of Man
+            {"BL", "EUR", "978", "2"},      // Saint Barthelemy
+            {"MF", "EUR", "978", "2"},      // Saint Martin
+            /* Defined neither in ISO 4217 nor ISO 3166 list */
+            {"XK", "EUR", "978", "2"},      // Kosovo
     };
+    private static SimpleDateFormat format = null;
 
-    /* Codes that are obsolete, do not have related country, extra currency */
-    static final String otherCodes =
-        "ADP-AFA-ATS-AYM-AZM-BEF-BGL-BOV-BYB-BYR-CHE-CHW-CLF-COU-CUC-CYP-"
-        + "DEM-EEK-ESP-FIM-FRF-GHC-GRD-GWP-IEP-ITL-LTL-LUF-LVL-MGF-MRO-MTL-MXV-MZM-NLG-"
-        + "PTE-ROL-RUR-SDD-SIT-SLL-SKK-SRG-STD-TMM-TPE-TRL-VEF-UYI-USN-USS-VEB-VED-"
-        + "XAG-XAU-XBA-XBB-XBC-XBD-XDR-XFO-XFU-XPD-XPT-XSU-XTS-XUA-XXX-"
-        + "YUM-ZMK-ZWD-ZWN-ZWR";
-
-    static boolean err = false;
-
-    static Set<Currency> testCurrencies = new HashSet<Currency>();
-
-    public static void main(String[] args) throws Exception {
-        CheckDataVersion.check();
-        test1();
-        test2();
-        getAvailableCurrenciesTest();
-
-        if (err) {
-            throw new RuntimeException("Failed: Validation ISO 4217 data");
-        }
+    // Sets up the following test data:
+    // ISO4217Codes, additionalCodes, testCurrencies, codes
+    @BeforeAll
+    static void setUpTestingData() throws Exception {
+        // These functions laterally setup 'testCurrencies' and 'codes'
+        // at the same time
+        setUpISO4217Codes();
+        setUpAdditionalCodes();
+        setUpOtherCurrencies();
     }
 
-    static void test1() throws Exception {
-
-        try (FileReader fr = new FileReader(new File(System.getProperty("test.src", "."), datafile));
+    // Parse the ISO4217 file and populate ISO4217Codes and testCurrencies.
+    private static void setUpISO4217Codes() throws Exception{
+        try (FileReader fr = new FileReader(dataFile);
              BufferedReader in = new BufferedReader(fr))
         {
             String line;
-            SimpleDateFormat format = null;
-
             while ((line = in.readLine()) != null) {
                 if (line.length() == 0 || line.charAt(0) == '#') {
+                    // Skip comments and empty lines
                     continue;
                 }
-
                 StringTokenizer tokens = new StringTokenizer(line, "\t");
                 String country = tokens.nextToken();
                 if (country.length() != 2) {
+                    // Skip invalid countries
                     continue;
                 }
+                // If the country is valid, process the additional columns
+                processColumns(tokens, country);
+            }
+        }
+    }
 
-                String currency;
-                String numeric;
-                String minorUnit;
-                int tokensCount = tokens.countTokens();
-                if (tokensCount < 3) {
-                    currency = "";
-                    numeric = "0";
-                    minorUnit = "0";
-                } else {
+    private static void processColumns(StringTokenizer tokens, String country) throws ParseException {
+        String currency;
+        String numeric;
+        String minorUnit;
+        int tokensCount = tokens.countTokens();
+        if (tokensCount < 3) {
+            // Ill-defined columns
+            currency = "";
+            numeric = "0";
+            minorUnit = "0";
+        } else {
+            // Fully defined columns
+            currency = tokens.nextToken();
+            numeric = tokens.nextToken();
+            minorUnit = tokens.nextToken();
+            testCurrencies.add(Currency.getInstance(currency));
+            // Check for the cut-over if a currency is changing
+            if (tokensCount > 3) {
+                if (format == null) {
+                    createDateFormat();
+                }
+                // If the cut-over already passed, use the new curency for ISO4217Codes
+                if (format.parse(tokens.nextToken()).getTime() < System.currentTimeMillis()) {
                     currency = tokens.nextToken();
                     numeric = tokens.nextToken();
                     minorUnit = tokens.nextToken();
                     testCurrencies.add(Currency.getInstance(currency));
-
-                    // check for the cutover
-                    if (tokensCount > 3) {
-                        if (format == null) {
-                            format = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss", Locale.US);
-                            format.setTimeZone(TimeZone.getTimeZone("GMT"));
-                            format.setLenient(false);
-                        }
-                        if (format.parse(tokens.nextToken()).getTime() <
-                            System.currentTimeMillis()) {
-                            currency = tokens.nextToken();
-                            numeric = tokens.nextToken();
-                            minorUnit = tokens.nextToken();
-                            testCurrencies.add(Currency.getInstance(currency));
-                        }
-                    }
                 }
-                int index = toIndex(country);
-                testCountryCurrency(country, currency, Integer.parseInt(numeric),
-                    Integer.parseInt(minorUnit), index);
             }
         }
+        int index = toIndex(country);
+        ISO4217Codes.add(Arguments.of(country, currency, Integer.parseInt(numeric),
+                Integer.parseInt(minorUnit), index));
+        codes[index] = DEFINED;
+    }
 
-        for (int i = 0; i < additionalCodes.length; i++) {
-            int index = toIndex(additionalCodes[i][0]);
-            if (additionalCodes[i][1].length() != 0) {
-                testCountryCurrency(additionalCodes[i][0], additionalCodes[i][1],
-                    Integer.parseInt(additionalCodes[i][2]),
-                    Integer.parseInt(additionalCodes[i][3]), index);
-                testCurrencies.add(Currency.getInstance(additionalCodes[i][1]));
+    // Generates a unique index for an alpha-2 country
+    private static int toIndex(String country) {
+        return ((country.charAt(0) - 'A') * ALPHA_NUM + country.charAt(1) - 'A');
+    }
+
+    private static void createDateFormat() {
+        format = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss", Locale.US);
+        format.setTimeZone(TimeZone.getTimeZone("GMT"));
+        format.setLenient(false);
+    }
+
+    // Process 'extraCodes', turning them into JUnit arguments and populate
+    // both additionalCodes and testCurrencies.
+    private static void setUpAdditionalCodes() {
+        for (String[] extraCode : extraCodes) {
+            int index = toIndex(extraCode[0]);
+            if (extraCode[1].length() != 0) {
+                additionalCodes.add(Arguments.of(extraCode[0], extraCode[1],
+                        Integer.parseInt(extraCode[2]), Integer.parseInt(extraCode[3]), index));
+                testCurrencies.add(Currency.getInstance(extraCode[1]));
             } else {
-                codes[index] = SKIPPED;
+                codes[index] = SKIPPED; // For example, Antarctica
             }
         }
     }
 
-    static int toIndex(String s) {
-        return ((s.charAt(0) - 'A') * ALPHA_NUM + s.charAt(1) - 'A');
-    }
-
-    static void testCountryCurrency(String country, String currencyCode,
-                                int numericCode, int digits, int index) {
-        if (currencyCode.length() == 0) {
-            return;
-        }
-        testCurrencyDefined(currencyCode, numericCode, digits);
-
-        Locale loc = new Locale("", country);
-        try {
-            Currency currency = Currency.getInstance(loc);
-            if (!currency.getCurrencyCode().equals(currencyCode)) {
-                System.err.println("Error: [" + country + ":" +
-                    loc.getDisplayCountry() + "] expected: " + currencyCode +
-                    ", got: " + currency.getCurrencyCode());
-                err = true;
-            }
-
-            if (codes[index] != UNDEFINED) {
-                System.out.println("Warning: [" + country + ":" +
-                    loc.getDisplayCountry() +
-                    "] multiple definitions. currency code=" + currencyCode);
-            }
-            codes[index] = DEFINED;
-        }
-        catch (Exception e) {
-            System.err.println("Error: " + e + ": Country=" + country);
-            err = true;
-        }
-    }
-
-    static void testCurrencyDefined(String currencyCode, int numericCode, int digits) {
-        try {
-            Currency currency = currency = Currency.getInstance(currencyCode);
-
-            if (currency.getNumericCode() != numericCode) {
-                System.err.println("Error: [" + currencyCode + "] expected: " +
-                    numericCode + "; got: " + currency.getNumericCode());
-                err = true;
-            }
-
-            if (currency.getDefaultFractionDigits() != digits) {
-                System.err.println("Error: [" + currencyCode + "] expected: " +
-                    digits + "; got: " + currency.getDefaultFractionDigits());
-                err = true;
-            }
-        }
-        catch (Exception e) {
-            System.err.println("Error: " + e + ": Currency code=" +
-                currencyCode);
-            err = true;
-        }
-    }
-
-    static void test2() {
-        for (int i = 0; i < ALPHA_NUM; i++) {
-            for (int j = 0; j < ALPHA_NUM; j++) {
-                char[] code = new char[2];
-                code[0] = (char)('A'+ i);
-                code[1] = (char)('A'+ j);
-                String country = new String(code);
-                boolean ex;
-
-                if (codes[toIndex(country)] == UNDEFINED) {
-                    ex = false;
-                    try {
-                        Currency.getInstance(new Locale("", country));
-                    }
-                    catch (IllegalArgumentException e) {
-                        ex = true;
-                    }
-                    if (!ex) {
-                        System.err.println("Error: This should be an undefined code and throw IllegalArgumentException: " +
-                            country);
-                        err = true;
-                    }
-                } else if (codes[toIndex(country)] == SKIPPED) {
-                    Currency cur = null;
-                    try {
-                        cur = Currency.getInstance(new Locale("", country));
-                    }
-                    catch (Exception e) {
-                        System.err.println("Error: " + e + ": Country=" +
-                            country);
-                        err = true;
-                    }
-                    if (cur != null) {
-                        System.err.println("Error: Currency.getInstance() for an this locale should return null: " +
-                            country);
-                        err = true;
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * This test depends on test1(), where 'testCurrencies' set is constructed
-     */
-    static void getAvailableCurrenciesTest() {
-        Set<Currency> jreCurrencies = Currency.getAvailableCurrencies();
-
-        // add otherCodes
+    // The previous set-up method populated most of testCurrencies. This
+    // method finishes populating the list with 'otherCodes'.
+    private static void setUpOtherCurrencies() {
+        // Add otherCodes
         StringTokenizer st = new StringTokenizer(otherCodes, "-");
         while (st.hasMoreTokens()) {
             testCurrencies.add(Currency.getInstance(st.nextToken()));
         }
+    }
 
-        if (!testCurrencies.containsAll(jreCurrencies)) {
-            System.err.print("Error: getAvailableCurrencies() returned extra currencies than expected: ");
-            jreCurrencies.removeAll(testCurrencies);
-            for (Currency c : jreCurrencies) {
-                System.err.print(" "+c);
+    // Check that the data file is up-to-date
+    @Test
+    public void dataVersionTest() {
+        CheckDataVersion.check();
+    }
+
+    /**
+     * Tests the JDK's ISO4217 data and ensures the values for getNumericCode(),
+     * getDefaultFractionDigits(), and getCurrencyCode() are as expected.
+     */
+    @ParameterizedTest
+    @MethodSource({"ISO4217CodesProvider", "additionalCodesProvider"})
+    public void countryCurrencyTest(String country, String currencyCode,
+                                    int numericCode, int digits, int index) {
+        currencyTest(currencyCode, numericCode, digits);
+        countryTest(country, currencyCode);
+        assertNotEquals(codes[index], TESTED,
+                "Error: Re-testing a previously defined code, possible duplication");
+        codes[index] = TESTED;
+    }
+
+    // Test a Currency built from currencyCode
+    private static void currencyTest(String currencyCode, int numericCode, int digits) {
+        Currency currency = Currency.getInstance(currencyCode);
+        assertEquals(currency.getNumericCode(), numericCode);
+        assertEquals(currency.getDefaultFractionDigits(), digits);
+    }
+
+    // Test a Currency built from country
+    private static void countryTest(String country, String currencyCode) {
+        Locale loc = new Locale("", country);
+        Currency currency = Currency.getInstance(loc);
+        assertEquals(currency.getCurrencyCode(), currencyCode);
+    }
+
+    private static List<Arguments> ISO4217CodesProvider() {
+        return ISO4217Codes;
+    }
+
+    private static List<Arguments> additionalCodesProvider() {
+        return additionalCodes;
+    }
+
+    /**
+     * Tests trying to create a Currency from an invalid alpha-2 country either
+     * throws an IllegalArgumentException or returns null. The test data
+     * supplied is every possible combination of AA -> ZZ.
+     */
+    @Test
+    public void twoLetterCodesTest() {
+        for (String country : codeCombos()) {
+            if (codes[toIndex(country)] == UNDEFINED) {
+                // if a code is undefined / 0, creating a Currency from it
+                // should throw an IllegalArgumentException
+                assertThrows(IllegalArgumentException.class,
+                        () -> Currency.getInstance(new Locale("", country)),
+                        "Error: This should be an undefined code and throw IllegalArgumentException: " + country);
+            } else if (codes[toIndex(country)] == SKIPPED) {
+                // if a code is marked as skipped / 2, creating a Currency from it
+                // should return null
+                assertNull(Currency.getInstance(new Locale("", country)),
+                        "Error: Currency.getInstance() for this locale should return null: " + country);
             }
-            System.err.println();
-            err = true;
         }
     }
-}
+
+    // This method generates code combos from AA to ZZ
+    private static List<String> codeCombos() {
+        List<String> codeCombos = new ArrayList<>();
+        for (int i = 0; i < ALPHA_NUM; i++) {
+            for (int j = 0; j < ALPHA_NUM; j++) {
+                char[] code = new char[2];
+                code[0] = (char) ('A' + i);
+                code[1] = (char) ('A' + j);
+                codeCombos.add(new String(code));
+            }
+        }
+        return codeCombos;
+    }
+
+    // This method ensures that getAvailableCurrencies() returns
+    // the expected amount of currencies.
+    @Test
+    public void getAvailableCurrenciesTest() {
+        Set<Currency> jreCurrencies = Currency.getAvailableCurrencies();
+        // Ensure that testCurrencies has all the JRE currency codes
+        assertTrue(testCurrencies.containsAll(jreCurrencies),
+                getSetDiffs(jreCurrencies, testCurrencies));
+    }
+
+    private static String getSetDiffs(Set<Currency> jreCurrencies, Set<Currency> testCurrencies) {
+        StringBuilder bldr = new StringBuilder();
+        bldr.append("Error: getAvailableCurrencies() returned unexpected currencies: ");
+        jreCurrencies.removeAll(testCurrencies);
+        for (Currency curr : jreCurrencies) {
+            bldr.append(" " + curr);
+        }
+        bldr.append("\n");
+        return bldr.toString();
+    }
+}
\ No newline at end of file
diff --git a/test/jdk/java/util/Currency/tablea1.txt b/test/jdk/java/util/Currency/tablea1.txt
index 4e33a62..6e85de5 100644
--- a/test/jdk/java/util/Currency/tablea1.txt
+++ b/test/jdk/java/util/Currency/tablea1.txt
@@ -1,12 +1,12 @@
 #
 #
-# Amendments up until ISO 4217 AMENDMENT NUMBER 175
-#   (As of 31 March 2023)
+# Amendments up until ISO 4217 AMENDMENT NUMBER 176
+#   (As of 06 December 2023)
 #
 
 # Version
 FILEVERSION=3
-DATAVERSION=175
+DATAVERSION=176
 
 # ISO 4217 currency data
 AF	AFN	971	2
@@ -67,9 +67,9 @@
 CK	NZD	554	2
 CR	CRC	188	2
 CI	XOF	952	0
-HR	HRK	191	2	2022-12-31-23-00-00	EUR	978	2
+HR	EUR	978	2
 CU	CUP	192	2
-CW	ANG	532	2
+CW	ANG	532	2	2025-04-01-04-00-00	XCG	532	2
 CY	EUR	978	2
 CZ	CZK	203	2
 DK	DKK	208	2
@@ -233,7 +233,7 @@
 SD	SDG	938	2
 SR	SRD	968	2
 SJ	NOK	578	2
-SX	ANG	532	2
+SX	ANG	532	2	2025-04-01-04-00-00	XCG	532	2
 SZ	SZL	748	2
 SE	SEK	752	2
 CH	CHF	756	2
diff --git a/test/jdk/java/util/TimeZone/TimeZoneData/VERSION b/test/jdk/java/util/TimeZone/TimeZoneData/VERSION
index c5483b4..bf02791 100644
--- a/test/jdk/java/util/TimeZone/TimeZoneData/VERSION
+++ b/test/jdk/java/util/TimeZone/TimeZoneData/VERSION
@@ -1 +1 @@
-tzdata2023c
+tzdata2024a
diff --git a/test/jdk/java/util/TimeZone/TimeZoneData/aliases.txt b/test/jdk/java/util/TimeZone/TimeZoneData/aliases.txt
index 07c5edb..82bad17 100644
--- a/test/jdk/java/util/TimeZone/TimeZoneData/aliases.txt
+++ b/test/jdk/java/util/TimeZone/TimeZoneData/aliases.txt
@@ -148,7 +148,6 @@
 Link	Pacific/Port_Moresby	Antarctica/DumontDUrville
 Link	Pacific/Auckland	Antarctica/McMurdo
 Link	Asia/Riyadh		Antarctica/Syowa
-Link	Asia/Urumqi		Antarctica/Vostok
 Link	Europe/Berlin		Arctic/Longyearbyen
 Link	Asia/Riyadh		Asia/Aden
 Link	Asia/Qatar		Asia/Bahrain
diff --git a/test/jdk/javax/net/ssl/ALPN/SSLEngineAlpnTest.java b/test/jdk/javax/net/ssl/ALPN/SSLEngineAlpnTest.java
index ca4af27..3a0397d 100644
--- a/test/jdk/javax/net/ssl/ALPN/SSLEngineAlpnTest.java
+++ b/test/jdk/javax/net/ssl/ALPN/SSLEngineAlpnTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@
  * @test
  * @bug 8051498 8145849 8170282
  * @summary JEP 244: TLS Application-Layer Protocol Negotiation Extension
+ * @library /javax/net/ssl/templates
  *
  * @run main/othervm SSLEngineAlpnTest h2          UNUSED   h2          h2
  * @run main/othervm SSLEngineAlpnTest h2          UNUSED   h2,http/1.1 h2
@@ -124,12 +125,9 @@
  */
 import javax.net.ssl.*;
 import javax.net.ssl.SSLEngineResult.*;
-import java.io.*;
-import java.security.*;
-import java.nio.*;
 import java.util.Arrays;
 
-public class SSLEngineAlpnTest {
+public class SSLEngineAlpnTest extends SSLEngineTemplate {
 
     /*
      * Enables logging of the SSLEngine operations.
@@ -147,41 +145,8 @@
      */
     private static final boolean debug = false;
 
-    private static boolean hasServerAPs; // whether server APs are present
     private static boolean hasCallback; // whether a callback is present
 
-    private final SSLContext sslc;
-
-    private SSLEngine clientEngine;     // client Engine
-    private ByteBuffer clientOut;       // write side of clientEngine
-    private ByteBuffer clientIn;        // read side of clientEngine
-
-    private SSLEngine serverEngine;     // server Engine
-    private ByteBuffer serverOut;       // write side of serverEngine
-    private ByteBuffer serverIn;        // read side of serverEngine
-
-    /*
-     * For data transport, this example uses local ByteBuffers.  This
-     * isn't really useful, but the purpose of this example is to show
-     * SSLEngine concepts, not how to do network transport.
-     */
-    private ByteBuffer cTOs;            // "reliable" transport client->server
-    private ByteBuffer sTOc;            // "reliable" transport server->client
-
-    /*
-     * The following is to set up the keystores.
-     */
-    private static final String pathToStores = "../etc";
-    private static final String keyStoreFile = "keystore";
-    private static final String trustStoreFile = "truststore";
-    private static final String passwd = "passphrase";
-
-    private static final String keyFilename
-            = System.getProperty("test.src", ".") + "/" + pathToStores
-            + "/" + keyStoreFile;
-    private static final String trustFilename
-            = System.getProperty("test.src", ".") + "/" + pathToStores
-            + "/" + trustStoreFile;
 
     /*
      * Main entry point for this test.
@@ -198,10 +163,9 @@
             throw new Exception("Invalid number of test parameters");
         }
 
-        hasServerAPs = !args[0].equals("UNUSED"); // are server APs being used?
         hasCallback = !args[1].equals("UNUSED"); // is callback being used?
 
-        SSLEngineAlpnTest test = new SSLEngineAlpnTest(args[3]);
+        SSLEngineAlpnTest test = new SSLEngineAlpnTest();
         try {
             test.runTest(convert(args[0]), args[1], convert(args[2]), args[3]);
         } catch (SSLHandshakeException she) {
@@ -215,35 +179,8 @@
         System.out.println("Test Passed.");
     }
 
-    /*
-     * Create an initialized SSLContext to use for these tests.
-     */
-    public SSLEngineAlpnTest(String expectedAP) throws Exception {
-
-        KeyStore ks = KeyStore.getInstance("JKS");
-        KeyStore ts = KeyStore.getInstance("JKS");
-
-        char[] passphrase = "passphrase".toCharArray();
-
-        ks.load(new FileInputStream(keyFilename), passphrase);
-        ts.load(new FileInputStream(trustFilename), passphrase);
-
-        KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
-        kmf.init(ks, passphrase);
-
-        KeyManager [] kms = kmf.getKeyManagers();
-        if (!(kms[0] instanceof X509ExtendedKeyManager)) {
-            throw new Exception("kms[0] not X509ExtendedKeyManager");
-        }
-
-        TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
-        tmf.init(ts);
-
-        SSLContext sslCtx = SSLContext.getInstance("TLS");
-
-        sslCtx.init(kms, tmf.getTrustManagers(), null);
-
-        sslc = sslCtx;
+    public SSLEngineAlpnTest() throws Exception {
+        super();
     }
 
     /*
@@ -290,8 +227,7 @@
 
         boolean dataDone = false;
 
-        createSSLEngines(serverAPs, callbackAP, clientAPs);
-        createBuffers();
+        configureSSLEngines(serverAPs, callbackAP, clientAPs);
 
         SSLEngineResult clientResult;   // results from client's last operation
         SSLEngineResult serverResult;   // results from server's last operation
@@ -311,12 +247,12 @@
 
             clientResult = clientEngine.wrap(clientOut, cTOs);
             log("client wrap: ", clientResult);
-            runDelegatedTasks(clientResult, clientEngine);
+            runDelegatedTasks(clientEngine);
             checkAPResult(clientEngine, clientResult, expectedAP);
 
             serverResult = serverEngine.wrap(serverOut, sTOc);
             log("server wrap: ", serverResult);
-            runDelegatedTasks(serverResult, serverEngine);
+            runDelegatedTasks(serverEngine);
             checkAPResult(serverEngine, serverResult, expectedAP);
 
             cTOs.flip();
@@ -326,12 +262,12 @@
 
             clientResult = clientEngine.unwrap(sTOc, clientIn);
             log("client unwrap: ", clientResult);
-            runDelegatedTasks(clientResult, clientEngine);
+            runDelegatedTasks(clientEngine);
             checkAPResult(clientEngine, clientResult, expectedAP);
 
             serverResult = serverEngine.unwrap(cTOs, serverIn);
             log("server unwrap: ", serverResult);
-            runDelegatedTasks(serverResult, serverEngine);
+            runDelegatedTasks(serverEngine);
             checkAPResult(serverEngine, serverResult, expectedAP);
 
             cTOs.compact();
@@ -403,13 +339,12 @@
      * Using the SSLContext created during object creation,
      * create/configure the SSLEngines we'll use for this test.
      */
-    private void createSSLEngines(String[] serverAPs, String callbackAP,
+    private void configureSSLEngines(String[] serverAPs, String callbackAP,
             String[] clientAPs) throws Exception {
         /*
          * Configure the serverEngine to act as a server in the SSL/TLS
          * handshake.  Also, require SSL client authentication.
          */
-        serverEngine = sslc.createSSLEngine();
         serverEngine.setUseClientMode(false);
 
         SSLParameters sslp = serverEngine.getSSLParameters();
@@ -454,7 +389,6 @@
         /*
          * Similar to above, but using client mode instead.
          */
-        clientEngine = sslc.createSSLEngine("client", 80);
         clientEngine.setUseClientMode(true);
         sslp = clientEngine.getSSLParameters();
         if (clientAPs != null) {
@@ -469,83 +403,10 @@
         }
     }
 
-    /*
-     * Create and size the buffers appropriately.
-     */
-    private void createBuffers() {
-
-        /*
-         * We'll assume the buffer sizes are the same
-         * between client and server.
-         */
-        SSLSession session = clientEngine.getSession();
-        int appBufferMax = session.getApplicationBufferSize();
-        int netBufferMax = session.getPacketBufferSize();
-
-        /*
-         * We'll make the input buffers a bit bigger than the max needed
-         * size, so that unwrap()s following a successful data transfer
-         * won't generate BUFFER_OVERFLOWS.
-         *
-         * We'll use a mix of direct and indirect ByteBuffers for
-         * tutorial purposes only.  In reality, only use direct
-         * ByteBuffers when they give a clear performance enhancement.
-         */
-        clientIn = ByteBuffer.allocate(appBufferMax + 50);
-        serverIn = ByteBuffer.allocate(appBufferMax + 50);
-
-        cTOs = ByteBuffer.allocateDirect(netBufferMax);
-        sTOc = ByteBuffer.allocateDirect(netBufferMax);
-
-        clientOut = ByteBuffer.wrap("Hi Server, I'm Client".getBytes());
-        serverOut = ByteBuffer.wrap("Hello Client, I'm Server".getBytes());
-    }
-
-    /*
-     * If the result indicates that we have outstanding tasks to do,
-     * go ahead and run them in this thread.
-     */
-    private static void runDelegatedTasks(SSLEngineResult result,
-            SSLEngine engine) throws Exception {
-
-        if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
-            Runnable runnable;
-            while ((runnable = engine.getDelegatedTask()) != null) {
-                log("\trunning delegated task...");
-                runnable.run();
-            }
-            HandshakeStatus hsStatus = engine.getHandshakeStatus();
-            if (hsStatus == HandshakeStatus.NEED_TASK) {
-                throw new Exception(
-                        "handshake shouldn't need additional tasks");
-            }
-            log("\tnew HandshakeStatus: " + hsStatus);
-        }
-    }
-
     private static boolean isEngineClosed(SSLEngine engine) {
         return (engine.isOutboundDone() && engine.isInboundDone());
     }
 
-    /*
-     * Simple check to make sure everything came across as expected.
-     */
-    private static void checkTransfer(ByteBuffer a, ByteBuffer b)
-            throws Exception {
-        a.flip();
-        b.flip();
-
-        if (!a.equals(b)) {
-            throw new Exception("Data didn't transfer cleanly");
-        } else {
-            log("\tData transferred cleanly");
-        }
-
-        a.position(a.limit());
-        b.position(b.limit());
-        a.limit(a.capacity());
-        b.limit(b.capacity());
-    }
 
     /*
      * Logging code
diff --git a/test/jdk/javax/net/ssl/TLSv12/DisabledShortDSAKeys.java b/test/jdk/javax/net/ssl/TLSv12/DisabledShortDSAKeys.java
index fa201aa..39937f8 100644
--- a/test/jdk/javax/net/ssl/TLSv12/DisabledShortDSAKeys.java
+++ b/test/jdk/javax/net/ssl/TLSv12/DisabledShortDSAKeys.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,7 +30,7 @@
  * @test
  * @bug 8139565
  * @summary Restrict certificates with DSA keys less than 1024 bits
- *
+ * @library /javax/net/ssl/templates
  * @run main/othervm DisabledShortDSAKeys PKIX TLSv1.2
  * @run main/othervm DisabledShortDSAKeys SunX509 TLSv1.2
  * @run main/othervm DisabledShortDSAKeys PKIX TLSv1.1
@@ -55,15 +55,9 @@
 import java.util.Base64;
 
 
-public class DisabledShortDSAKeys {
+public class DisabledShortDSAKeys extends SSLContextTemplate {
 
-    /*
-     * =============================================================
-     * Set the various variables needed for the tests, then
-     * specify what tests to run on each side.
-     */
-
-    /*
+     /*
      * Should we run the client or server in a separate thread?
      * Both sides can throw exceptions, but do you have a preference
      * as to which side should be the main thread.
@@ -71,58 +65,6 @@
     static boolean separateServerThread = true;
 
     /*
-     * Where do we find the keystores?
-     */
-    // Certificates and key used in the test.
-    static String trustedCertStr =
-        "-----BEGIN CERTIFICATE-----\n" +
-        "MIIDDjCCAs2gAwIBAgIJAO5/hbm1ByJOMAkGByqGSM44BAMwHzELMAkGA1UEBhMC\n" +
-        "VVMxEDAOBgNVBAoTB0V4YW1wbGUwHhcNMTYwMjE2MDQzNTQ2WhcNMzcwMTI2MDQz\n" +
-        "NTQ2WjAfMQswCQYDVQQGEwJVUzEQMA4GA1UEChMHRXhhbXBsZTCCAbgwggEsBgcq\n" +
-        "hkjOOAQBMIIBHwKBgQC4aSK8nBYdWJtuBkz6yoDyjZnNuGFSpDmx1ggKpLpcnPuw\n" +
-        "YKAbUhqdYhZtaIqQ4aO0T1ZS/HuOM0zvddnMUidFNX3RUvDkvdD/JYOnjqzCm+xW\n" +
-        "U0NFuPHZdapQY5KFk3ugkqZpHLY1StZbu0qugZOZjbBOMwB7cHAbMDuVpEr8DQIV\n" +
-        "AOi+ig+h3okFbWEE9MztiI2+DqNrAoGBAKh2EZbuWU9NoHglhVzfDUoz8CeyW6W6\n" +
-        "rUZuIOQsjWaYOeRPWX0UVAGq9ykIOfamEpurKt4H8ge/pHaL9iazJjonMHOXG12A\n" +
-        "0lALsMDGv22zVaJzXjOBvdPzc87opr0LIVgHASKOcDYjsICKNYPlS2cL3MJoD+bj\n" +
-        "NAR67b90VBbEA4GFAAKBgQCGrkRp2tdj2mZF7Qz0tO6p3xSysbEfN6QZxOJYPTvM\n" +
-        "yIYfLV9Yoy7XaRd/mCpJo/dqmsZMzowtyi+u+enuVpOLKiq/lyCktL+xUzZAjLT+\n" +
-        "9dafHlS1wR3pDSa1spo9xTEi4Ff/DQDHcdGalBxSXX/UdRtSecIYAp5/fkt3QZ5v\n" +
-        "0aOBkTCBjjAdBgNVHQ4EFgQUX4qbP5PgBx1J8BJ8qEgfoKVLSnQwTwYDVR0jBEgw\n" +
-        "RoAUX4qbP5PgBx1J8BJ8qEgfoKVLSnShI6QhMB8xCzAJBgNVBAYTAlVTMRAwDgYD\n" +
-        "VQQKEwdFeGFtcGxlggkA7n+FubUHIk4wDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8E\n" +
-        "BAMCAgQwCQYHKoZIzjgEAwMwADAtAhUAkr5bINXyy/McAx6qwhb6r0/QJUgCFFUP\n" +
-        "CZokA4/NqJIgq8ThpTQAE8SB\n" +
-        "-----END CERTIFICATE-----";
-
-    static String targetCertStr =
-        "-----BEGIN CERTIFICATE-----\n" +
-        "MIICUjCCAhGgAwIBAgIJAIiDrs/4W8rtMAkGByqGSM44BAMwHzELMAkGA1UEBhMC\n" +
-        "VVMxEDAOBgNVBAoTB0V4YW1wbGUwHhcNMTYwMjE2MDQzNTQ2WhcNMzUxMTAzMDQz\n" +
-        "NTQ2WjA5MQswCQYDVQQGEwJVUzEQMA4GA1UECgwHRXhhbXBsZTEYMBYGA1UEAwwP\n" +
-        "d3d3LmV4YW1wbGUuY29tMIHwMIGoBgcqhkjOOAQBMIGcAkEAs6A0p3TysTtVXGSv\n" +
-        "ThR/8GHpbL49KyWRJBMIlmLc5jl/wxJgnL1t07p4YTOEa6ecyTFos04Z8n2GARmp\n" +
-        "zYlUywIVAJLDcf4JXhZbguRFSQdWwWhZkh+LAkBLCzh3Xvpmc/5CDqU+QHqDcuSk\n" +
-        "5B8+ZHaHRi2KQ00ejilpF2qZpW5JdHe4m3Pggh0MIuaAGX+leM4JKlnObj14A0MA\n" +
-        "AkAYb+DYlFgStFhF1ip7rFzY8K6i/3ellkXI2umI/XVwxUQTHSlk5nFOep5Dfzm9\n" +
-        "pADJwuSe1qGHsHB5LpMZPVpto4GEMIGBMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgPo\n" +
-        "MB0GA1UdDgQWBBT8nsFyccF4q1dtpWE1dkNK5UiXtTAfBgNVHSMEGDAWgBRfips/\n" +
-        "k+AHHUnwEnyoSB+gpUtKdDAnBgNVHSUEIDAeBggrBgEFBQcDAQYIKwYBBQUHAwIG\n" +
-        "CCsGAQUFBwMDMAkGByqGSM44BAMDMAAwLQIUIcIlxpIwaZXdpMC+U076unR1Mp8C\n" +
-        "FQCD/NE8O0xwq57nwFfp7tUvUHYMMA==\n" +
-        "-----END CERTIFICATE-----";
-
-    // Private key in the format of PKCS#8, key size is 512 bits.
-    static String targetPrivateKey =
-        "MIHGAgEAMIGoBgcqhkjOOAQBMIGcAkEAs6A0p3TysTtVXGSvThR/8GHpbL49KyWR\n" +
-        "JBMIlmLc5jl/wxJgnL1t07p4YTOEa6ecyTFos04Z8n2GARmpzYlUywIVAJLDcf4J\n" +
-        "XhZbguRFSQdWwWhZkh+LAkBLCzh3Xvpmc/5CDqU+QHqDcuSk5B8+ZHaHRi2KQ00e\n" +
-        "jilpF2qZpW5JdHe4m3Pggh0MIuaAGX+leM4JKlnObj14BBYCFHB2Wek2g5hpNj5y\n" +
-        "RQfCc6CFO0dv";
-
-    static char passphrase[] = "passphrase".toCharArray();
-
-    /*
      * Is the server ready to serve?
      */
     volatile static boolean serverReady = false;
@@ -139,8 +81,8 @@
      * to avoid infinite hangs.
      */
     void doServerSide() throws Exception {
-        SSLContext context = generateSSLContext(null, targetCertStr,
-                                            targetPrivateKey);
+        SSLContext context = createSSLContext(null,
+                new Cert[]{Cert.CA_DSA_512}, getServerContextParameters());
         SSLServerSocketFactory sslssf = context.getServerSocketFactory();
         SSLServerSocket sslServerSocket =
             (SSLServerSocket)sslssf.createServerSocket(serverPort);
@@ -178,7 +120,8 @@
             Thread.sleep(50);
         }
 
-        SSLContext context = generateSSLContext(trustedCertStr, null, null);
+        SSLContext context = createSSLContext(new Cert[]{Cert.CA_DSA_1024},
+                null, getClientContextParameters());
         SSLSocketFactory sslsf = context.getSocketFactory();
 
         try (SSLSocket sslSocket =
@@ -215,72 +158,15 @@
         enabledProtocol = args[1];
     }
 
-    private static SSLContext generateSSLContext(String trustedCertStr,
-            String keyCertStr, String keySpecStr) throws Exception {
-
-        // generate certificate from cert string
-        CertificateFactory cf = CertificateFactory.getInstance("X.509");
-
-        // create a key store
-        KeyStore ks = KeyStore.getInstance("JKS");
-        ks.load(null, null);
-
-        // import the trused cert
-        Certificate trusedCert = null;
-        ByteArrayInputStream is = null;
-        if (trustedCertStr != null) {
-            is = new ByteArrayInputStream(trustedCertStr.getBytes());
-            trusedCert = cf.generateCertificate(is);
-            is.close();
-
-            ks.setCertificateEntry("DSA Export Signer", trusedCert);
-        }
-
-        if (keyCertStr != null) {
-            // generate the private key.
-            PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec(
-                                Base64.getMimeDecoder().decode(keySpecStr));
-            KeyFactory kf = KeyFactory.getInstance("DSA");
-            DSAPrivateKey priKey =
-                    (DSAPrivateKey)kf.generatePrivate(priKeySpec);
-
-            // generate certificate chain
-            is = new ByteArrayInputStream(keyCertStr.getBytes());
-            Certificate keyCert = cf.generateCertificate(is);
-            is.close();
-
-            Certificate[] chain = null;
-            if (trusedCert != null) {
-                chain = new Certificate[2];
-                chain[0] = keyCert;
-                chain[1] = trusedCert;
-            } else {
-                chain = new Certificate[1];
-                chain[0] = keyCert;
-            }
-
-            // import the key entry.
-            ks.setKeyEntry("Whatever", priKey, passphrase, chain);
-        }
-
-        // create SSL context
-        TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmAlgorithm);
-        tmf.init(ks);
-
-        SSLContext ctx = SSLContext.getInstance("TLS");
-        if (keyCertStr != null && !keyCertStr.isEmpty()) {
-            KeyManagerFactory kmf = KeyManagerFactory.getInstance("NewSunX509");
-            kmf.init(ks, passphrase);
-
-            ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
-            ks = null;
-        } else {
-            ctx.init(null, tmf.getTrustManagers(), null);
-        }
-
-        return ctx;
+    @Override
+    protected ContextParameters getServerContextParameters() {
+        return new ContextParameters(enabledProtocol, tmAlgorithm, "NewSunX509");
     }
 
+    @Override
+    protected ContextParameters getClientContextParameters() {
+        return new ContextParameters(enabledProtocol, tmAlgorithm, "NewSunX509");
+    }
 
     // use any free port by default
     volatile int serverPort = 0;
diff --git a/test/jdk/javax/net/ssl/TLSv12/ShortRSAKey512.java b/test/jdk/javax/net/ssl/TLSv12/ShortRSAKey512.java
index 627536a..c9ff202 100644
--- a/test/jdk/javax/net/ssl/TLSv12/ShortRSAKey512.java
+++ b/test/jdk/javax/net/ssl/TLSv12/ShortRSAKey512.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,25 +33,18 @@
  *
  *     SunJSSE does not support dynamic system properties, no way to re-use
  *     system properties in samevm/agentvm mode.
+ *
+ * @library /javax/net/ssl/templates
  * @run main/othervm ShortRSAKey512 PKIX
  * @run main/othervm ShortRSAKey512 SunX509
  */
 
-import java.net.*;
-import java.util.*;
 import java.io.*;
 import javax.net.ssl.*;
 import java.security.Security;
-import java.security.KeyStore;
-import java.security.KeyFactory;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateFactory;
-import java.security.spec.*;
-import java.security.interfaces.*;
-import java.util.Base64;
 
 
-public class ShortRSAKey512 {
+public class ShortRSAKey512 extends SSLContextTemplate {
 
     /*
      * =============================================================
@@ -67,57 +60,6 @@
     static boolean separateServerThread = false;
 
     /*
-     * Where do we find the keystores?
-     */
-    // Certificates and key used in the test.
-    static String trustedCertStr =
-        "-----BEGIN CERTIFICATE-----\n" +
-        "MIICkjCCAfugAwIBAgIBADANBgkqhkiG9w0BAQQFADA7MQswCQYDVQQGEwJVUzEN\n" +
-        "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n" +
-        "MTEwODE5MDE1MjE5WhcNMzIwNzI5MDE1MjE5WjA7MQswCQYDVQQGEwJVUzENMAsG\n" +
-        "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwgZ8wDQYJ\n" +
-        "KoZIhvcNAQEBBQADgY0AMIGJAoGBAM8orG08DtF98TMSscjGsidd1ZoN4jiDpi8U\n" +
-        "ICz+9dMm1qM1d7O2T+KH3/mxyox7Rc2ZVSCaUD0a3CkhPMnlAx8V4u0H+E9sqso6\n" +
-        "iDW3JpOyzMExvZiRgRG/3nvp55RMIUV4vEHOZ1QbhuqG4ebN0Vz2DkRft7+flthf\n" +
-        "vDld6f5JAgMBAAGjgaUwgaIwHQYDVR0OBBYEFLl81dnfp0wDrv0OJ1sxlWzH83Xh\n" +
-        "MGMGA1UdIwRcMFqAFLl81dnfp0wDrv0OJ1sxlWzH83XhoT+kPTA7MQswCQYDVQQG\n" +
-        "EwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2\n" +
-        "Y2WCAQAwDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQEE\n" +
-        "BQADgYEALlgaH1gWtoBZ84EW8Hu6YtGLQ/L9zIFmHonUPZwn3Pr//icR9Sqhc3/l\n" +
-        "pVTxOINuFHLRz4BBtEylzRIOPzK3tg8XwuLb1zd0db90x3KBCiAL6E6cklGEPwLe\n" +
-        "XYMHDn9eDsaq861Tzn6ZwzMgw04zotPMoZN0mVd/3Qca8UJFucE=\n" +
-        "-----END CERTIFICATE-----";
-
-    static String targetCertStr =
-        "-----BEGIN CERTIFICATE-----\n" +
-        "MIICNDCCAZ2gAwIBAgIBDDANBgkqhkiG9w0BAQQFADA7MQswCQYDVQQGEwJVUzEN\n" +
-        "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n" +
-        "MTExMTA3MTM1NTUyWhcNMzEwNzI1MTM1NTUyWjBPMQswCQYDVQQGEwJVUzENMAsG\n" +
-        "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UxEjAQBgNV\n" +
-        "BAMTCWxvY2FsaG9zdDBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC3Pb49OSPfOD2G\n" +
-        "HSXFCFx1GJEZfqG9ZUf7xuIi/ra5dLjPGAaoY5QF2QOa8VnOriQCXDfyXHxsuRnE\n" +
-        "OomxL7EVAgMBAAGjeDB2MAsGA1UdDwQEAwID6DAdBgNVHQ4EFgQUXNCJK3/dtCIc\n" +
-        "xb+zlA/JINlvs/MwHwYDVR0jBBgwFoAUuXzV2d+nTAOu/Q4nWzGVbMfzdeEwJwYD\n" +
-        "VR0lBCAwHgYIKwYBBQUHAwEGCCsGAQUFBwMCBggrBgEFBQcDAzANBgkqhkiG9w0B\n" +
-        "AQQFAAOBgQB2qIDUxA2caMPpGtUACZAPRUtrGssCINIfItETXJZCx/cRuZ5sP4D9\n" +
-        "N1acoNDn0hCULe3lhXAeTC9NZ97680yJzregQMV5wATjo1FGsKY30Ma+sc/nfzQW\n" +
-        "+h/7RhYtoG0OTsiaDCvyhI6swkNJzSzrAccPY4+ZgU8HiDLzZTmM3Q==\n" +
-        "-----END CERTIFICATE-----";
-
-    // Private key in the format of PKCS#8, key size is 512 bits.
-    static String targetPrivateKey =
-        "MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAtz2+PTkj3zg9hh0l\n" +
-        "xQhcdRiRGX6hvWVH+8biIv62uXS4zxgGqGOUBdkDmvFZzq4kAlw38lx8bLkZxDqJ\n" +
-        "sS+xFQIDAQABAkByx/5Oo2hQ/w2q4L8z+NTRlJ3vdl8iIDtC/4XPnfYfnGptnpG6\n" +
-        "ZThQRvbMZiai0xHQPQMszvAHjZVme1eDl3EBAiEA3aKJHynPVCEJhpfCLWuMwX5J\n" +
-        "1LntwJO7NTOyU5m8rPECIQDTpzn5X44r2rzWBDna/Sx7HW9IWCxNgUD2Eyi2nA7W\n" +
-        "ZQIgJerEorw4aCAuzQPxiGu57PB6GRamAihEAtoRTBQlH0ECIQDN08FgTtnesgCU\n" +
-        "DFYLLcw1CiHvc7fZw4neBDHCrC8NtQIgA8TOUkGnpCZlQ0KaI8KfKWI+vxFcgFnH\n" +
-        "3fnqsTgaUs4=";
-
-    static char passphrase[] = "passphrase".toCharArray();
-
-    /*
      * Is the server ready to serve?
      */
     volatile static boolean serverReady = false;
@@ -134,8 +76,8 @@
      * to avoid infinite hangs.
      */
     void doServerSide() throws Exception {
-        SSLContext context = generateSSLContext(null, targetCertStr,
-                                            targetPrivateKey);
+        SSLContext context = createSSLContext(null,
+                new Cert[]{Cert.EE_RSA_MD5_512}, getServerContextParameters());
         SSLServerSocketFactory sslssf = context.getServerSocketFactory();
         try (SSLServerSocket sslServerSocket =
                 (SSLServerSocket) sslssf.createServerSocket(serverPort)) {
@@ -174,7 +116,8 @@
             Thread.sleep(50);
         }
 
-        SSLContext context = generateSSLContext(trustedCertStr, null, null);
+        SSLContext context = createSSLContext(new Cert[]{Cert.CA_RSA_MD5_512},
+                null, getClientContextParameters());
         SSLSocketFactory sslsf = context.getSocketFactory();
 
         System.out.println("Client connects to port " + serverPort);
@@ -197,6 +140,16 @@
         }
     }
 
+    @Override
+    protected ContextParameters getServerContextParameters() {
+        return new ContextParameters("TLSv1.2", tmAlgorithm, "NewSunX509");
+    }
+
+    @Override
+    protected ContextParameters getClientContextParameters() {
+        return new ContextParameters("TLSv1.2", tmAlgorithm, "NewSunX509");
+    }
+
     /*
      * =============================================================
      * The remainder is just support stuff
@@ -207,72 +160,6 @@
         tmAlgorithm = args[0];
     }
 
-    private static SSLContext generateSSLContext(String trustedCertStr,
-            String keyCertStr, String keySpecStr) throws Exception {
-
-        // generate certificate from cert string
-        CertificateFactory cf = CertificateFactory.getInstance("X.509");
-
-        // create a key store
-        KeyStore ks = KeyStore.getInstance("JKS");
-        ks.load(null, null);
-
-        // import the trused cert
-        Certificate trusedCert = null;
-        ByteArrayInputStream is = null;
-        if (trustedCertStr != null) {
-            is = new ByteArrayInputStream(trustedCertStr.getBytes());
-            trusedCert = cf.generateCertificate(is);
-            is.close();
-
-            ks.setCertificateEntry("RSA Export Signer", trusedCert);
-        }
-
-        if (keyCertStr != null) {
-            // generate the private key.
-            PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec(
-                                Base64.getMimeDecoder().decode(keySpecStr));
-            KeyFactory kf = KeyFactory.getInstance("RSA");
-            RSAPrivateKey priKey =
-                    (RSAPrivateKey)kf.generatePrivate(priKeySpec);
-
-            // generate certificate chain
-            is = new ByteArrayInputStream(keyCertStr.getBytes());
-            Certificate keyCert = cf.generateCertificate(is);
-            is.close();
-
-            Certificate[] chain = null;
-            if (trusedCert != null) {
-                chain = new Certificate[2];
-                chain[0] = keyCert;
-                chain[1] = trusedCert;
-            } else {
-                chain = new Certificate[1];
-                chain[0] = keyCert;
-            }
-
-            // import the key entry.
-            ks.setKeyEntry("Whatever", priKey, passphrase, chain);
-        }
-
-        // create SSL context
-        TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmAlgorithm);
-        tmf.init(ks);
-
-        SSLContext ctx = SSLContext.getInstance("TLS");
-        if (keyCertStr != null && !keyCertStr.isEmpty()) {
-            KeyManagerFactory kmf = KeyManagerFactory.getInstance("NewSunX509");
-            kmf.init(ks, passphrase);
-
-            ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
-            ks = null;
-        } else {
-            ctx.init(null, tmf.getTrustManagers(), null);
-        }
-
-        return ctx;
-    }
-
 
     // use any free port by default
     volatile int serverPort = 0;
diff --git a/test/jdk/javax/net/ssl/TLSv12/ShortRSAKeyGCM.java b/test/jdk/javax/net/ssl/TLSv12/ShortRSAKeyGCM.java
index 6ccfa03..df6767e 100644
--- a/test/jdk/javax/net/ssl/TLSv12/ShortRSAKeyGCM.java
+++ b/test/jdk/javax/net/ssl/TLSv12/ShortRSAKeyGCM.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,6 +32,7 @@
  * @test
  * @bug 7030966
  * @summary Support AEAD CipherSuites
+ * @library /javax/net/ssl/templates
  * @run main/othervm ShortRSAKeyGCM PKIX TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
  * @run main/othervm ShortRSAKeyGCM PKIX TLS_RSA_WITH_AES_128_GCM_SHA256
  * @run main/othervm ShortRSAKeyGCM PKIX TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
@@ -70,7 +71,7 @@
 import java.security.interfaces.*;
 
 
-public class ShortRSAKeyGCM {
+public class ShortRSAKeyGCM extends SSLContextTemplate {
 
     /*
      * =============================================================
@@ -86,57 +87,6 @@
     static boolean separateServerThread = true;
 
     /*
-     * Where do we find the keystores?
-     */
-    // Certificates and key used in the test.
-    static String trustedCertStr =
-        "-----BEGIN CERTIFICATE-----\n" +
-        "MIICkjCCAfugAwIBAgIBADANBgkqhkiG9w0BAQQFADA7MQswCQYDVQQGEwJVUzEN\n" +
-        "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n" +
-        "MTEwODE5MDE1MjE5WhcNMzIwNzI5MDE1MjE5WjA7MQswCQYDVQQGEwJVUzENMAsG\n" +
-        "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwgZ8wDQYJ\n" +
-        "KoZIhvcNAQEBBQADgY0AMIGJAoGBAM8orG08DtF98TMSscjGsidd1ZoN4jiDpi8U\n" +
-        "ICz+9dMm1qM1d7O2T+KH3/mxyox7Rc2ZVSCaUD0a3CkhPMnlAx8V4u0H+E9sqso6\n" +
-        "iDW3JpOyzMExvZiRgRG/3nvp55RMIUV4vEHOZ1QbhuqG4ebN0Vz2DkRft7+flthf\n" +
-        "vDld6f5JAgMBAAGjgaUwgaIwHQYDVR0OBBYEFLl81dnfp0wDrv0OJ1sxlWzH83Xh\n" +
-        "MGMGA1UdIwRcMFqAFLl81dnfp0wDrv0OJ1sxlWzH83XhoT+kPTA7MQswCQYDVQQG\n" +
-        "EwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2\n" +
-        "Y2WCAQAwDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQEE\n" +
-        "BQADgYEALlgaH1gWtoBZ84EW8Hu6YtGLQ/L9zIFmHonUPZwn3Pr//icR9Sqhc3/l\n" +
-        "pVTxOINuFHLRz4BBtEylzRIOPzK3tg8XwuLb1zd0db90x3KBCiAL6E6cklGEPwLe\n" +
-        "XYMHDn9eDsaq861Tzn6ZwzMgw04zotPMoZN0mVd/3Qca8UJFucE=\n" +
-        "-----END CERTIFICATE-----";
-
-    static String targetCertStr =
-        "-----BEGIN CERTIFICATE-----\n" +
-        "MIICNDCCAZ2gAwIBAgIBDDANBgkqhkiG9w0BAQQFADA7MQswCQYDVQQGEwJVUzEN\n" +
-        "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n" +
-        "MTExMTA3MTM1NTUyWhcNMzEwNzI1MTM1NTUyWjBPMQswCQYDVQQGEwJVUzENMAsG\n" +
-        "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UxEjAQBgNV\n" +
-        "BAMTCWxvY2FsaG9zdDBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC3Pb49OSPfOD2G\n" +
-        "HSXFCFx1GJEZfqG9ZUf7xuIi/ra5dLjPGAaoY5QF2QOa8VnOriQCXDfyXHxsuRnE\n" +
-        "OomxL7EVAgMBAAGjeDB2MAsGA1UdDwQEAwID6DAdBgNVHQ4EFgQUXNCJK3/dtCIc\n" +
-        "xb+zlA/JINlvs/MwHwYDVR0jBBgwFoAUuXzV2d+nTAOu/Q4nWzGVbMfzdeEwJwYD\n" +
-        "VR0lBCAwHgYIKwYBBQUHAwEGCCsGAQUFBwMCBggrBgEFBQcDAzANBgkqhkiG9w0B\n" +
-        "AQQFAAOBgQB2qIDUxA2caMPpGtUACZAPRUtrGssCINIfItETXJZCx/cRuZ5sP4D9\n" +
-        "N1acoNDn0hCULe3lhXAeTC9NZ97680yJzregQMV5wATjo1FGsKY30Ma+sc/nfzQW\n" +
-        "+h/7RhYtoG0OTsiaDCvyhI6swkNJzSzrAccPY4+ZgU8HiDLzZTmM3Q==\n" +
-        "-----END CERTIFICATE-----";
-
-    // Private key in the format of PKCS#8, key size is 512 bits.
-    static String targetPrivateKey =
-        "MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAtz2+PTkj3zg9hh0l\n" +
-        "xQhcdRiRGX6hvWVH+8biIv62uXS4zxgGqGOUBdkDmvFZzq4kAlw38lx8bLkZxDqJ\n" +
-        "sS+xFQIDAQABAkByx/5Oo2hQ/w2q4L8z+NTRlJ3vdl8iIDtC/4XPnfYfnGptnpG6\n" +
-        "ZThQRvbMZiai0xHQPQMszvAHjZVme1eDl3EBAiEA3aKJHynPVCEJhpfCLWuMwX5J\n" +
-        "1LntwJO7NTOyU5m8rPECIQDTpzn5X44r2rzWBDna/Sx7HW9IWCxNgUD2Eyi2nA7W\n" +
-        "ZQIgJerEorw4aCAuzQPxiGu57PB6GRamAihEAtoRTBQlH0ECIQDN08FgTtnesgCU\n" +
-        "DFYLLcw1CiHvc7fZw4neBDHCrC8NtQIgA8TOUkGnpCZlQ0KaI8KfKWI+vxFcgFnH\n" +
-        "3fnqsTgaUs4=";
-
-    static char passphrase[] = "passphrase".toCharArray();
-
-    /*
      * Is the server ready to serve?
      */
     volatile static boolean serverReady = false;
@@ -153,8 +103,8 @@
      * to avoid infinite hangs.
      */
     void doServerSide() throws Exception {
-        SSLContext context = generateSSLContext(null, targetCertStr,
-                                            targetPrivateKey);
+        SSLContext context = createSSLContext(null, new Cert[]{Cert.EE_RSA_MD5_512},
+                getServerContextParameters());
         SSLServerSocketFactory sslssf = context.getServerSocketFactory();
         SSLServerSocket sslServerSocket =
             (SSLServerSocket)sslssf.createServerSocket(serverPort);
@@ -192,7 +142,8 @@
             Thread.sleep(50);
         }
 
-        SSLContext context = generateSSLContext(trustedCertStr, null, null);
+       SSLContext context = createSSLContext(new Cert[]{Cert.CA_RSA_MD5_512},
+                null, getClientContextParameters());
         SSLSocketFactory sslsf = context.getSocketFactory();
 
         SSLSocket sslSocket =
@@ -226,72 +177,15 @@
         cipherSuite = args[1];
     }
 
-    private static SSLContext generateSSLContext(String trustedCertStr,
-            String keyCertStr, String keySpecStr) throws Exception {
-
-        // generate certificate from cert string
-        CertificateFactory cf = CertificateFactory.getInstance("X.509");
-
-        // create a key store
-        KeyStore ks = KeyStore.getInstance("JKS");
-        ks.load(null, null);
-
-        // import the trused cert
-        Certificate trusedCert = null;
-        ByteArrayInputStream is = null;
-        if (trustedCertStr != null) {
-            is = new ByteArrayInputStream(trustedCertStr.getBytes());
-            trusedCert = cf.generateCertificate(is);
-            is.close();
-
-            ks.setCertificateEntry("RSA Export Signer", trusedCert);
-        }
-
-        if (keyCertStr != null) {
-            // generate the private key.
-            PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec(
-                                Base64.getMimeDecoder().decode(keySpecStr));
-            KeyFactory kf = KeyFactory.getInstance("RSA");
-            RSAPrivateKey priKey =
-                    (RSAPrivateKey)kf.generatePrivate(priKeySpec);
-
-            // generate certificate chain
-            is = new ByteArrayInputStream(keyCertStr.getBytes());
-            Certificate keyCert = cf.generateCertificate(is);
-            is.close();
-
-            Certificate[] chain = null;
-            if (trusedCert != null) {
-                chain = new Certificate[2];
-                chain[0] = keyCert;
-                chain[1] = trusedCert;
-            } else {
-                chain = new Certificate[1];
-                chain[0] = keyCert;
-            }
-
-            // import the key entry.
-            ks.setKeyEntry("Whatever", priKey, passphrase, chain);
-        }
-
-        // create SSL context
-        TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmAlgorithm);
-        tmf.init(ks);
-
-        SSLContext ctx = SSLContext.getInstance("TLS");
-        if (keyCertStr != null && !keyCertStr.isEmpty()) {
-            KeyManagerFactory kmf = KeyManagerFactory.getInstance("NewSunX509");
-            kmf.init(ks, passphrase);
-
-            ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
-            ks = null;
-        } else {
-            ctx.init(null, tmf.getTrustManagers(), null);
-        }
-
-        return ctx;
+    @Override
+    protected ContextParameters getServerContextParameters() {
+        return new ContextParameters("TLSv1.2", tmAlgorithm, "NewSunX509");
     }
 
+    @Override
+    protected ContextParameters getClientContextParameters() {
+        return new ContextParameters("TLSv1.2", tmAlgorithm, "NewSunX509");
+    }
 
     // use any free port by default
     volatile int serverPort = 0;
diff --git a/test/jdk/javax/net/ssl/TLSv12/SignatureAlgorithms.java b/test/jdk/javax/net/ssl/TLSv12/SignatureAlgorithms.java
index 8b51703..52191ec 100644
--- a/test/jdk/javax/net/ssl/TLSv12/SignatureAlgorithms.java
+++ b/test/jdk/javax/net/ssl/TLSv12/SignatureAlgorithms.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,6 +32,7 @@
  * @test
  * @bug 8049321
  * @summary Support SHA256WithDSA in JSSE
+ * @library /javax/net/ssl/templates
  * @run main/othervm SignatureAlgorithms PKIX "SHA-224,SHA-256"
  *                   TLS_DHE_DSS_WITH_AES_128_CBC_SHA
  * @run main/othervm SignatureAlgorithms PKIX "SHA-1,SHA-224"
@@ -46,20 +47,14 @@
  *                   TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
  */
 
-import java.net.*;
 import java.util.*;
 import java.io.*;
 import javax.net.ssl.*;
 import java.security.Security;
-import java.security.KeyStore;
-import java.security.KeyFactory;
 import java.security.cert.Certificate;
 import java.security.cert.X509Certificate;
-import java.security.cert.CertificateFactory;
-import java.security.spec.*;
-import java.security.interfaces.*;
 
-public class SignatureAlgorithms {
+public class SignatureAlgorithms extends SSLContextTemplate {
 
     /*
      * =============================================================
@@ -75,131 +70,6 @@
     static boolean separateServerThread = true;
 
     /*
-     * Where do we find the keystores?
-     */
-    // Certificates and key (DSA) used in the test.
-    static String trustedCertStr =
-        "-----BEGIN CERTIFICATE-----\n" +
-        "MIIDYTCCAyGgAwIBAgIJAK8/gw6zg/DPMAkGByqGSM44BAMwOzELMAkGA1UEBhMC\n" +
-        "VVMxDTALBgNVBAoTBEphdmExHTAbBgNVBAsTFFN1bkpTU0UgVGVzdCBTZXJpdmNl\n" +
-        "MB4XDTE1MTIwMzEzNTIyNVoXDTM2MTExMjEzNTIyNVowOzELMAkGA1UEBhMCVVMx\n" +
-        "DTALBgNVBAoTBEphdmExHTAbBgNVBAsTFFN1bkpTU0UgVGVzdCBTZXJpdmNlMIIB\n" +
-        "uDCCASwGByqGSM44BAEwggEfAoGBAPH+b+GSMX6KS7jXDRevzc464DFG4X+uxu5V\n" +
-        "b3U4yhsU8A8cuH4gwin6L/IDkmZQ7N0zC0jRsiGVSMsFETTq10F39pH2eBfUv/hJ\n" +
-        "cLfBnIjBEtVqV/dExK88Hul2sZ4mQihQ4issPl7hsroS9EWYicnX0oNAqAB9PO5Y\n" +
-        "zKbfpL7TAhUA13WW48rln2UP/LaAgtnzKhqcNtMCgYEA3Rv0GirTbAaor8iURd82\n" +
-        "b5FlDTevOCTuq7ZIpfZVV30neS7cBYNet6m/3/4cfUlbbrqhbqIJ2I+I81drnN0Y\n" +
-        "lyN4KkuxEcB6OTwfWkIUj6rvPaCQrBH8Q213bDq3HHtYNaP8OoeQUyVXW+SEGADC\n" +
-        "J1+z8uqP3lIB6ltdgOiV/GQDgYUAAoGBAOXRppuJSGdt6AiZkb81P1DCUgIUlZFI\n" +
-        "J9GxWrjbbHDmGllMwPNhK6dU7LJKJJuYVPW+95rUGlSJEjRqSlHuyHkNb6e3e7qx\n" +
-        "tmx1/oIyq+oLult50hBS7uBvLLR0JbIKjBzzkudL8Rjze4G/Wq7KDM2T1JOP49tW\n" +
-        "eocCvaC8h8uQo4GtMIGqMB0GA1UdDgQWBBT17HcqLllsqnZzP+kElcGcBGmubjBr\n" +
-        "BgNVHSMEZDBigBT17HcqLllsqnZzP+kElcGcBGmubqE/pD0wOzELMAkGA1UEBhMC\n" +
-        "VVMxDTALBgNVBAoTBEphdmExHTAbBgNVBAsTFFN1bkpTU0UgVGVzdCBTZXJpdmNl\n" +
-        "ggkArz+DDrOD8M8wDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAQYwCQYHKoZI\n" +
-        "zjgEAwMvADAsAhQ6Y1I6LtIEBMqNo8o6GIe4LLEJuwIUbVQUKi8tvtWyRoxm8AFV\n" +
-        "0axJYUU=\n" +
-        "-----END CERTIFICATE-----";
-
-    static String[] targetCertStr = {
-        // DSA-SHA1
-        "-----BEGIN CERTIFICATE-----\n" +
-        "MIIDKTCCAumgAwIBAgIJAOy5c0b+8stFMAkGByqGSM44BAMwOzELMAkGA1UEBhMC\n" +
-        "VVMxDTALBgNVBAoTBEphdmExHTAbBgNVBAsTFFN1bkpTU0UgVGVzdCBTZXJpdmNl\n" +
-        "MB4XDTE1MTIwMzEzNTIyNVoXDTM1MDgyMDEzNTIyNVowTzELMAkGA1UEBhMCVVMx\n" +
-        "DTALBgNVBAoMBEphdmExHTAbBgNVBAsMFFN1bkpTU0UgVGVzdCBTZXJpdmNlMRIw\n" +
-        "EAYDVQQDDAlsb2NhbGhvc3QwggG3MIIBLAYHKoZIzjgEATCCAR8CgYEA8f5v4ZIx\n" +
-        "fopLuNcNF6/NzjrgMUbhf67G7lVvdTjKGxTwDxy4fiDCKfov8gOSZlDs3TMLSNGy\n" +
-        "IZVIywURNOrXQXf2kfZ4F9S/+Elwt8GciMES1WpX90TErzwe6XaxniZCKFDiKyw+\n" +
-        "XuGyuhL0RZiJydfSg0CoAH087ljMpt+kvtMCFQDXdZbjyuWfZQ/8toCC2fMqGpw2\n" +
-        "0wKBgQDdG/QaKtNsBqivyJRF3zZvkWUNN684JO6rtkil9lVXfSd5LtwFg163qb/f\n" +
-        "/hx9SVtuuqFuognYj4jzV2uc3RiXI3gqS7ERwHo5PB9aQhSPqu89oJCsEfxDbXds\n" +
-        "Orcce1g1o/w6h5BTJVdb5IQYAMInX7Py6o/eUgHqW12A6JX8ZAOBhAACgYB+zYqn\n" +
-        "jJwG4GZpBIN/6qhzbp0flChsV+Trlu0SL0agAQzb6XdI/4JnO87Pgbxaxh3VNAj3\n" +
-        "3+Ghr1NLBuBfTKzJ4j9msWT3EpLupkMyNtXvBYM0iyMrll67lSjMdv++wLEw35Af\n" +
-        "/bzVcjGyA5Q0i0cuEzDmHTVfi0OydynbwSLxtKNjMGEwCwYDVR0PBAQDAgPoMB0G\n" +
-        "A1UdDgQWBBQXJI8AxM0qsYCbbkIMuI5zJ+nMEDAfBgNVHSMEGDAWgBT17HcqLlls\n" +
-        "qnZzP+kElcGcBGmubjASBgNVHREBAf8ECDAGhwR/AAABMAkGByqGSM44BAMDLwAw\n" +
-        "LAIUXgyJ0xll4FrZAKXi8bj7Kiz+SA4CFH9WCSZIBYA9lmJkiTgRS7iM/6IC\n" +
-        "-----END CERTIFICATE-----",
-
-        // DSA-SHA224
-        "-----BEGIN CERTIFICATE-----\n" +
-        "MIIDLzCCAuugAwIBAgIJAOy5c0b+8stGMAsGCWCGSAFlAwQDATA7MQswCQYDVQQG\n" +
-        "EwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2\n" +
-        "Y2UwHhcNMTUxMjAzMTU0NDM5WhcNMzUwODIwMTU0NDM5WjBPMQswCQYDVQQGEwJV\n" +
-        "UzENMAsGA1UECgwESmF2YTEdMBsGA1UECwwUU3VuSlNTRSBUZXN0IFNlcml2Y2Ux\n" +
-        "EjAQBgNVBAMMCWxvY2FsaG9zdDCCAbcwggEsBgcqhkjOOAQBMIIBHwKBgQDx/m/h\n" +
-        "kjF+iku41w0Xr83OOuAxRuF/rsbuVW91OMobFPAPHLh+IMIp+i/yA5JmUOzdMwtI\n" +
-        "0bIhlUjLBRE06tdBd/aR9ngX1L/4SXC3wZyIwRLValf3RMSvPB7pdrGeJkIoUOIr\n" +
-        "LD5e4bK6EvRFmInJ19KDQKgAfTzuWMym36S+0wIVANd1luPK5Z9lD/y2gILZ8yoa\n" +
-        "nDbTAoGBAN0b9Boq02wGqK/IlEXfNm+RZQ03rzgk7qu2SKX2VVd9J3ku3AWDXrep\n" +
-        "v9/+HH1JW266oW6iCdiPiPNXa5zdGJcjeCpLsRHAejk8H1pCFI+q7z2gkKwR/ENt\n" +
-        "d2w6txx7WDWj/DqHkFMlV1vkhBgAwidfs/Lqj95SAepbXYDolfxkA4GEAAKBgA81\n" +
-        "CJKEv+pwiqYgxtw/9rkQ9748WP3mKrEC06kjUG+94/Z9dQloNFFfj6LiO1bymc5l\n" +
-        "6QIR8XCi4Po3N80K3+WxhBGFhY+RkVWTh43JV8epb41aH2qiWErarBwBGEh8LyGT\n" +
-        "i30db+Nkz2gfvyz9H/9T0jmYgfLEOlMCusali1qHo2MwYTALBgNVHQ8EBAMCA+gw\n" +
-        "HQYDVR0OBBYEFBqSP0S4+X+zOCTEnlp2hbAjV/W5MB8GA1UdIwQYMBaAFPXsdyou\n" +
-        "WWyqdnM/6QSVwZwEaa5uMBIGA1UdEQEB/wQIMAaHBH8AAAEwCwYJYIZIAWUDBAMB\n" +
-        "AzEAMC4CFQChiRaOnAnsCSJFwdpK22jSxU/mhQIVALgLbj/G39+1Ej8UuSWnEQyU\n" +
-        "4DA+\n" +
-        "-----END CERTIFICATE-----",
-
-        // DSA-SHA256
-        "-----BEGIN CERTIFICATE-----\n" +
-        "MIIDLTCCAuugAwIBAgIJAOy5c0b+8stHMAsGCWCGSAFlAwQDAjA7MQswCQYDVQQG\n" +
-        "EwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2\n" +
-        "Y2UwHhcNMTUxMjAzMTU0NjUxWhcNMzUwODIwMTU0NjUxWjBPMQswCQYDVQQGEwJV\n" +
-        "UzENMAsGA1UECgwESmF2YTEdMBsGA1UECwwUU3VuSlNTRSBUZXN0IFNlcml2Y2Ux\n" +
-        "EjAQBgNVBAMMCWxvY2FsaG9zdDCCAbcwggEsBgcqhkjOOAQBMIIBHwKBgQDx/m/h\n" +
-        "kjF+iku41w0Xr83OOuAxRuF/rsbuVW91OMobFPAPHLh+IMIp+i/yA5JmUOzdMwtI\n" +
-        "0bIhlUjLBRE06tdBd/aR9ngX1L/4SXC3wZyIwRLValf3RMSvPB7pdrGeJkIoUOIr\n" +
-        "LD5e4bK6EvRFmInJ19KDQKgAfTzuWMym36S+0wIVANd1luPK5Z9lD/y2gILZ8yoa\n" +
-        "nDbTAoGBAN0b9Boq02wGqK/IlEXfNm+RZQ03rzgk7qu2SKX2VVd9J3ku3AWDXrep\n" +
-        "v9/+HH1JW266oW6iCdiPiPNXa5zdGJcjeCpLsRHAejk8H1pCFI+q7z2gkKwR/ENt\n" +
-        "d2w6txx7WDWj/DqHkFMlV1vkhBgAwidfs/Lqj95SAepbXYDolfxkA4GEAAKBgEF7\n" +
-        "2qiYxGrjX4KCOy0k5nK/RYlgLy4gYDChihQpiaa+fbA5JOBOxPWsh7rdtmJuDrEJ\n" +
-        "keacU223+DIhOKC49fa+EvhLNqo6U1oPn8n/yvBsvvnWkcynw5KfNzaLlaPmzugh\n" +
-        "v9xl/GhyZNAXc1QUcW3C+ceHVNrKnkfbTKZz5eRSo2MwYTALBgNVHQ8EBAMCA+gw\n" +
-        "HQYDVR0OBBYEFNMkPrt40oO9Dpy+bcbQdEvOlNlyMB8GA1UdIwQYMBaAFPXsdyou\n" +
-        "WWyqdnM/6QSVwZwEaa5uMBIGA1UdEQEB/wQIMAaHBH8AAAEwCwYJYIZIAWUDBAMC\n" +
-        "Ay8AMCwCFCvA2QiKSe/n+6GqSYQwgQ/zL5M9AhQfSiuWdMJKWpgPJKakvzhBUbMb\n" +
-        "vA==\n" +
-        "-----END CERTIFICATE-----"};
-
-    // Private key in the format of PKCS#8, key size is 1024 bits.
-    static String[] targetPrivateKey = {
-        // For cert DSA-SHA1
-        "MIIBSwIBADCCASwGByqGSM44BAEwggEfAoGBAPH+b+GSMX6KS7jXDRevzc464DFG\n" +
-        "4X+uxu5Vb3U4yhsU8A8cuH4gwin6L/IDkmZQ7N0zC0jRsiGVSMsFETTq10F39pH2\n" +
-        "eBfUv/hJcLfBnIjBEtVqV/dExK88Hul2sZ4mQihQ4issPl7hsroS9EWYicnX0oNA\n" +
-        "qAB9PO5YzKbfpL7TAhUA13WW48rln2UP/LaAgtnzKhqcNtMCgYEA3Rv0GirTbAao\n" +
-        "r8iURd82b5FlDTevOCTuq7ZIpfZVV30neS7cBYNet6m/3/4cfUlbbrqhbqIJ2I+I\n" +
-        "81drnN0YlyN4KkuxEcB6OTwfWkIUj6rvPaCQrBH8Q213bDq3HHtYNaP8OoeQUyVX\n" +
-        "W+SEGADCJ1+z8uqP3lIB6ltdgOiV/GQEFgIUOiB7J/lrFrNduQ8nDNTe8VspoAI=",
-
-        // For cert DSA-SHA224
-        "MIIBSwIBADCCASwGByqGSM44BAEwggEfAoGBAPH+b+GSMX6KS7jXDRevzc464DFG\n" +
-        "4X+uxu5Vb3U4yhsU8A8cuH4gwin6L/IDkmZQ7N0zC0jRsiGVSMsFETTq10F39pH2\n" +
-        "eBfUv/hJcLfBnIjBEtVqV/dExK88Hul2sZ4mQihQ4issPl7hsroS9EWYicnX0oNA\n" +
-        "qAB9PO5YzKbfpL7TAhUA13WW48rln2UP/LaAgtnzKhqcNtMCgYEA3Rv0GirTbAao\n" +
-        "r8iURd82b5FlDTevOCTuq7ZIpfZVV30neS7cBYNet6m/3/4cfUlbbrqhbqIJ2I+I\n" +
-        "81drnN0YlyN4KkuxEcB6OTwfWkIUj6rvPaCQrBH8Q213bDq3HHtYNaP8OoeQUyVX\n" +
-        "W+SEGADCJ1+z8uqP3lIB6ltdgOiV/GQEFgIUOj9F5mxWd9W1tiLSdsOAt8BUBzE=",
-
-        // For cert DSA-SHA256
-        "MIIBSwIBADCCASwGByqGSM44BAEwggEfAoGBAPH+b+GSMX6KS7jXDRevzc464DFG\n" +
-        "4X+uxu5Vb3U4yhsU8A8cuH4gwin6L/IDkmZQ7N0zC0jRsiGVSMsFETTq10F39pH2\n" +
-        "eBfUv/hJcLfBnIjBEtVqV/dExK88Hul2sZ4mQihQ4issPl7hsroS9EWYicnX0oNA\n" +
-        "qAB9PO5YzKbfpL7TAhUA13WW48rln2UP/LaAgtnzKhqcNtMCgYEA3Rv0GirTbAao\n" +
-        "r8iURd82b5FlDTevOCTuq7ZIpfZVV30neS7cBYNet6m/3/4cfUlbbrqhbqIJ2I+I\n" +
-        "81drnN0YlyN4KkuxEcB6OTwfWkIUj6rvPaCQrBH8Q213bDq3HHtYNaP8OoeQUyVX\n" +
-        "W+SEGADCJ1+z8uqP3lIB6ltdgOiV/GQEFgIUQ2WGgg+OO39Aujj0e4lM4pP4/9g="};
-
-
-    static char passphrase[] = "passphrase".toCharArray();
-
-    /*
      * Turn on SSL debugging?
      */
     static boolean debug = false;
@@ -209,6 +79,12 @@
      */
     volatile boolean serverReady = false;
 
+    private final Cert[] SERVER_CERTS = {
+            SSLContextTemplate.Cert.EE_DSA_SHA1_1024,
+            SSLContextTemplate.Cert.EE_DSA_SHA224_1024,
+            SSLContextTemplate.Cert.EE_DSA_SHA256_1024,
+    };
+
     /*
      * Define the server side of the test.
      *
@@ -216,9 +92,7 @@
      * to avoid infinite hangs.
      */
     void doServerSide() throws Exception {
-
-        SSLContext context = generateSSLContext(
-                null, targetCertStr, targetPrivateKey);
+        SSLContext context = createSSLContext(null, SERVER_CERTS, getServerContextParameters());
         SSLServerSocketFactory sslssf = context.getServerSocketFactory();
         try (SSLServerSocket sslServerSocket =
                 (SSLServerSocket)sslssf.createServerSocket(serverPort)) {
@@ -260,7 +134,7 @@
             Thread.sleep(50);
         }
 
-        SSLContext context = generateSSLContext(trustedCertStr, null, null);
+        SSLContext context = createSSLContext(new Cert[]{Cert.CA_DSA_SHA1_1024}, null, getClientContextParameters());
         SSLSocketFactory sslsf = context.getSocketFactory();
 
         try (SSLSocket sslSocket =
@@ -343,75 +217,14 @@
         cipherSuite = args[2];
     }
 
-    private static SSLContext generateSSLContext(String trustedCertStr,
-            String[] keyCertStrs, String[] keySpecStrs) throws Exception {
+    @Override
+    protected ContextParameters getServerContextParameters() {
+        return new ContextParameters("TLSv1.2", tmAlgorithm, "NewSunX509");
+    }
 
-        // generate certificate from cert string
-        CertificateFactory cf = CertificateFactory.getInstance("X.509");
-
-        // create a key store
-        KeyStore ks = KeyStore.getInstance("JKS");
-        ks.load(null, null);
-
-        // import the trused cert
-        Certificate trusedCert = null;
-        ByteArrayInputStream is = null;
-        if (trustedCertStr != null) {
-            is = new ByteArrayInputStream(trustedCertStr.getBytes());
-            trusedCert = cf.generateCertificate(is);
-            is.close();
-
-            ks.setCertificateEntry("DSA Signer", trusedCert);
-        }
-
-        if (keyCertStrs != null && keyCertStrs.length != 0) {
-            for (int i = 0; i < keyCertStrs.length; i++) {
-                String keyCertStr = keyCertStrs[i];
-                String keySpecStr = keySpecStrs[i];
-
-                // generate the private key.
-                PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec(
-                                Base64.getMimeDecoder().decode(keySpecStr));
-                KeyFactory kf = KeyFactory.getInstance("DSA");
-                DSAPrivateKey priKey =
-                        (DSAPrivateKey)kf.generatePrivate(priKeySpec);
-
-                // generate certificate chain
-                is = new ByteArrayInputStream(keyCertStr.getBytes());
-                Certificate keyCert = cf.generateCertificate(is);
-                is.close();
-
-                Certificate[] chain = null;
-                if (trusedCert != null) {
-                    chain = new Certificate[2];
-                    chain[0] = keyCert;
-                    chain[1] = trusedCert;
-                } else {
-                    chain = new Certificate[1];
-                    chain[0] = keyCert;
-                }
-
-                // import the key entry.
-                ks.setKeyEntry("DSA Entry " + i, priKey, passphrase, chain);
-            }
-        }
-
-        // create SSL context
-        TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmAlgorithm);
-        tmf.init(ks);
-
-        SSLContext ctx = SSLContext.getInstance("TLS");
-        if (keyCertStrs != null && keyCertStrs.length != 0) {
-            KeyManagerFactory kmf = KeyManagerFactory.getInstance("NewSunX509");
-            kmf.init(ks, passphrase);
-
-            ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
-            ks = null;
-        } else {
-            ctx.init(null, tmf.getTrustManagers(), null);
-        }
-
-        return ctx;
+    @Override
+    protected ContextParameters getClientContextParameters() {
+        return new ContextParameters("TLSv1.2", tmAlgorithm, "NewSunX509");
     }
 
 
diff --git a/test/jdk/javax/net/ssl/templates/SSLContextTemplate.java b/test/jdk/javax/net/ssl/templates/SSLContextTemplate.java
index 171807c..568575f 100644
--- a/test/jdk/javax/net/ssl/templates/SSLContextTemplate.java
+++ b/test/jdk/javax/net/ssl/templates/SSLContextTemplate.java
@@ -427,6 +427,34 @@
 
         ),
 
+        CA_RSA_MD5_512 ( // for ShortRSAKeys512 and ShortRSAKeyGCM tests
+                "RSA",
+                // Signature Algorithm: md5WithRSAEncryption
+                // Issuer: C = US, O = Java, OU = SunJSSE Test Serivce
+                // Validity
+                //     Not Before: Aug 19 01:52:19 2011 GMT
+                //     Not After : Jul 29 01:52:19 2032 GMT
+                // Authority Key Identifier:
+                //     B9:7C:D5:D9:DF:A7:4C:03:AE:FD:0E:27:5B:31:95:6C:C7:F3:75:E1
+                "-----BEGIN CERTIFICATE-----\n" +
+                "MIICkjCCAfugAwIBAgIBADANBgkqhkiG9w0BAQQFADA7MQswCQYDVQQGEwJVUzEN\n" +
+                "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n" +
+                "MTEwODE5MDE1MjE5WhcNMzIwNzI5MDE1MjE5WjA7MQswCQYDVQQGEwJVUzENMAsG\n" +
+                "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwgZ8wDQYJ\n" +
+                "KoZIhvcNAQEBBQADgY0AMIGJAoGBAM8orG08DtF98TMSscjGsidd1ZoN4jiDpi8U\n" +
+                "ICz+9dMm1qM1d7O2T+KH3/mxyox7Rc2ZVSCaUD0a3CkhPMnlAx8V4u0H+E9sqso6\n" +
+                "iDW3JpOyzMExvZiRgRG/3nvp55RMIUV4vEHOZ1QbhuqG4ebN0Vz2DkRft7+flthf\n" +
+                "vDld6f5JAgMBAAGjgaUwgaIwHQYDVR0OBBYEFLl81dnfp0wDrv0OJ1sxlWzH83Xh\n" +
+                "MGMGA1UdIwRcMFqAFLl81dnfp0wDrv0OJ1sxlWzH83XhoT+kPTA7MQswCQYDVQQG\n" +
+                "EwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2\n" +
+                "Y2WCAQAwDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQEE\n" +
+                "BQADgYEALlgaH1gWtoBZ84EW8Hu6YtGLQ/L9zIFmHonUPZwn3Pr//icR9Sqhc3/l\n" +
+                "pVTxOINuFHLRz4BBtEylzRIOPzK3tg8XwuLb1zd0db90x3KBCiAL6E6cklGEPwLe\n" +
+                "XYMHDn9eDsaq861Tzn6ZwzMgw04zotPMoZN0mVd/3Qca8UJFucE=\n" +
+                "-----END CERTIFICATE-----",
+                ""
+        ),
+
         CA_DSA_2048(
                 "DSA",
                 // SHA256withDSA, 2048 bits
@@ -477,6 +505,36 @@
                 "tXHs6lmu6+uBmtJ5I9ZMJHEao4E4icdDcJ1F6+/FQFxYVRfefjt5X6ob3bRBrZIQ" +
                 "xj4OzQQjAiEAsceWOM8do4etxp2zgnoNXV8PUUyqWhz1+0srcKV7FR4="),
 
+        CA_DSA_512(
+                "DSA",
+                // dsaWithSHA1, 512 bits
+                // Validity
+                //     Not Before: Feb 16 04:35:46 2016 GMT
+                //     Not After : Nov  3 04:35:46 2035 GMT
+                // Authority Key Identifier:
+                //    5F:8A:9B:3F:93:E0:07:1D:49:F0:12:7C:A8:48:1F:A0:A5:4B:4A:74
+                "-----BEGIN CERTIFICATE-----\n" +
+                "MIICUjCCAhGgAwIBAgIJAIiDrs/4W8rtMAkGByqGSM44BAMwHzELMAkGA1UEBhMC\n" +
+                "VVMxEDAOBgNVBAoTB0V4YW1wbGUwHhcNMTYwMjE2MDQzNTQ2WhcNMzUxMTAzMDQz\n" +
+                "NTQ2WjA5MQswCQYDVQQGEwJVUzEQMA4GA1UECgwHRXhhbXBsZTEYMBYGA1UEAwwP\n" +
+                "d3d3LmV4YW1wbGUuY29tMIHwMIGoBgcqhkjOOAQBMIGcAkEAs6A0p3TysTtVXGSv\n" +
+                "ThR/8GHpbL49KyWRJBMIlmLc5jl/wxJgnL1t07p4YTOEa6ecyTFos04Z8n2GARmp\n" +
+                "zYlUywIVAJLDcf4JXhZbguRFSQdWwWhZkh+LAkBLCzh3Xvpmc/5CDqU+QHqDcuSk\n" +
+                "5B8+ZHaHRi2KQ00ejilpF2qZpW5JdHe4m3Pggh0MIuaAGX+leM4JKlnObj14A0MA\n" +
+                "AkAYb+DYlFgStFhF1ip7rFzY8K6i/3ellkXI2umI/XVwxUQTHSlk5nFOep5Dfzm9\n" +
+                "pADJwuSe1qGHsHB5LpMZPVpto4GEMIGBMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgPo\n" +
+                "MB0GA1UdDgQWBBT8nsFyccF4q1dtpWE1dkNK5UiXtTAfBgNVHSMEGDAWgBRfips/\n" +
+                "k+AHHUnwEnyoSB+gpUtKdDAnBgNVHSUEIDAeBggrBgEFBQcDAQYIKwYBBQUHAwIG\n" +
+                "CCsGAQUFBwMDMAkGByqGSM44BAMDMAAwLQIUIcIlxpIwaZXdpMC+U076unR1Mp8C\n" +
+                "FQCD/NE8O0xwq57nwFfp7tUvUHYMMA==\n" +
+                "-----END CERTIFICATE-----",
+                "MIHGAgEAMIGoBgcqhkjOOAQBMIGcAkEAs6A0p3TysTtVXGSvThR/8GHpbL49KyWR\n" +
+                "JBMIlmLc5jl/wxJgnL1t07p4YTOEa6ecyTFos04Z8n2GARmpzYlUywIVAJLDcf4J\n" +
+                "XhZbguRFSQdWwWhZkh+LAkBLCzh3Xvpmc/5CDqU+QHqDcuSk5B8+ZHaHRi2KQ00e\n" +
+                "jilpF2qZpW5JdHe4m3Pggh0MIuaAGX+leM4JKlnObj14BBYCFHB2Wek2g5hpNj5y\n" +
+                "RQfCc6CFO0dv"
+        ),
+
         CA_DSA_1024(
                 "DSA",
                 // dsaWithSHA1, 1024 bits
@@ -558,6 +616,180 @@
                 "MEcCAQAwBQYDK2VxBDsEOd6/hRZqkUyTlJSwdN5gO/HnoWYda1fD83YUm5j6m2Bg\n" +
                 "hAQi+QadFsQLD7R6PI/4Q0twXqlKnxU5Ug=="),
 
+        CA_DSA_SHA1_1024( // for SignatureAlgorithms test
+                "DSA",
+                // Signature Algorithm: dsaWithSHA1
+                // Validity
+                //   Not Before: Dec  3 13:52:25 2015 GMT
+                //   Not After : Nov 12 13:52:25 2036 GMT
+                // Authority Key Identifier:
+                //     F5:EC:77:2A:2E:59:6C:AA:76:73:3F:E9:04:95:C1:9C:04:69:AE:6E
+                "-----BEGIN CERTIFICATE-----\n" +
+                "MIIDYTCCAyGgAwIBAgIJAK8/gw6zg/DPMAkGByqGSM44BAMwOzELMAkGA1UEBhMC\n" +
+                "VVMxDTALBgNVBAoTBEphdmExHTAbBgNVBAsTFFN1bkpTU0UgVGVzdCBTZXJpdmNl\n" +
+                "MB4XDTE1MTIwMzEzNTIyNVoXDTM2MTExMjEzNTIyNVowOzELMAkGA1UEBhMCVVMx\n" +
+                "DTALBgNVBAoTBEphdmExHTAbBgNVBAsTFFN1bkpTU0UgVGVzdCBTZXJpdmNlMIIB\n" +
+                "uDCCASwGByqGSM44BAEwggEfAoGBAPH+b+GSMX6KS7jXDRevzc464DFG4X+uxu5V\n" +
+                "b3U4yhsU8A8cuH4gwin6L/IDkmZQ7N0zC0jRsiGVSMsFETTq10F39pH2eBfUv/hJ\n" +
+                "cLfBnIjBEtVqV/dExK88Hul2sZ4mQihQ4issPl7hsroS9EWYicnX0oNAqAB9PO5Y\n" +
+                "zKbfpL7TAhUA13WW48rln2UP/LaAgtnzKhqcNtMCgYEA3Rv0GirTbAaor8iURd82\n" +
+                "b5FlDTevOCTuq7ZIpfZVV30neS7cBYNet6m/3/4cfUlbbrqhbqIJ2I+I81drnN0Y\n" +
+                "lyN4KkuxEcB6OTwfWkIUj6rvPaCQrBH8Q213bDq3HHtYNaP8OoeQUyVXW+SEGADC\n" +
+                "J1+z8uqP3lIB6ltdgOiV/GQDgYUAAoGBAOXRppuJSGdt6AiZkb81P1DCUgIUlZFI\n" +
+                "J9GxWrjbbHDmGllMwPNhK6dU7LJKJJuYVPW+95rUGlSJEjRqSlHuyHkNb6e3e7qx\n" +
+                "tmx1/oIyq+oLult50hBS7uBvLLR0JbIKjBzzkudL8Rjze4G/Wq7KDM2T1JOP49tW\n" +
+                "eocCvaC8h8uQo4GtMIGqMB0GA1UdDgQWBBT17HcqLllsqnZzP+kElcGcBGmubjBr\n" +
+                "BgNVHSMEZDBigBT17HcqLllsqnZzP+kElcGcBGmubqE/pD0wOzELMAkGA1UEBhMC\n" +
+                "VVMxDTALBgNVBAoTBEphdmExHTAbBgNVBAsTFFN1bkpTU0UgVGVzdCBTZXJpdmNl\n" +
+                "ggkArz+DDrOD8M8wDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAQYwCQYHKoZI\n" +
+                "zjgEAwMvADAsAhQ6Y1I6LtIEBMqNo8o6GIe4LLEJuwIUbVQUKi8tvtWyRoxm8AFV\n" +
+                "0axJYUU=\n" +
+                "-----END CERTIFICATE-----",
+                ""
+        ),
+
+        EE_DSA_SHA1_1024( // for SignatureAlgorithms test
+                "DSA",
+                // Signature Algorithm: dsaWithSHA1
+                // Validity
+                //    Not Before: Dec  3 13:52:25 2015 GMT
+                //    Not After : Aug 20 13:52:25 2035 GMT
+                // Authority Key Identifier:
+                //    F5:EC:77:2A:2E:59:6C:AA:76:73:3F:E9:04:95:C1:9C:04:69:AE:6E
+                "-----BEGIN CERTIFICATE-----\n" +
+                "MIIDKTCCAumgAwIBAgIJAOy5c0b+8stFMAkGByqGSM44BAMwOzELMAkGA1UEBhMC\n" +
+                "VVMxDTALBgNVBAoTBEphdmExHTAbBgNVBAsTFFN1bkpTU0UgVGVzdCBTZXJpdmNl\n" +
+                "MB4XDTE1MTIwMzEzNTIyNVoXDTM1MDgyMDEzNTIyNVowTzELMAkGA1UEBhMCVVMx\n" +
+                "DTALBgNVBAoMBEphdmExHTAbBgNVBAsMFFN1bkpTU0UgVGVzdCBTZXJpdmNlMRIw\n" +
+                "EAYDVQQDDAlsb2NhbGhvc3QwggG3MIIBLAYHKoZIzjgEATCCAR8CgYEA8f5v4ZIx\n" +
+                "fopLuNcNF6/NzjrgMUbhf67G7lVvdTjKGxTwDxy4fiDCKfov8gOSZlDs3TMLSNGy\n" +
+                "IZVIywURNOrXQXf2kfZ4F9S/+Elwt8GciMES1WpX90TErzwe6XaxniZCKFDiKyw+\n" +
+                "XuGyuhL0RZiJydfSg0CoAH087ljMpt+kvtMCFQDXdZbjyuWfZQ/8toCC2fMqGpw2\n" +
+                "0wKBgQDdG/QaKtNsBqivyJRF3zZvkWUNN684JO6rtkil9lVXfSd5LtwFg163qb/f\n" +
+                "/hx9SVtuuqFuognYj4jzV2uc3RiXI3gqS7ERwHo5PB9aQhSPqu89oJCsEfxDbXds\n" +
+                "Orcce1g1o/w6h5BTJVdb5IQYAMInX7Py6o/eUgHqW12A6JX8ZAOBhAACgYB+zYqn\n" +
+                "jJwG4GZpBIN/6qhzbp0flChsV+Trlu0SL0agAQzb6XdI/4JnO87Pgbxaxh3VNAj3\n" +
+                "3+Ghr1NLBuBfTKzJ4j9msWT3EpLupkMyNtXvBYM0iyMrll67lSjMdv++wLEw35Af\n" +
+                "/bzVcjGyA5Q0i0cuEzDmHTVfi0OydynbwSLxtKNjMGEwCwYDVR0PBAQDAgPoMB0G\n" +
+                "A1UdDgQWBBQXJI8AxM0qsYCbbkIMuI5zJ+nMEDAfBgNVHSMEGDAWgBT17HcqLlls\n" +
+                "qnZzP+kElcGcBGmubjASBgNVHREBAf8ECDAGhwR/AAABMAkGByqGSM44BAMDLwAw\n" +
+                "LAIUXgyJ0xll4FrZAKXi8bj7Kiz+SA4CFH9WCSZIBYA9lmJkiTgRS7iM/6IC\n" +
+                "-----END CERTIFICATE-----",
+                "MIIBSwIBADCCASwGByqGSM44BAEwggEfAoGBAPH+b+GSMX6KS7jXDRevzc464DFG\n" +
+                "4X+uxu5Vb3U4yhsU8A8cuH4gwin6L/IDkmZQ7N0zC0jRsiGVSMsFETTq10F39pH2\n" +
+                "eBfUv/hJcLfBnIjBEtVqV/dExK88Hul2sZ4mQihQ4issPl7hsroS9EWYicnX0oNA\n" +
+                "qAB9PO5YzKbfpL7TAhUA13WW48rln2UP/LaAgtnzKhqcNtMCgYEA3Rv0GirTbAao\n" +
+                "r8iURd82b5FlDTevOCTuq7ZIpfZVV30neS7cBYNet6m/3/4cfUlbbrqhbqIJ2I+I\n" +
+                "81drnN0YlyN4KkuxEcB6OTwfWkIUj6rvPaCQrBH8Q213bDq3HHtYNaP8OoeQUyVX\n" +
+                "W+SEGADCJ1+z8uqP3lIB6ltdgOiV/GQEFgIUOiB7J/lrFrNduQ8nDNTe8VspoAI="
+        ),
+
+        EE_DSA_SHA224_1024( // for SignatureAlgorithms test
+                "DSA",
+                // Signature Algorithm: dsa_with_SHA224
+                // Validity
+                //   Not Before: Dec  3 15:44:39 2015 GMT
+                //   Not After : Aug 20 15:44:39 2035 GMT
+                // Authority Key Identifier:
+                //   F5:EC:77:2A:2E:59:6C:AA:76:73:3F:E9:04:95:C1:9C:04:69:AE:6E
+                "-----BEGIN CERTIFICATE-----\n" +
+                "MIIDLzCCAuugAwIBAgIJAOy5c0b+8stGMAsGCWCGSAFlAwQDATA7MQswCQYDVQQG\n" +
+                "EwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2\n" +
+                "Y2UwHhcNMTUxMjAzMTU0NDM5WhcNMzUwODIwMTU0NDM5WjBPMQswCQYDVQQGEwJV\n" +
+                "UzENMAsGA1UECgwESmF2YTEdMBsGA1UECwwUU3VuSlNTRSBUZXN0IFNlcml2Y2Ux\n" +
+                "EjAQBgNVBAMMCWxvY2FsaG9zdDCCAbcwggEsBgcqhkjOOAQBMIIBHwKBgQDx/m/h\n" +
+                "kjF+iku41w0Xr83OOuAxRuF/rsbuVW91OMobFPAPHLh+IMIp+i/yA5JmUOzdMwtI\n" +
+                "0bIhlUjLBRE06tdBd/aR9ngX1L/4SXC3wZyIwRLValf3RMSvPB7pdrGeJkIoUOIr\n" +
+                "LD5e4bK6EvRFmInJ19KDQKgAfTzuWMym36S+0wIVANd1luPK5Z9lD/y2gILZ8yoa\n" +
+                "nDbTAoGBAN0b9Boq02wGqK/IlEXfNm+RZQ03rzgk7qu2SKX2VVd9J3ku3AWDXrep\n" +
+                "v9/+HH1JW266oW6iCdiPiPNXa5zdGJcjeCpLsRHAejk8H1pCFI+q7z2gkKwR/ENt\n" +
+                "d2w6txx7WDWj/DqHkFMlV1vkhBgAwidfs/Lqj95SAepbXYDolfxkA4GEAAKBgA81\n" +
+                "CJKEv+pwiqYgxtw/9rkQ9748WP3mKrEC06kjUG+94/Z9dQloNFFfj6LiO1bymc5l\n" +
+                "6QIR8XCi4Po3N80K3+WxhBGFhY+RkVWTh43JV8epb41aH2qiWErarBwBGEh8LyGT\n" +
+                "i30db+Nkz2gfvyz9H/9T0jmYgfLEOlMCusali1qHo2MwYTALBgNVHQ8EBAMCA+gw\n" +
+                "HQYDVR0OBBYEFBqSP0S4+X+zOCTEnlp2hbAjV/W5MB8GA1UdIwQYMBaAFPXsdyou\n" +
+                "WWyqdnM/6QSVwZwEaa5uMBIGA1UdEQEB/wQIMAaHBH8AAAEwCwYJYIZIAWUDBAMB\n" +
+                "AzEAMC4CFQChiRaOnAnsCSJFwdpK22jSxU/mhQIVALgLbj/G39+1Ej8UuSWnEQyU\n" +
+                "4DA+\n" +
+                "-----END CERTIFICATE-----",
+                "MIIBSwIBADCCASwGByqGSM44BAEwggEfAoGBAPH+b+GSMX6KS7jXDRevzc464DFG\n" +
+                "4X+uxu5Vb3U4yhsU8A8cuH4gwin6L/IDkmZQ7N0zC0jRsiGVSMsFETTq10F39pH2\n" +
+                "eBfUv/hJcLfBnIjBEtVqV/dExK88Hul2sZ4mQihQ4issPl7hsroS9EWYicnX0oNA\n" +
+                "qAB9PO5YzKbfpL7TAhUA13WW48rln2UP/LaAgtnzKhqcNtMCgYEA3Rv0GirTbAao\n" +
+                "r8iURd82b5FlDTevOCTuq7ZIpfZVV30neS7cBYNet6m/3/4cfUlbbrqhbqIJ2I+I\n" +
+                "81drnN0YlyN4KkuxEcB6OTwfWkIUj6rvPaCQrBH8Q213bDq3HHtYNaP8OoeQUyVX\n" +
+                "W+SEGADCJ1+z8uqP3lIB6ltdgOiV/GQEFgIUOj9F5mxWd9W1tiLSdsOAt8BUBzE="
+        ),
+
+        EE_DSA_SHA256_1024( // for SignatureAlgorithms test
+                "DSA",
+                // Signature Algorithm: dsa_with_SHA256
+                // Validity
+                //   Not Before: Dec  3 15:46:51 2015 GMT
+                //   Not After : Aug 20 15:46:51 2035 GMT
+                // Authority Key Identifier:
+                //   F5:EC:77:2A:2E:59:6C:AA:76:73:3F:E9:04:95:C1:9C:04:69:AE:6E
+                "-----BEGIN CERTIFICATE-----\n" +
+                "MIIDLTCCAuugAwIBAgIJAOy5c0b+8stHMAsGCWCGSAFlAwQDAjA7MQswCQYDVQQG\n" +
+                "EwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2\n" +
+                "Y2UwHhcNMTUxMjAzMTU0NjUxWhcNMzUwODIwMTU0NjUxWjBPMQswCQYDVQQGEwJV\n" +
+                "UzENMAsGA1UECgwESmF2YTEdMBsGA1UECwwUU3VuSlNTRSBUZXN0IFNlcml2Y2Ux\n" +
+                "EjAQBgNVBAMMCWxvY2FsaG9zdDCCAbcwggEsBgcqhkjOOAQBMIIBHwKBgQDx/m/h\n" +
+                "kjF+iku41w0Xr83OOuAxRuF/rsbuVW91OMobFPAPHLh+IMIp+i/yA5JmUOzdMwtI\n" +
+                "0bIhlUjLBRE06tdBd/aR9ngX1L/4SXC3wZyIwRLValf3RMSvPB7pdrGeJkIoUOIr\n" +
+                "LD5e4bK6EvRFmInJ19KDQKgAfTzuWMym36S+0wIVANd1luPK5Z9lD/y2gILZ8yoa\n" +
+                "nDbTAoGBAN0b9Boq02wGqK/IlEXfNm+RZQ03rzgk7qu2SKX2VVd9J3ku3AWDXrep\n" +
+                "v9/+HH1JW266oW6iCdiPiPNXa5zdGJcjeCpLsRHAejk8H1pCFI+q7z2gkKwR/ENt\n" +
+                "d2w6txx7WDWj/DqHkFMlV1vkhBgAwidfs/Lqj95SAepbXYDolfxkA4GEAAKBgEF7\n" +
+                "2qiYxGrjX4KCOy0k5nK/RYlgLy4gYDChihQpiaa+fbA5JOBOxPWsh7rdtmJuDrEJ\n" +
+                "keacU223+DIhOKC49fa+EvhLNqo6U1oPn8n/yvBsvvnWkcynw5KfNzaLlaPmzugh\n" +
+                "v9xl/GhyZNAXc1QUcW3C+ceHVNrKnkfbTKZz5eRSo2MwYTALBgNVHQ8EBAMCA+gw\n" +
+                "HQYDVR0OBBYEFNMkPrt40oO9Dpy+bcbQdEvOlNlyMB8GA1UdIwQYMBaAFPXsdyou\n" +
+                "WWyqdnM/6QSVwZwEaa5uMBIGA1UdEQEB/wQIMAaHBH8AAAEwCwYJYIZIAWUDBAMC\n" +
+                "Ay8AMCwCFCvA2QiKSe/n+6GqSYQwgQ/zL5M9AhQfSiuWdMJKWpgPJKakvzhBUbMb\n" +
+                "vA==\n" +
+                "-----END CERTIFICATE-----",
+                "MIIBSwIBADCCASwGByqGSM44BAEwggEfAoGBAPH+b+GSMX6KS7jXDRevzc464DFG\n" +
+                "4X+uxu5Vb3U4yhsU8A8cuH4gwin6L/IDkmZQ7N0zC0jRsiGVSMsFETTq10F39pH2\n" +
+                "eBfUv/hJcLfBnIjBEtVqV/dExK88Hul2sZ4mQihQ4issPl7hsroS9EWYicnX0oNA\n" +
+                "qAB9PO5YzKbfpL7TAhUA13WW48rln2UP/LaAgtnzKhqcNtMCgYEA3Rv0GirTbAao\n" +
+                "r8iURd82b5FlDTevOCTuq7ZIpfZVV30neS7cBYNet6m/3/4cfUlbbrqhbqIJ2I+I\n" +
+                "81drnN0YlyN4KkuxEcB6OTwfWkIUj6rvPaCQrBH8Q213bDq3HHtYNaP8OoeQUyVX\n" +
+                "W+SEGADCJ1+z8uqP3lIB6ltdgOiV/GQEFgIUQ2WGgg+OO39Aujj0e4lM4pP4/9g="
+        ),
+
+        EE_RSA_MD5_512 ( // for ShortRSAKeys512 and ShortRSAKeyGCM tests
+                "RSA",
+                // md5WithRSAEncryption
+                // Validity
+                //     Not Before: Nov  7 13:55:52 2011 GMT
+                //     Not After : Jul 25 13:55:52 2031 GMT
+                // Authority Key Identifier:
+                //     B9:7C:D5:D9:DF:A7:4C:03:AE:FD:0E:27:5B:31:95:6C:C7:F3:75:E1
+                "-----BEGIN CERTIFICATE-----\n" +
+                "MIICNDCCAZ2gAwIBAgIBDDANBgkqhkiG9w0BAQQFADA7MQswCQYDVQQGEwJVUzEN\n" +
+                "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n" +
+                "MTExMTA3MTM1NTUyWhcNMzEwNzI1MTM1NTUyWjBPMQswCQYDVQQGEwJVUzENMAsG\n" +
+                "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UxEjAQBgNV\n" +
+                "BAMTCWxvY2FsaG9zdDBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC3Pb49OSPfOD2G\n" +
+                "HSXFCFx1GJEZfqG9ZUf7xuIi/ra5dLjPGAaoY5QF2QOa8VnOriQCXDfyXHxsuRnE\n" +
+                "OomxL7EVAgMBAAGjeDB2MAsGA1UdDwQEAwID6DAdBgNVHQ4EFgQUXNCJK3/dtCIc\n" +
+                "xb+zlA/JINlvs/MwHwYDVR0jBBgwFoAUuXzV2d+nTAOu/Q4nWzGVbMfzdeEwJwYD\n" +
+                "VR0lBCAwHgYIKwYBBQUHAwEGCCsGAQUFBwMCBggrBgEFBQcDAzANBgkqhkiG9w0B\n" +
+                "AQQFAAOBgQB2qIDUxA2caMPpGtUACZAPRUtrGssCINIfItETXJZCx/cRuZ5sP4D9\n" +
+                "N1acoNDn0hCULe3lhXAeTC9NZ97680yJzregQMV5wATjo1FGsKY30Ma+sc/nfzQW\n" +
+                "+h/7RhYtoG0OTsiaDCvyhI6swkNJzSzrAccPY4+ZgU8HiDLzZTmM3Q==\n" +
+                "-----END CERTIFICATE-----",
+                "MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAtz2+PTkj3zg9hh0l\n" +
+                "xQhcdRiRGX6hvWVH+8biIv62uXS4zxgGqGOUBdkDmvFZzq4kAlw38lx8bLkZxDqJ\n" +
+                "sS+xFQIDAQABAkByx/5Oo2hQ/w2q4L8z+NTRlJ3vdl8iIDtC/4XPnfYfnGptnpG6\n" +
+                "ZThQRvbMZiai0xHQPQMszvAHjZVme1eDl3EBAiEA3aKJHynPVCEJhpfCLWuMwX5J\n" +
+                "1LntwJO7NTOyU5m8rPECIQDTpzn5X44r2rzWBDna/Sx7HW9IWCxNgUD2Eyi2nA7W\n" +
+                "ZQIgJerEorw4aCAuzQPxiGu57PB6GRamAihEAtoRTBQlH0ECIQDN08FgTtnesgCU\n" +
+                "DFYLLcw1CiHvc7fZw4neBDHCrC8NtQIgA8TOUkGnpCZlQ0KaI8KfKWI+vxFcgFnH\n" +
+                "3fnqsTgaUs4="
+        ),
+
         EE_ECDSA_SECP256R1(
                 "EC",
                 // SHA256withECDSA, curve secp256r1
diff --git a/test/jdk/javax/script/JDK_8196959/BadFactoryTest.sh b/test/jdk/javax/script/JDK_8196959/BadFactoryTest.sh
index 21becec..e5d1a06 100644
--- a/test/jdk/javax/script/JDK_8196959/BadFactoryTest.sh
+++ b/test/jdk/javax/script/JDK_8196959/BadFactoryTest.sh
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -56,5 +56,5 @@
 
 echo "Running test without security manager ..."
 $JAVA ${TESTVMOPTS} -classpath \
-  "${TESTCLASSES}${PS}${TESTCLASSES}/badfactoty.jar" \
+  "${TESTCLASSES}${PS}${TESTCLASSES}/badfactory.jar" \
   BadFactoryTest
diff --git a/test/jdk/javax/security/auth/Subject/DoAs.java b/test/jdk/javax/security/auth/Subject/DoAsTest.java
similarity index 95%
rename from test/jdk/javax/security/auth/Subject/DoAs.java
rename to test/jdk/javax/security/auth/Subject/DoAsTest.java
index 7f378be..e042573 100644
--- a/test/jdk/javax/security/auth/Subject/DoAs.java
+++ b/test/jdk/javax/security/auth/Subject/DoAsTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -36,7 +36,7 @@
 import java.util.Set;
 import javax.security.auth.Subject;
 
-public class DoAs {
+public class DoAsTest {
 
     public static void main(String[] args) throws Exception {
         final Set<String> outer = new HashSet<>(Arrays.asList("Outer"));
diff --git a/test/jdk/javax/sound/midi/SysexMessage/SendRawSysexMessage.java b/test/jdk/javax/sound/midi/SysexMessage/SendRawSysexMessage.java
index 591def6..2a33d28 100644
--- a/test/jdk/javax/sound/midi/SysexMessage/SendRawSysexMessage.java
+++ b/test/jdk/javax/sound/midi/SysexMessage/SendRawSysexMessage.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -34,8 +34,9 @@
 
 /**
  * @test
- * @bug 8237495
- * @summary fail with a dereferenced memory error when asked to send a raw 0xF7
+ * @bug 8237495 8301310
+ * @summary fail with memory errors when asked to send a sysex message starting
+ *          with 0xF7
  */
 public final class SendRawSysexMessage {
 
@@ -113,6 +114,16 @@
                         (byte) SPECIAL_SYSTEM_EXCLUSIVE}), -1);
                 System.err.println("note off");
                 r.send(new ShortMessage(ShortMessage.NOTE_OFF, 5, 5), -1);
+                System.err.println("sysex part 1 of 3");
+                r.send(new SysexMessage(new byte[]{
+                        (byte) SYSTEM_EXCLUSIVE, 0x7D, 0x01, 0x02}, 4), -1);
+                System.err.println("sysex part 2 of 3");
+                r.send(new SysexMessage(new byte[]{
+                        (byte) SPECIAL_SYSTEM_EXCLUSIVE, 0x03, 0x04}, 3), -1);
+                System.err.println("sysex part 3 of 3");
+                r.send(new SysexMessage(new byte[]{
+                        (byte) SPECIAL_SYSTEM_EXCLUSIVE, 0x05, 0x06, 0x07,
+                        (byte) SPECIAL_SYSTEM_EXCLUSIVE}, 4), -1);
                 System.err.println("done, should quit");
                 System.err.println();
             }
diff --git a/test/jdk/javax/sound/sampled/Lines/OpenLineAfterScreenLock.java b/test/jdk/javax/sound/sampled/Lines/OpenLineAfterScreenLock.java
new file mode 100644
index 0000000..dcfeccb
--- /dev/null
+++ b/test/jdk/javax/sound/sampled/Lines/OpenLineAfterScreenLock.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.BorderLayout;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.util.Arrays;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import javax.sound.sampled.AudioSystem;
+import javax.sound.sampled.Line;
+import javax.sound.sampled.LineUnavailableException;
+import javax.sound.sampled.Mixer;
+import javax.sound.sampled.TargetDataLine;
+import javax.swing.JButton;
+import javax.swing.JFileChooser;
+import javax.swing.JFrame;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+
+import static javax.swing.SwingUtilities.invokeAndWait;
+
+/*
+ * @test
+ * @bug 8301846
+ * @requires (os.family == "windows")
+ * @summary Sound recording fails after screen lock and unlock.
+ * @run main/manual OpenLineAfterScreenLock
+ */
+public class OpenLineAfterScreenLock {
+
+    private static final String INSTRUCTIONS = """
+            This test verifies it can record sound from the first sound capture device after
+            locking and unlocking the screen. The first part of the test has already completed.
+
+            Lock the screen and unlock it. Then click Continue to complete the test.
+
+            The test will finish automatically.
+            """;
+
+    private static final CountDownLatch latch = new CountDownLatch(1);
+
+    private static JFrame frame;
+
+    public static void main(String[] args) throws Exception {
+        try {
+            runTest();
+
+            // Creating JFileChooser initializes COM
+            // which affects ability to open audio lines
+            new JFileChooser();
+
+            invokeAndWait(OpenLineAfterScreenLock::createInstructionsUI);
+            if (!latch.await(2, TimeUnit.MINUTES)) {
+                throw new RuntimeException("Test failed: Test timed out!!");
+            }
+
+            runTest();
+        } finally {
+            invokeAndWait(() -> {
+                if (frame != null) {
+                    frame.dispose();
+                }
+            });
+        }
+        System.out.println("Test Passed");
+    }
+
+    private static void runTest() {
+        try {
+            Mixer mixer = getMixer();
+            TargetDataLine line =
+                    (TargetDataLine) mixer.getLine(mixer.getTargetLineInfo()[0]);
+            line.open();
+            line.close();
+        } catch (LineUnavailableException e) {
+            throw new RuntimeException("Test failed: Line unavailable", e);
+        }
+    }
+
+    private static Mixer getMixer() {
+        return Arrays.stream(AudioSystem.getMixerInfo())
+                     .map(AudioSystem::getMixer)
+                     .filter(OpenLineAfterScreenLock::isRecordingDevice)
+                     .skip(1) // Skip the primary driver and choose one directly
+                     .findAny()
+                     .orElseThrow();
+    }
+
+    private static boolean isRecordingDevice(Mixer mixer) {
+        Line.Info[] lineInfos = mixer.getTargetLineInfo();
+        return lineInfos.length > 0
+               && lineInfos[0].getLineClass() == TargetDataLine.class;
+    }
+
+    private static void createInstructionsUI() {
+        frame = new JFrame("Instructions for OpenLineAfterScreenLock");
+
+        JTextArea textArea = new JTextArea(INSTRUCTIONS);
+        textArea.setEditable(false);
+
+        JScrollPane pane = new JScrollPane(textArea);
+        frame.getContentPane().add(pane, BorderLayout.NORTH);
+
+        JButton button = new JButton("Continue");
+        button.addActionListener(e -> latch.countDown());
+        frame.getContentPane().add(button, BorderLayout.PAGE_END);
+
+        frame.pack();
+        frame.setLocationRelativeTo(null);
+
+        frame.addWindowListener(new CloseWindowHandler());
+        frame.setVisible(true);
+    }
+
+    private static class CloseWindowHandler extends WindowAdapter {
+        @Override
+        public void windowClosing(WindowEvent e) {
+            latch.countDown();
+            throw new RuntimeException("Test window closed abruptly");
+        }
+    }
+}
diff --git a/test/jdk/javax/swing/BoxLayout/NPECheckRequests/NPECheckRequests.java b/test/jdk/javax/swing/BoxLayout/NPECheckRequests/NPECheckRequests.java
new file mode 100644
index 0000000..d696b03
--- /dev/null
+++ b/test/jdk/javax/swing/BoxLayout/NPECheckRequests/NPECheckRequests.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2024 JetBrains s.r.o.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary BoxLayout doesn't ignore invisible components
+ * @key headful
+ * @run main NPECheckRequests
+ */
+
+import java.awt.BorderLayout;
+import java.lang.reflect.InvocationTargetException;
+import java.awt.Dimension;
+import java.util.logging.Logger;
+import javax.swing.BoxLayout;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.SwingUtilities;
+
+public class NPECheckRequests {
+    private static final Logger LOG = Logger.getLogger(NPECheckRequests.class.getName());
+    JFrame frame;
+    JPanel p;
+    BrokenComponent foo;
+
+    public void init() {
+        frame = new JFrame() {
+            @Override
+            public void validate() {
+                try {
+                    super.validate();
+                } catch (BrokenComponentException e) {
+                    if (foo.broken) {
+                        LOG.info("Caught BrokenComponentException in JFrame.validate() - expected, ignored");
+                    } else {
+                        throw e;
+                    }
+                }
+            }
+        };
+        p = new JPanel();
+        BoxLayout boxLayout = new BoxLayout(p, BoxLayout.X_AXIS);
+        p.setLayout(boxLayout);
+        foo = new BrokenComponent();
+        p.add(foo);
+        frame.setLayout(new BorderLayout());
+        frame.add(p, BorderLayout.CENTER);
+        try {
+            frame.pack();
+        } catch (BrokenComponentException ignored) {
+            LOG.info("Caught BrokenComponentException in JFrame.pack() - expected, ignored");
+        }
+    }
+
+    public void start() {
+        foo.broken = false;
+        // check that the layout isn't in a broken state because of that exception
+        frame.pack();
+    }
+
+    public static void main(String[] args) throws InterruptedException,
+            InvocationTargetException {
+        NPECheckRequests test = new NPECheckRequests();
+        SwingUtilities.invokeAndWait(test::init);
+        SwingUtilities.invokeAndWait(test::start);
+    }
+
+    private class BrokenComponent extends JPanel {
+
+        boolean broken = true;
+
+        @Override
+        public Dimension getPreferredSize() {
+            if (broken) {
+                throw new BrokenComponentException();
+            }
+            return super.getPreferredSize();
+        }
+    }
+
+    private static class BrokenComponentException extends RuntimeException {
+        BrokenComponentException() {
+            super("Broken component");
+        }
+    }
+
+}
diff --git a/test/jdk/javax/swing/JComboBox/JComboBoxActionEvent.java b/test/jdk/javax/swing/JComboBox/JComboBoxActionEvent.java
new file mode 100644
index 0000000..769d2dc
--- /dev/null
+++ b/test/jdk/javax/swing/JComboBox/JComboBoxActionEvent.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8290399
+ * @requires (os.family == "mac")
+ * @library /java/awt/regtesthelpers
+ * @build PassFailJFrame
+ * @summary Tests if AquaL&F fire actionevent if combobox menu is displayed.
+ * @run main/manual JComboBoxActionEvent
+ */
+
+import java.awt.FlowLayout;
+
+import javax.swing.JComboBox;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+
+public class JComboBoxActionEvent {
+    private static final String instructionsText = " Click the arrow to display the menu.\n" +
+         "While the menu is displayed, edit the text to create a new value.\n" +
+         "Type return.\n" +
+         "If a dialog appears with \"ActionCommand received\"\n" +
+         "press Pass, else Fail";
+
+    private static JFrame frame;
+
+    public static void createAndShowGUI() throws Exception {
+        SwingUtilities.invokeAndWait(() -> {
+
+            JComboBox<String> comboBox = new JComboBox<>(new String[]
+                    { "Apple", "Orange", "Pear" });
+            comboBox.setEditable(true);
+            comboBox.addActionListener(e -> {
+               System.out.println("Action Listener called: " + e.getActionCommand());
+               if (e.getActionCommand().contains("comboBoxEdited")) {
+                   JOptionPane.showMessageDialog(null, "ActionCommand received");
+               }
+            });
+
+            FlowLayout layout = new FlowLayout();
+            JPanel panel = new JPanel(layout);
+            panel.add(comboBox);
+            frame = new JFrame("Test Editable Combo Box");
+            frame.getContentPane().add(panel);
+            frame.setVisible(true);
+            frame.pack();
+            frame.setLocationRelativeTo(null);
+
+            PassFailJFrame.addTestWindow(frame);
+            PassFailJFrame.positionTestWindow(frame,
+                    PassFailJFrame.Position.HORIZONTAL);
+        });
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        UIManager.setLookAndFeel("com.apple.laf.AquaLookAndFeel");
+
+        PassFailJFrame pfjFrame = new PassFailJFrame("JScrollPane "
+                + "Test Instructions", instructionsText, 5);
+
+        createAndShowGUI();
+
+        pfjFrame.awaitAndCheck();
+    }
+}
diff --git a/test/jdk/javax/swing/JComboBox/JComboBoxWithTitledBorderTest.java b/test/jdk/javax/swing/JComboBox/JComboBoxWithTitledBorderTest.java
new file mode 100644
index 0000000..29ff196
--- /dev/null
+++ b/test/jdk/javax/swing/JComboBox/JComboBoxWithTitledBorderTest.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Robot;
+import java.awt.Toolkit;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.io.File;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.stream.Collectors;
+
+import javax.imageio.ImageIO;
+import javax.swing.BorderFactory;
+import javax.swing.JComboBox;
+import javax.swing.JComponent;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+import javax.swing.UIManager.LookAndFeelInfo;
+import javax.swing.UnsupportedLookAndFeelException;
+
+import static javax.swing.UIManager.getInstalledLookAndFeels;
+
+/*
+ * @test
+ * @key headful
+ * @bug 8300269
+ * @summary This test verifies the issue: Can't see the selected JComboBox
+ *          item if it has a titled border.
+ * @run main JComboBoxWithTitledBorderTest
+ */
+public class JComboBoxWithTitledBorderTest {
+    private static final String[] comboStrings =
+            {"First", "Second", "Third", "Fourth"};
+    private static JFrame frame;
+    private static JComboBox<String> combo;
+    private static Robot robot;
+
+    public static void main(String[] argv) throws Exception {
+        robot = new Robot();
+        robot.setAutoWaitForIdle(true);
+        robot.setAutoDelay(200);
+        List<String> lafs = Arrays.stream(getInstalledLookAndFeels())
+                .map(LookAndFeelInfo::getClassName)
+                .collect(Collectors.toList());
+        for (final String laf : lafs) {
+            // Skip GTK L&F because pressing ENTER after editing JComboBox
+            // doesn't change text and resets to starting text instead.
+            if (laf.equals("com.sun.java.swing.plaf.gtk.GTKLookAndFeel")) {
+                continue;
+            }
+            try {
+                AtomicBoolean lafSetSuccess = new AtomicBoolean(false);
+                System.out.println("Setting LAF: " + laf);
+                SwingUtilities.invokeAndWait(() -> {
+                    lafSetSuccess.set(setLookAndFeel(laf));
+                    if (lafSetSuccess.get()) {
+                        createAndShowGUI(laf);
+                    }
+                });
+                if (!lafSetSuccess.get()) {
+                    continue;
+                }
+                robot.waitForIdle();
+
+                mouseClick(combo);
+
+                hitKeys(KeyEvent.VK_RIGHT, KeyEvent.VK_BACK_SPACE,
+                        KeyEvent.VK_ENTER);
+                String item = (String) combo.getSelectedItem();
+                System.out.println("Current item: " + item);
+                // Deletes the last character of the combo item and check
+                // whether its getting reflected in item. Bug JDK-8300269: It's
+                // not getting reflected in case of AquaLookAndFeel.
+                if ("Firs".equals(item)) {
+                    System.out.println("Test Passed for " + laf);
+                } else {
+                    captureScreen();
+                    throw new RuntimeException("Test Failed for " + laf);
+                }
+            } finally {
+                SwingUtilities.invokeAndWait(
+                        JComboBoxWithTitledBorderTest::disposeFrame);
+            }
+        }
+    }
+
+    private static void hitKeys(int... keys) {
+        for (int key : keys) {
+            robot.keyPress(key);
+        }
+        for (int i = keys.length - 1; i >= 0; i--) {
+            robot.keyRelease(keys[i]);
+        }
+    }
+
+    private static void mouseClick(JComponent jComponent) throws Exception {
+        final AtomicReference<Point> loc = new AtomicReference<>();
+        SwingUtilities
+                .invokeAndWait(() -> loc.set(jComponent.getLocationOnScreen()));
+        final Point location = loc.get();
+        robot.mouseMove(location.x + 25, location.y + 5);
+        robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
+        robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
+    }
+
+    private static void createAndShowGUI(final String laf) {
+        frame = new JFrame("JComboBox with Titled Border test");
+        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
+
+        JPanel panel = new JPanel();
+        combo = new JComboBox<>(comboStrings);
+        combo.setEditable(true);
+
+        // Create a titled border for the ComboBox with the LAF name as title.
+        String[] lafStrings = laf.split("[.]");
+        combo.setBorder(BorderFactory.createTitledBorder(
+                lafStrings[lafStrings.length - 1]));
+        panel.add(combo);
+        frame.getContentPane().add(panel);
+        frame.pack();
+        frame.setLocationRelativeTo(null);
+        frame.setVisible(true);
+    }
+
+    private static boolean setLookAndFeel(String lafName) {
+        try {
+            UIManager.setLookAndFeel(lafName);
+        } catch (UnsupportedLookAndFeelException ignored) {
+            System.out.println("Ignoring Unsupported LAF: " + lafName);
+            return false;
+        } catch (ClassNotFoundException | InstantiationException
+                | IllegalAccessException e) {
+            throw new RuntimeException(e);
+        }
+        return true;
+    }
+
+    private static void disposeFrame() {
+        if (frame != null) {
+            frame.dispose();
+            frame = null;
+        }
+    }
+
+    private static void captureScreen() {
+        try {
+            final Rectangle screenBounds = new Rectangle(
+                    Toolkit.getDefaultToolkit().getScreenSize());
+            ImageIO.write(robot.createScreenCapture(screenBounds),
+                    "png", new File("failScreen.png"));
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/test/jdk/javax/swing/JComboBox/TestComboBoxHeight.java b/test/jdk/javax/swing/JComboBox/TestComboBoxHeight.java
new file mode 100644
index 0000000..5cd5edc
--- /dev/null
+++ b/test/jdk/javax/swing/JComboBox/TestComboBoxHeight.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @key headful
+ * @bug 4517214
+ * @summary Tests that comboBox is not doubleheight if editable and has TitledBorder
+*/
+
+import javax.swing.BorderFactory;
+import javax.swing.JComboBox;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.SwingUtilities;
+import javax.swing.WindowConstants;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Robot;
+
+public class TestComboBoxHeight {
+    private static String[] data = { "Ten", "Twenty", "Forty-three" };
+    private static JFrame jframe;
+    private static int heightCombo1, heightCombo2;
+    private static JComboBox combo1, combo2;
+
+    public static void main(String[] args) throws Exception {
+        try {
+            Robot robot = new Robot();
+            robot.setAutoDelay(100);
+            SwingUtilities.invokeAndWait(() -> {
+                jframe = new JFrame();
+
+                GridBagLayout gridBag = new GridBagLayout();
+                GridBagConstraints c = new GridBagConstraints();
+                JPanel p = new JPanel(gridBag);
+                c.fill = GridBagConstraints.NONE;
+
+                // fine-looking combo
+                combo1 = new JComboBox(data);
+                combo1.setEditable(true);
+                gridBag.setConstraints(combo1, c);
+                p.add(combo1);
+
+                // combo has border
+                combo2 = new JComboBox(data);
+                combo2.setEditable(true);
+                combo2.setBorder(BorderFactory.
+                        createTitledBorder("Combo Border"));
+                gridBag.setConstraints(combo2, c);
+                p.add(combo2);
+
+                jframe.setContentPane(p);
+                jframe.setLocationRelativeTo(null);
+                jframe.setSize(400, 200);
+                jframe.setDefaultCloseOperation(
+                        WindowConstants.DISPOSE_ON_CLOSE);
+                jframe.setVisible(true);
+            });
+
+            robot.delay(1000);
+            robot.waitForIdle();
+            SwingUtilities.invokeAndWait(() -> {
+                heightCombo1 = combo1.getHeight();
+                heightCombo2 = combo2.getHeight();
+            });
+
+            if (heightCombo2 >= heightCombo1 * 2) {
+                throw new RuntimeException("combo boxes with border " +
+                 " should not have double height compared to normal combobox");
+            }
+        } finally {
+            SwingUtilities.invokeAndWait(() -> {
+                if (jframe != null) {
+                    jframe.dispose();
+                }
+            });
+        }
+    }
+}
diff --git a/test/jdk/javax/swing/JInternalFrame/bug4268949.java b/test/jdk/javax/swing/JInternalFrame/bug4268949.java
new file mode 100644
index 0000000..83a200b
--- /dev/null
+++ b/test/jdk/javax/swing/JInternalFrame/bug4268949.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4268949
+ * @summary Tests if JInternalFrame can do setBackground()
+ * @run main bug4268949
+ */
+
+import java.awt.Color;
+import javax.swing.JInternalFrame;
+import javax.swing.SwingUtilities;
+
+public class bug4268949 {
+
+    static Color c1;
+    static Color c2;
+    static Color c3;
+
+    public static void main(String[] argv) throws Exception {
+        SwingUtilities.invokeAndWait(() -> {
+            JInternalFrame if1, if2, if3;
+            if1 = new JInternalFrame("Frame 1");
+            if2 = new JInternalFrame("Frame 2");
+            if3 = new JInternalFrame("Frame 3");
+            if1.setBounds(20, 20, 95, 95);
+            if2.setBounds(120, 20, 95, 95);
+            if3.setBounds(220, 20, 95, 95);
+            if1.setBackground(Color.red);
+            if2.setBackground(Color.blue);
+            if3.setBackground(Color.green);
+            c1 = if1.getContentPane().getBackground();
+            c2 = if2.getContentPane().getBackground();
+            c3 = if3.getContentPane().getBackground();
+        });
+        if (!(c1.equals(Color.red)) || !(c2.equals(Color.blue))
+                || !(c3.equals(Color.green))) {
+            throw new RuntimeException("Test failed: JInternalFrame " +
+                    "cannot do setBackground()");
+        }
+    }
+}
diff --git a/test/jdk/javax/swing/JInternalFrame/bug4309079.java b/test/jdk/javax/swing/JInternalFrame/bug4309079.java
new file mode 100644
index 0000000..b87748c
--- /dev/null
+++ b/test/jdk/javax/swing/JInternalFrame/bug4309079.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4309079
+ * @summary Tests that when a JInternalFrame is activated,
+            focused JTextField shows cursor.
+ * @key headful
+ * @run main bug4309079
+ */
+
+import java.awt.FlowLayout;
+import java.awt.Point;
+import java.awt.Robot;
+import java.awt.event.InputEvent;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import javax.swing.JFrame;
+import javax.swing.JDesktopPane;
+import javax.swing.JInternalFrame;
+import javax.swing.JTextField;
+import javax.swing.SwingUtilities;
+
+public class bug4309079 {
+
+    private static JFrame f;
+    private static JTextField tf;
+    private static JDesktopPane desktop;
+    private static JInternalFrame f1;
+    private static JInternalFrame f2;
+    private static volatile boolean passed = true;
+    private static volatile Point p;
+
+    public static void main(String[] args) throws Exception {
+        try {
+            Robot robot = new Robot();
+            robot.setAutoDelay(100);
+            SwingUtilities.invokeAndWait(() -> {
+                f = new JFrame();
+                f.setSize(500, 300);
+                tf = new JTextField(10);
+                tf.addFocusListener(new FocusListener() {
+                    public void focusGained(FocusEvent e) {
+                        passed = tf.getCaret().isVisible();
+                    }
+                    public void focusLost(FocusEvent e) {
+                    }
+                });
+                tf.requestFocus();
+                f1 = AddFrame(new JTextField(10));
+                f2 = AddFrame(tf);
+                f.getContentPane().add(desktop);
+                f.setVisible(true);
+            });
+            robot.waitForIdle();
+            robot.delay(500);
+
+            SwingUtilities.invokeAndWait(() -> {
+                f1.toFront();
+                f2.toFront();
+                p = tf.getLocationOnScreen();
+            });
+            robot.mouseMove(p.x, p.y);
+            robot.mousePress(InputEvent.BUTTON1_DOWN_MASK );
+            robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK );
+
+            if (!passed) {
+                throw new RuntimeException("Test failed.");
+            }
+        } finally {
+            SwingUtilities.invokeAndWait(() -> {
+                if (f != null) {
+                    f.dispose();
+                }
+            });
+        }
+    }
+
+    private static JInternalFrame AddFrame(JTextField tf) {
+        JInternalFrame frame = new JInternalFrame();
+        desktop = new JDesktopPane();
+        desktop.add(frame);
+        frame.getContentPane().setLayout(new FlowLayout());
+        frame.getContentPane().add(tf);
+        frame.setSize(300, 200);
+        frame.setVisible(true);
+        return frame;
+    }
+}
diff --git a/test/jdk/javax/swing/JInternalFrame/bug4732229.java b/test/jdk/javax/swing/JInternalFrame/bug4732229.java
new file mode 100644
index 0000000..bf3eefe
--- /dev/null
+++ b/test/jdk/javax/swing/JInternalFrame/bug4732229.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4732229
+ * @summary Ctrl+Space, bringing up System menu on a JIF errors using Win LAF
+ * @key headful
+ * @run main bug4732229
+ */
+
+import javax.swing.JFrame;
+import javax.swing.JDesktopPane;
+import javax.swing.JInternalFrame;
+import javax.swing.JTextArea;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+import java.awt.Robot;
+import java.awt.event.FocusAdapter;
+import java.awt.event.FocusEvent;
+import java.awt.event.KeyEvent;
+
+public class bug4732229 {
+
+    JFrame frame;
+    JDesktopPane desktop;
+    JInternalFrame jif;
+    JTextArea ta;
+    Robot robot;
+    volatile boolean keyTyped = false;
+
+    public static void main(String[] args) throws Exception {
+        bug4732229 b = new bug4732229();
+        b.init();
+    }
+
+    public void init() throws Exception {
+        robot = new Robot();
+        robot.setAutoDelay(100);
+        try {
+            SwingUtilities.invokeAndWait(() -> {
+                frame = new JFrame("bug4732229");
+                desktop = new JDesktopPane();
+                frame.getContentPane().add(desktop);
+
+                ta = new JTextArea();
+                ta.addFocusListener(new FocusAdapter() {
+                    public void focusGained(FocusEvent e) {
+                        synchronized (bug4732229.this) {
+                            keyTyped = true;
+                            bug4732229.this.notifyAll();
+                        }
+                    }
+                });
+                frame.setSize(200, 200);
+                frame.setLocationRelativeTo(null);
+                frame.setVisible(true);
+                jif = new JInternalFrame("Internal Frame", true, false, true,
+                        true);
+                jif.setBounds(10, 10, 100, 100);
+                jif.getContentPane().add(ta);
+                jif.setVisible(true);
+                desktop.add(jif);
+                try {
+                    jif.setSelected(true);
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+
+            });
+            synchronized (this) {
+                while (!keyTyped) {
+                    bug4732229.this.wait();
+                }
+            }
+            robot.waitForIdle();
+            robot.delay(200);
+            robot.keyPress(KeyEvent.VK_CONTROL);
+            robot.keyPress(KeyEvent.VK_SPACE);
+            robot.keyRelease(KeyEvent.VK_SPACE);
+            robot.keyRelease(KeyEvent.VK_CONTROL);
+            robot.waitForIdle();
+            robot.delay(200);
+            SwingUtilities.invokeAndWait(() -> {
+                try {
+                    jif.setSelected(false);
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+                jif.setVisible(false);
+                desktop.remove(jif);
+                try {
+                    UIManager.setLookAndFeel(
+                            UIManager.getSystemLookAndFeelClassName());
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+                desktop.updateUI();
+
+                jif = new JInternalFrame("Internal Frame", true, false, true,
+                        true);
+                jif.setBounds(10, 10, 100, 100);
+                jif.getContentPane().add(ta);
+                jif.setVisible(true);
+                desktop.add(jif);
+                try {
+                    jif.setSelected(true);
+                } catch (Exception e) {
+                    throw new RuntimeException(e);
+                }
+            });
+            synchronized (this) {
+                while (!keyTyped) {
+                    bug4732229.this.wait();
+                }
+            }
+            robot.keyPress(KeyEvent.VK_CONTROL);
+            robot.keyPress(KeyEvent.VK_SPACE);
+            robot.keyRelease(KeyEvent.VK_SPACE);
+            robot.keyRelease(KeyEvent.VK_CONTROL);
+            robot.waitForIdle();
+            robot.delay(200);
+        } finally {
+            SwingUtilities.invokeAndWait(() -> {
+                if (frame != null) {
+                    frame.dispose();
+                }
+            });
+        }
+    }
+}
diff --git a/test/jdk/javax/swing/JInternalFrame/bug5009724.java b/test/jdk/javax/swing/JInternalFrame/bug5009724.java
new file mode 100644
index 0000000..aab8623
--- /dev/null
+++ b/test/jdk/javax/swing/JInternalFrame/bug5009724.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 5009724
+ * @requires (os.family == "linux")
+ * @summary JInternalFrame not serializable in GTK L&F
+ * @key headful
+ * @run main bug5009724
+ */
+
+import java.awt.event.ActionEvent;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import javax.swing.AbstractAction;
+import javax.swing.JInternalFrame;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+
+public class bug5009724 {
+
+    public static void main(String []args) throws Exception {
+        UIManager.setLookAndFeel("com.sun.java.swing.plaf.gtk.GTKLookAndFeel");
+        SwingUtilities.invokeAndWait(() -> {
+            JInternalFrame frame = new JInternalFrame();
+            ObjectOutputStream out = null;
+            ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
+            try {
+                out = new ObjectOutputStream(byteStream);
+            } catch (IOException e) {
+
+            }
+            if (out != null) {
+                System.out.println("Testing...");
+                try {
+                    out.writeObject(frame);
+                } catch (Exception e) {
+                    System.out.println(e);
+                    throw new RuntimeException("Serialization exception. Test failed.");
+                }
+            }
+        });
+    }
+}
diff --git a/test/jdk/javax/swing/JList/bug4300224.java b/test/jdk/javax/swing/JList/bug4300224.java
new file mode 100644
index 0000000..570a432
--- /dev/null
+++ b/test/jdk/javax/swing/JList/bug4300224.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4300224
+ * @summary BasicListUI.ListDataHandler improperly updates list selection on insertion
+ * @run main bug4300224
+ */
+
+import javax.swing.JList;
+import javax.swing.DefaultListModel;
+
+public class bug4300224 {
+
+    public static void main(String[] args) throws Exception {
+        DefaultListModel<String> model = new DefaultListModel<>();
+        JList<String> list = new JList<>(model);
+
+        model.addElement("List Item 1");
+        model.addElement("List Item 2");
+        model.addElement("List Item 3");
+        model.addElement("List Item 4");
+        list.setSelectedIndex(2);
+        model.insertElementAt("Inserted Item", 0);
+        if (list.getSelectedIndex() != 3) {
+            throw new RuntimeException("Inserted element improperly updates list selection");
+        }
+    }
+}
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnilocalreflock04/TestDescription.java b/test/jdk/javax/swing/JList/bug4487689.java
similarity index 62%
copy from test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnilocalreflock04/TestDescription.java
copy to test/jdk/javax/swing/JList/bug4487689.java
index 42d7299..a13367d 100644
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnilocalreflock04/TestDescription.java
+++ b/test/jdk/javax/swing/JList/bug4487689.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -21,20 +21,26 @@
  * questions.
  */
 
-
 /*
  * @test
- * @key stress randomness
- *
- * @summary converted from VM Testbase gc/lock/jniref/jnilocalreflock04.
- * VM Testbase keywords: [gc, stress, stressopt, nonconcurrent]
- *
- * @library /vmTestbase
- *          /test/lib
- * @run main/othervm/native
- *      -XX:-UseGCOverheadLimit
- *      gc.lock.LockerTest
- *      -gp1 class
- *      -lockers jniLocalRef
+ * @bug 4487689
+ * @summary JList.setSelectedValue() throws ArrayIndexOutOfBoundsException on empty list.
+ * @run main bug4487689
  */
 
+import java.util.Vector;
+import javax.swing.JList;
+
+public class bug4487689 {
+
+    public static void main(String[] args) throws Exception {
+        JList<String> list = new JList<>(new Vector<String>());
+
+        list.setSelectedIndex(0);
+        list.getSelectedValue();
+
+        int[] indices = {0,1};
+        list.setSelectedIndices(indices);
+        list.getSelectedValues();
+    }
+}
diff --git a/test/jdk/javax/swing/JList/bug4832765.java b/test/jdk/javax/swing/JList/bug4832765.java
new file mode 100644
index 0000000..4030193
--- /dev/null
+++ b/test/jdk/javax/swing/JList/bug4832765.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4832765
+ * @summary JList vertical scrolling doesn't work properly.
+ * @run main bug4832765
+ */
+
+import java.awt.Dimension;
+import java.awt.Rectangle;
+import javax.swing.JFrame;
+import javax.swing.JList;
+import javax.swing.JScrollPane;
+import javax.swing.SwingConstants;
+import javax.swing.SwingUtilities;
+
+public class bug4832765 {
+
+    public static void main(String[] argv) throws Exception {
+        SwingUtilities.invokeAndWait(() -> {
+            String[] data = {"One", "Two", "Three", "Four",
+                    "Five", "Six ", "Seven", "Eight",
+                    "Nine", "Ten", "Eleven", "Twelv"};
+            JList<String> list = new JList<>(data);
+            list.setLayoutOrientation(JList.HORIZONTAL_WRAP);
+
+            JScrollPane jsp = new JScrollPane(list);
+            Rectangle rect = list.getCellBounds(5, 5);
+            Dimension d = new Dimension(200, rect.height);
+            jsp.setPreferredSize(d);
+            jsp.setMinimumSize(d);
+
+            list.scrollRectToVisible(rect);
+
+            int unit = list.getScrollableUnitIncrement(rect,
+                    SwingConstants.VERTICAL,
+                    -1);
+            if (unit <= 0) {
+                throw new RuntimeException("JList scrollable unit increment" +
+                        " should be greate than 0.");
+            }
+        });
+    }
+}
diff --git a/test/jdk/javax/swing/JMenuBar/bug4191374.java b/test/jdk/javax/swing/JMenuBar/bug4191374.java
new file mode 100644
index 0000000..eecbfde
--- /dev/null
+++ b/test/jdk/javax/swing/JMenuBar/bug4191374.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4191374
+ * @summary Verify if JMenuBar.getSubElements returns an array
+            with null values
+ * @run main bug4191374
+ */
+
+import javax.swing.Box;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.MenuElement;
+import javax.swing.SwingUtilities;
+
+public class bug4191374 {
+    static JMenuBar mb;
+    static volatile boolean pass = true;
+
+    public static void main(String[] args) throws Exception {
+        SwingUtilities.invokeAndWait(() -> {
+            mb = new JMenuBar();
+            newMenu(mb);
+            newMenu(mb);
+            mb.add(Box.createGlue());
+            mb.add(new JMenu("Help"));
+            MenuElement[] me = mb.getSubElements();
+            for (int i = 0; i < me.length; i++) {
+                if (me[i] == null)
+                    pass = false;
+            }
+        });
+        if (!pass) {
+            throw new RuntimeException("Bug 4191374 FAILED");
+        }
+    }
+
+    public static void newMenu(JMenuBar mb) {
+        JMenu m = (JMenu) mb.add(new JMenu("File"));
+        m.add("Menu item");
+        m.add("Menu item");
+        m.add("Menu item");
+    }
+}
diff --git a/test/jdk/javax/swing/JMenuBar/bug4802656.java b/test/jdk/javax/swing/JMenuBar/bug4802656.java
new file mode 100644
index 0000000..01f0d84
--- /dev/null
+++ b/test/jdk/javax/swing/JMenuBar/bug4802656.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4802656
+ * @summary Problem with keyboard navigation in JMenus JMenuItems if setVisible(false)
+ * @key headful
+ * @run main bug4802656
+ */
+
+import java.awt.Robot;
+import java.awt.event.KeyEvent;
+import javax.swing.JFrame;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.SwingUtilities;
+
+public class bug4802656 {
+
+    public static JFrame mainFrame;
+    public static JMenu menu2;
+    public static volatile boolean menu2Selected = true;
+
+    public static void main(String[] args) throws Exception {
+        Robot robo = new Robot();
+        robo.setAutoDelay(100);
+        try {
+            SwingUtilities.invokeAndWait(() -> {
+                mainFrame = new JFrame("Bug4802656");
+                JMenuBar menuBar = new JMenuBar();
+                JMenu menu1 = new JMenu("File");
+                menu2 = new JMenu("Hidden");
+                JMenu menu3 = new JMenu("Help");
+                menuBar.add(menu1);
+                menuBar.add(menu2);
+                menuBar.add(menu3);
+                menu2.setVisible(false);
+                mainFrame.setJMenuBar(menuBar);
+                mainFrame.setSize(200, 200);
+                mainFrame.setLocationRelativeTo(null);
+                mainFrame.setVisible(true);
+            });
+            robo.waitForIdle();
+            robo.delay(1000);
+            robo.keyPress(KeyEvent.VK_F10);
+            robo.keyRelease(KeyEvent.VK_F10);
+            robo.keyPress(KeyEvent.VK_RIGHT);
+            robo.keyRelease(KeyEvent.VK_RIGHT);
+            robo.delay(500);
+
+            SwingUtilities.invokeAndWait(() -> {
+                menu2Selected = menu2.isSelected();
+            });
+
+            if (menu2Selected) {
+                throw new RuntimeException("Test failed");
+            }
+        } finally {
+            SwingUtilities.invokeAndWait(() -> {
+                if (mainFrame != null) {
+                    mainFrame.dispose();
+                }
+            });
+        }
+    }
+}
diff --git a/test/jdk/javax/swing/JMenuItem/4654927/bug4654927.java b/test/jdk/javax/swing/JMenuItem/4654927/bug4654927.java
index b1a757e..46628cf 100644
--- a/test/jdk/javax/swing/JMenuItem/4654927/bug4654927.java
+++ b/test/jdk/javax/swing/JMenuItem/4654927/bug4654927.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,15 +26,20 @@
  * @key headful
  * @bug 4654927
  * @summary Clicking on Greyed Menuitems closes the Menubar Dropdown
- * @author Alexander Potochkin
  * @library ../../regtesthelpers
  * @build Util
  * @run main bug4654927
  */
 
-import javax.swing.*;
+import javax.swing.JFrame;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
 
-import java.awt.*;
+import java.awt.Point;
+import java.awt.Robot;
 import java.awt.event.InputEvent;
 import java.util.concurrent.Callable;
 
@@ -48,78 +53,65 @@
         try {
             String systemLAF = UIManager.getSystemLookAndFeelClassName();
             // the test is not applicable to Motif L&F
-            if(systemLAF.endsWith("MotifLookAndFeel")){
+            if (systemLAF.endsWith("MotifLookAndFeel")) {
                 return;
             }
 
             UIManager.setLookAndFeel(systemLAF);
             Robot robot = new Robot();
-            robot.setAutoDelay(10);
+            robot.setAutoWaitForIdle(true);
+            robot.setAutoDelay(100);
 
-            SwingUtilities.invokeAndWait(new Runnable() {
+            SwingUtilities.invokeAndWait(() -> createAndShowUI());
 
-                public void run() {
-                    createAndShowUI();
-                }
-            });
             robot.waitForIdle();
+            robot.delay(1000);
 
             // test mouse press
-            Point point = Util.getCenterPoint(menu);
-            robot.mouseMove(point.x, point.y);
-            robot.mousePress(InputEvent.BUTTON1_MASK);
-            robot.mouseRelease(InputEvent.BUTTON1_MASK);
+            Point menuLocation = Util.getCenterPoint(menu);
+            System.out.println("Menu Location " + menuLocation);
+            robot.mouseMove(menuLocation.x, menuLocation.y);
+            robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
+            robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
             robot.waitForIdle();
+            robot.delay(250);
 
-            point = Util.getCenterPoint(menuItem);
-            robot.mouseMove(point.x, point.y);
-            robot.mousePress(InputEvent.BUTTON1_MASK);
-            robot.mouseRelease(InputEvent.BUTTON1_MASK);
+            Point itemLocation = Util.getCenterPoint(menuItem);
+            System.out.println("MenuItem Location " + itemLocation);
+            robot.mouseMove(itemLocation.x, itemLocation.y);
+            robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
+            robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
             robot.waitForIdle();
+            robot.delay(250);
 
             if (!isMenuItemShowing()) {
                 throw new RuntimeException("Popup is unexpectedly closed");
             }
 
-            // test mouse drag
-            point = Util.getCenterPoint(menu);
-            robot.mouseMove(point.x, point.y);
-            Point menuLocation = Util.invokeOnEDT(new Callable<Point>() {
-
-                @Override
-                public Point call() throws Exception {
-                    return menu.getLocationOnScreen();
-                }
-            });
-
-            Point itemLocation = Util.invokeOnEDT(new Callable<Point>() {
-
-                @Override
-                public Point call() throws Exception {
-                    return menuItem.getLocationOnScreen();
-                }
-            });
-
-            int x0 = menuLocation.x + 10;
-            int y0 = menuLocation.y + 10;
-            int x1 = itemLocation.x + 10;
-            int y1 = itemLocation.y + 10;
-
             // close menu
-            robot.mousePress(InputEvent.BUTTON1_MASK);
-            robot.mouseRelease(InputEvent.BUTTON1_MASK);
+            robot.mouseMove(menuLocation.x, menuLocation.y);
+            robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
+            robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
             robot.waitForIdle();
+            robot.delay(250);
 
-            robot.mousePress(InputEvent.BUTTON1_MASK);
-            Util.glide(robot, x0, y0, x1, y1);
-            robot.mouseRelease(InputEvent.BUTTON1_MASK);
+            // test mouse drag
+            robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
+            robot.delay(250);
+            Util.glide(robot, menuLocation.x, menuLocation.y,
+                              itemLocation.x, itemLocation.y);
+            robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
             robot.waitForIdle();
 
             if (!isMenuItemShowing()) {
                 throw new RuntimeException("Popup is unexpectedly closed");
             }
         } finally {
-            if (frame != null) SwingUtilities.invokeAndWait(() -> frame.dispose());
+            SwingUtilities.invokeAndWait(() -> {
+                if (frame != null) {
+                    frame.dispose();
+                }
+            });
         }
     }
 
@@ -151,6 +143,6 @@
         frame.setSize(200, 200);
         frame.setLocationRelativeTo(null);
         frame.setVisible(true);
-
     }
 }
+
diff --git a/test/jdk/javax/swing/JTableHeader/6889007/bug6889007.java b/test/jdk/javax/swing/JTableHeader/6889007/bug6889007.java
index 7b12002..d552664 100644
--- a/test/jdk/javax/swing/JTableHeader/6889007/bug6889007.java
+++ b/test/jdk/javax/swing/JTableHeader/6889007/bug6889007.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,6 +30,7 @@
 
 import java.awt.Cursor;
 import java.awt.Dimension;
+import java.awt.MouseInfo;
 import java.awt.Point;
 import java.awt.Rectangle;
 import java.awt.Robot;
@@ -47,12 +48,15 @@
     static JFrame frame;
     static Robot robot;
     static volatile Point point;
+    static volatile Point mouseLoc;
     static volatile int width;
     static volatile int height;
+    static volatile boolean ignoreFirst = false;
 
     public static void main(String[] args) throws Exception {
         try {
             robot = new Robot();
+            robot.mouseMove(100, 100);
 
             SwingUtilities.invokeAndWait(() -> {
                 frame = new JFrame();
@@ -74,14 +78,21 @@
             robot.waitForIdle();
             robot.delay(1000);
             SwingUtilities.invokeAndWait(() -> {
+                mouseLoc = MouseInfo.getPointerInfo().getLocation();
                 point = frame.getLocationOnScreen();
                 width = frame.getWidth();
                 height = frame.getHeight();
             });
+            if ((mouseLoc.x >= point.x) && (mouseLoc.x < point.x + width) &&
+                (mouseLoc.y >= point.y) && (mouseLoc.y < point.y + height)) {
+                 System.out.println("pointer is within window");
+                 ignoreFirst = true;
+                 MyTableHeaderUI.testValue = 0;
+            }
             int shift = 10;
             int x = point.x;
             int y = point.y + height/2;
-            for(int i = -shift; i < width + 2*shift; i++) {
+            for (int i = -shift; i < width + 2*shift; i++) {
                 robot.mouseMove(x++, y);
                 robot.delay(100);
             }
@@ -102,15 +113,21 @@
     }
 
     static class MyTableHeaderUI extends BasicTableHeaderUI {
-        private static int testValue;
+        private static volatile int testValue;
 
         protected void rolloverColumnUpdated(int oldColumn, int newColumn) {
             increaseTestValue(newColumn);
             Cursor cursor = Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR);
+            System.out.println("oldColumn " + oldColumn + " newColumn " + newColumn +
+                        " header.getCursor " + header.getCursor() + " cursor " + cursor);
+            if (ignoreFirst) {
+                ignoreFirst = false;
+                if (newColumn == 0) {
+                    return;
+                }
+            }
             if (oldColumn != -1 && newColumn != -1 &&
                     header.getCursor() != cursor) {
-                System.out.println("oldColumn " + oldColumn + " newColumn " + newColumn +
-                        "header.getCursor " + header.getCursor() + " cursor " + cursor);
                 try {
                     Dimension screenSize =
                                Toolkit.getDefaultToolkit().getScreenSize();
diff --git a/test/jdk/javax/swing/plaf/aqua/CustomComboBoxFocusTest.java b/test/jdk/javax/swing/plaf/aqua/CustomComboBoxFocusTest.java
index 57d2cdd..21ea5f9 100644
--- a/test/jdk/javax/swing/plaf/aqua/CustomComboBoxFocusTest.java
+++ b/test/jdk/javax/swing/plaf/aqua/CustomComboBoxFocusTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,14 +25,14 @@
  * @test
  * @key headful
  * @bug     8073001 8081764
+ * @requires (os.family == "mac")
  * @summary Test verifies that combo box with custom editor renders
  *          focus ring around arrow button correctly.
- * @library /test/lib
- * @build jdk.test.lib.Platform
- * @run     main CustomComboBoxFocusTest
+ * @run     main/othervm -Dsun.java2d.uiScale=1 CustomComboBoxFocusTest
  */
 
 import java.awt.AWTException;
+import java.awt.Color;
 import java.awt.Component;
 import java.awt.GridLayout;
 import java.awt.Point;
@@ -44,8 +44,8 @@
 import java.awt.image.BufferedImage;
 import java.io.File;
 import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
 import java.util.concurrent.CountDownLatch;
+
 import javax.imageio.ImageIO;
 import javax.swing.ComboBoxEditor;
 import javax.swing.JComboBox;
@@ -55,29 +55,24 @@
 import javax.swing.JTextField;
 import javax.swing.SwingUtilities;
 
-import jdk.test.lib.Platform;
-
 public class CustomComboBoxFocusTest {
 
     private static CustomComboBoxFocusTest test = null;
+    static int colorTolerance = 5;
 
-    public static void main(String[] args) {
-        if (!Platform.isOSX()) {
+    public static void main(String[] args) throws Exception {
+        if (!System.getProperty("os.name").toLowerCase().contains("os x")) {
             System.out.println("Only Mac platform test. Test is skipped for other OS.");
             return;
         }
 
-        try {
-            SwingUtilities.invokeAndWait(new Runnable() {
-                public void run() {
-                    test = new CustomComboBoxFocusTest();
-                }
-            });
-        } catch (InterruptedException | InvocationTargetException e ) {
-            throw new RuntimeException("Test failed.", e);
-        }
+        SwingUtilities.invokeAndWait(new Runnable() {
+            public void run() {
+                test = new CustomComboBoxFocusTest();
+            }
+        });
 
-        SwingUtilities.invokeLater(test.init);
+        SwingUtilities.invokeAndWait(test.init);
 
         try {
             System.out.println("Wait for screenshots...");
@@ -130,7 +125,23 @@
 
         for (int y = 0; y < h; y++) {
             for (int x = 0; x < w; x++) {
-                if (a.getRGB(x, y) != b.getRGB(x, y)) {
+                Color refRGB = new Color(a.getRGB(x,y));
+                Color customRGB = new Color(b.getRGB(x,y));
+
+                int red1 = refRGB.getRed();
+                int blue1 = refRGB.getBlue();
+                int green1 = refRGB.getGreen();
+
+                int red2 = customRGB.getRed();
+                int blue2 = customRGB.getBlue();
+                int green2 = customRGB.getGreen();
+
+                if ((Math.abs(red1 - red2) > colorTolerance) ||
+                    (Math.abs(green1 - green2) > colorTolerance) ||
+                    (Math.abs(blue1 - blue2) > colorTolerance)) {
+                    System.out.println("x " + x + " y " + y +
+                                       " refRGB " + refRGB +
+                                       " customRGB " + customRGB);
                     return false;
                 }
             }
@@ -222,6 +233,7 @@
             f.add(p);
 
             f.pack();
+            f.setLocationRelativeTo(null);
             f.setVisible(true);
         }
 
diff --git a/test/jdk/javax/swing/plaf/aqua/TestAltUpDownComboBox.java b/test/jdk/javax/swing/plaf/aqua/TestAltUpDownComboBox.java
new file mode 100644
index 0000000..9093757
--- /dev/null
+++ b/test/jdk/javax/swing/plaf/aqua/TestAltUpDownComboBox.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/* @test
+ * @bug 7148092
+ * @requires (os.family == "mac")
+ * @summary Tests that alt+down arrow pulls down JComboBox popup
+ * @key headful
+ * @run main TestAltUpDownComboBox
+*/
+
+import java.awt.Container;
+import java.awt.Robot;
+import java.awt.event.KeyEvent;
+import javax.swing.BoxLayout;
+import javax.swing.JFrame;
+import javax.swing.JComboBox;
+import javax.swing.SwingUtilities;
+
+public class TestAltUpDownComboBox {
+
+    private static JFrame frame;
+    private static JComboBox combo;
+
+    public static void main(String[] argv) throws Exception {
+        Robot robot = new Robot();
+        robot.setAutoDelay(100);
+        try {
+            SwingUtilities.invokeAndWait(() -> {
+                frame = new JFrame("");
+                Object[] fruits = {"Banana", "Pear", "Apple"};
+                combo = new JComboBox(fruits);
+                Container pane = frame.getContentPane();
+                pane.setLayout(new BoxLayout(pane, BoxLayout.X_AXIS));
+                pane.add(combo);
+
+                frame.pack();
+                frame.setLocationRelativeTo(null);
+                frame.setVisible(true);
+            });
+            robot.waitForIdle();
+            robot.delay(1000);
+            robot.keyPress(KeyEvent.VK_ALT);
+            robot.keyPress(KeyEvent.VK_DOWN);
+            robot.keyRelease(KeyEvent.VK_DOWN);
+            robot.keyRelease(KeyEvent.VK_ALT);
+            robot.delay(1000);
+
+            if (!combo.isPopupVisible()) {
+                throw new RuntimeException("comboBox is not visible");
+            }
+
+            robot.keyPress(KeyEvent.VK_ALT);
+            robot.keyPress(KeyEvent.VK_DOWN);
+            robot.keyRelease(KeyEvent.VK_DOWN);
+            robot.keyRelease(KeyEvent.VK_ALT);
+            robot.delay(1000);
+
+            if (combo.getSelectedIndex() != combo.getItemCount() - 1) {
+                System.out.println(combo.getSelectedIndex());
+                throw new RuntimeException("Alt+Down did not select last entry");
+            }
+
+            robot.keyPress(KeyEvent.VK_ALT);
+            robot.keyPress(KeyEvent.VK_UP);
+            robot.keyRelease(KeyEvent.VK_UP);
+            robot.keyRelease(KeyEvent.VK_ALT);
+            robot.delay(1000);
+
+            if (combo.getSelectedIndex() != 0) {
+                System.out.println(combo.getSelectedIndex());
+                throw new RuntimeException("Alt+Up did not select first entry");
+            }
+        } finally {
+            SwingUtilities.invokeAndWait(() -> {
+                if (frame != null) {
+                    frame.dispose();
+                }
+            });
+        }
+    }
+}
diff --git a/test/jdk/javax/swing/text/CompositeView/bug4398059.java b/test/jdk/javax/swing/text/CompositeView/bug4398059.java
new file mode 100644
index 0000000..3ce5675
--- /dev/null
+++ b/test/jdk/javax/swing/text/CompositeView/bug4398059.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.Robot;
+import java.awt.Shape;
+import javax.swing.JEditorPane;
+import javax.swing.JFrame;
+import javax.swing.SwingUtilities;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Document;
+import javax.swing.text.Element;
+import javax.swing.text.Position;
+import javax.swing.text.StyleConstants;
+import javax.swing.text.View;
+import javax.swing.text.ViewFactory;
+import javax.swing.text.html.HTML;
+import javax.swing.text.html.HTMLEditorKit;
+import javax.swing.text.html.ParagraphView;
+
+/*
+ * @test
+ * @bug 4398059
+ * @key headful
+ * @summary Tests that CompositeView doesn't throw NPE.
+ */
+
+public class bug4398059 {
+    private static JFrame jFrame;
+
+    public static void main(String[] args) throws Exception {
+        try {
+            Robot robot = new Robot();
+            SwingUtilities.invokeAndWait(bug4398059::createAndShowUI);
+            robot.waitForIdle();
+            robot.delay(1000);
+        } finally {
+            SwingUtilities.invokeAndWait(() -> {
+                if (jFrame != null) {
+                    jFrame.dispose();
+                }
+            });
+        }
+    }
+
+    public static void createAndShowUI() {
+        String text = "<H1>text";
+        jFrame = new JFrame("CompositeView Test");
+        JEditorPane jep = new JEditorPane();
+        jep.setEditorKit(new MyHTMLEditorKit());
+        jep.setText(text);
+
+        Document doc = jep.getDocument();
+        jep.setCaretPosition(doc.getLength() - 1);
+
+        jFrame.getContentPane().add(jep);
+        jFrame.setSize(200,200);
+        jFrame.setVisible(true);
+    }
+
+    static class MyHTMLEditorKit extends HTMLEditorKit {
+        private static final ViewFactory defaultFactory = new MyHTMLFactory();
+
+        public ViewFactory getViewFactory() {
+            return defaultFactory;
+        }
+
+        static class MyHTMLFactory extends HTMLEditorKit.HTMLFactory {
+            public View create(Element elem) {
+                Object obj = elem.getAttributes().getAttribute(StyleConstants.NameAttribute);
+                if (obj instanceof HTML.Tag kind) {
+                    if (kind == HTML.Tag.H1) {
+                        return new MyParagraphView(elem);
+                    }
+                }
+                return super.create(elem);
+            }
+        }
+
+        static class MyParagraphView extends ParagraphView {
+            public MyParagraphView(Element elem) {
+                super(elem);
+            }
+
+            public Shape getChildAllocation(int index, Shape a) {
+                return null;
+            }
+
+            public Shape modelToView(int pos, Shape a, Position.Bias b)
+                                      throws BadLocationException {
+                return super.modelToView(pos, a, b);
+            }
+        }
+    }
+}
diff --git a/test/jdk/javax/swing/text/DefaultCaret/bug4197894.java b/test/jdk/javax/swing/text/DefaultCaret/bug4197894.java
new file mode 100644
index 0000000..11bb163
--- /dev/null
+++ b/test/jdk/javax/swing/text/DefaultCaret/bug4197894.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Robot;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+import javax.swing.JFrame;
+import javax.swing.JTextArea;
+import javax.swing.SwingUtilities;
+
+/*
+ * @test
+ * @bug 4197894
+ * @key headful
+ * @summary Tests if shift-click adjusts selection in text areas.
+ */
+
+public class bug4197894 {
+    private static JFrame jFrame;
+    private static JTextArea ta;
+
+    private static volatile Point point = null;
+    private static volatile Rectangle bounds;
+
+    private static volatile boolean passed = true;
+
+    public static void main(String[] args) throws Exception {
+        try {
+            Robot robot = new Robot();
+            robot.setAutoDelay(50);
+            robot.setAutoWaitForIdle(true);
+
+            SwingUtilities.invokeAndWait(bug4197894::createAndShowUI);
+            robot.waitForIdle();
+            robot.delay(1000);
+
+            SwingUtilities.invokeAndWait(() -> {
+                point = ta.getLocationOnScreen();
+                bounds = ta.getBounds();
+            });
+            robot.waitForIdle();
+            robot.delay(300);
+
+            robot.mouseMove((point.x + bounds.width / 4),
+                    (point.y + bounds.height / 4));
+
+            robot.keyPress(KeyEvent.VK_SHIFT);
+            robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
+            robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
+            robot.keyRelease(KeyEvent.VK_SHIFT);
+            robot.delay(300);
+
+            if (!passed) {
+                throw new RuntimeException("Test failed." +
+                        " Shift-Click Text Selection does not work!");
+            }
+        } finally {
+            SwingUtilities.invokeAndWait(() -> {
+                if (jFrame != null) {
+                    jFrame.dispose();
+                }
+            });
+        }
+    }
+
+    private static void createAndShowUI() {
+        jFrame = new JFrame("Shift-Click Text Selection");
+        ta = new JTextArea();
+        ta.addKeyListener(new KeyAdapter() {
+            public void keyReleased(KeyEvent e) {
+                String selText = ta.getSelectedText();
+                passed = !(selText == null || (selText.length() == 0));
+            }
+        });
+        ta.setText("12345\n12345\n12345\n12345\n12345\n12345\n12345");
+        ta.setCaretPosition(ta.getDocument().getLength());
+        jFrame.getContentPane().add(ta);
+        jFrame.pack();
+        jFrame.setLocationRelativeTo(null);
+        jFrame.setAlwaysOnTop(true);
+        jFrame.setVisible(true);
+    }
+}
diff --git a/test/jdk/javax/swing/text/DefaultCaret/bug4203175.java b/test/jdk/javax/swing/text/DefaultCaret/bug4203175.java
new file mode 100644
index 0000000..8a15644
--- /dev/null
+++ b/test/jdk/javax/swing/text/DefaultCaret/bug4203175.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.Container;
+import java.awt.Point;
+import java.awt.Robot;
+import java.awt.event.InputEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JTextField;
+import javax.swing.SwingUtilities;
+
+/*
+ * @test
+ * @bug 4203175
+ * @key headful
+ * @summary Tests that double-click on disabled JTextField doesn't
+ *          cause other text-field to select content.
+ */
+
+public class bug4203175 {
+    private static JFrame jFrame;
+    private static JTextField tf1, tf2;
+    private static JButton b;
+    private static volatile Point point;
+    private static volatile boolean passed = true;
+    private static int clicks = 0;
+
+    public static void main(String[] args) throws Exception {
+        try {
+            Robot robot = new Robot();
+            robot.setAutoDelay(50);
+            robot.setAutoWaitForIdle(true);
+
+            SwingUtilities.invokeAndWait(bug4203175::createAndShowUI);
+            robot.delay(1000);
+
+            SwingUtilities.invokeAndWait(() -> point = tf1.getLocationOnScreen());
+            robot.mouseMove(point.x, point.y);
+            robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
+            robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
+            robot.delay(200);
+
+            SwingUtilities.invokeAndWait(() -> point = b.getLocationOnScreen());
+            robot.mouseMove(point.x, point.y);
+            robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
+            robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
+            robot.delay(200);
+
+            SwingUtilities.invokeAndWait(() -> point = tf2.getLocationOnScreen());
+            robot.mouseMove(point.x, point.y);
+            robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
+            robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
+            robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
+            robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
+            robot.delay(200);
+
+            if (!passed) {
+                throw new RuntimeException("Test failed!! Text selection on disabled" +
+                                           " TextField does not work as expected!");
+            }
+        } finally {
+            SwingUtilities.invokeAndWait(() -> {
+                if (jFrame != null) {
+                    jFrame.dispose();
+                }
+            });
+        }
+    }
+
+    private static void createAndShowUI() {
+        jFrame = new JFrame("JTextField Text Selection");
+        Container cont = jFrame.getContentPane();
+        cont.setLayout(new BoxLayout(cont, BoxLayout.Y_AXIS));
+
+        tf1 = new JTextField(20);
+        tf1.setText("sometext");
+        tf1.setName("Field 1");
+        tf1.setCaretPosition(tf1.getDocument().getLength());
+        cont.add(tf1);
+
+        tf2 = new JTextField(20);
+        tf2.setName("Field 2");
+        tf2.addMouseListener(new MouseAdapter() {
+            @Override
+            public void mouseClicked(MouseEvent e) {
+                super.mouseClicked(e);
+                clicks++;
+                if (clicks == 2) {
+                    String selText = tf1.getSelectedText();
+                    passed = (selText == null || (selText.length() == 0));
+                }
+            }
+        });
+        cont.add(tf2);
+
+        b = new JButton("Toggle Enabled");
+        cont.add(b);
+        b.addActionListener(e -> {
+            if (e.getSource() == b) {
+                boolean b = tf1.isEnabled();
+                tf1.setEnabled(!b);
+                tf2.setEnabled(!b);
+            }
+        });
+
+        jFrame.pack();
+        jFrame.setLocationRelativeTo(null);
+        jFrame.setVisible(true);
+    }
+}
diff --git a/test/jdk/javax/swing/text/DefaultEditorKit/bug4265242.java b/test/jdk/javax/swing/text/DefaultEditorKit/bug4265242.java
new file mode 100644
index 0000000..d797b58
--- /dev/null
+++ b/test/jdk/javax/swing/text/DefaultEditorKit/bug4265242.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.event.ActionEvent;
+import javax.swing.Action;
+import javax.swing.JTextPane;
+import javax.swing.text.DefaultEditorKit;
+
+/*
+ * @test
+ * @bug 4265242
+ * @summary Tests endParagraphAction in JTextPane
+ */
+
+public class bug4265242 {
+    public static void main(String[] args) {
+        JTextPane jTextPane = new JTextPane();
+        jTextPane.setText("Merry sparrow");
+
+        Action[] actions = jTextPane.getActions();
+        Action endPara = null;
+        for (Action action : actions) {
+            String name = (String) action.getValue(Action.NAME);
+            if (name.equals(DefaultEditorKit.endParagraphAction)) {
+                endPara = action;
+            }
+        }
+        endPara.actionPerformed(new ActionEvent(jTextPane,
+                ActionEvent.ACTION_PERFORMED,
+                DefaultEditorKit.endParagraphAction));
+    }
+}
diff --git a/test/jdk/javax/swing/text/DefaultStyledDocument/bug4472852.java b/test/jdk/javax/swing/text/DefaultStyledDocument/bug4472852.java
new file mode 100644
index 0000000..cb9b4e6
--- /dev/null
+++ b/test/jdk/javax/swing/text/DefaultStyledDocument/bug4472852.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.Color;
+import javax.swing.text.DefaultStyledDocument;
+import javax.swing.text.Element;
+import javax.swing.text.MutableAttributeSet;
+import javax.swing.text.SimpleAttributeSet;
+import javax.swing.text.StyleConstants;
+import javax.swing.text.StyledDocument;
+
+/*
+ * @test
+ * @bug 4472852
+ * @summary Tests DefaultStyledDocument.split(int, int)
+ */
+
+public class bug4472852 {
+
+    public static void main(String[] args) throws Exception {
+        // create a Document and insert some text there
+        StyledDocument doc = new DefaultStyledDocument();
+        doc.insertString(0, "this", null);
+
+        // add style to the last word
+        Element root = doc.getDefaultRootElement();
+        int end = root.getEndOffset();
+        MutableAttributeSet as = new SimpleAttributeSet();
+        StyleConstants.setBackground(as, Color.BLUE);
+        doc.setCharacterAttributes(end-5, 5, as, true);
+
+        // inspect Elements of the only Paragraph --
+        // there should be no empty Elements
+        Element para = root.getElement(0);
+        for (int i = 0; i < para.getElementCount(); i++) {
+            Element el = para.getElement(i);
+            if (el.getStartOffset() == el.getEndOffset()) {
+                throw new RuntimeException("Failed: empty Element found");
+            }
+        }
+    }
+}
diff --git a/test/jdk/javax/swing/text/html/HTMLEditorKit/bug4267840.java b/test/jdk/javax/swing/text/html/HTMLEditorKit/bug4267840.java
new file mode 100644
index 0000000..30d3645
--- /dev/null
+++ b/test/jdk/javax/swing/text/html/HTMLEditorKit/bug4267840.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+   @bug 4267840
+   @summary Tests how HTMLEditorKit.write() works on small documents
+   @run main bug4267840
+*/
+
+import javax.swing.JTextPane;
+import javax.swing.text.EditorKit;
+import javax.swing.SwingUtilities;
+import java.io.File;
+import java.io.FileOutputStream;
+
+public class bug4267840 {
+    public static void main(String[] args) throws Exception {
+        SwingUtilities.invokeAndWait(() -> {
+            final JTextPane textpane = new JTextPane();
+            textpane.setContentType("text/html");
+            final EditorKit kit = textpane.getEditorKit();
+
+            textpane.setText("A word");
+            File file = new File("bug4267840.out");
+            try {
+                FileOutputStream out = new FileOutputStream(file);
+                kit.write(out, textpane.getDocument(), 0,
+                          textpane.getDocument().getLength());
+                out.close();
+            } catch (Exception e) {}
+            try {
+                if (file.length() < 6) {  // simply can't be
+                    throw new RuntimeException("Failed: " +
+                                          " HTMLEditorKit.write() is broken");
+                }
+            } finally {
+                file.delete();
+            }
+        });
+    }
+}
diff --git a/test/jdk/javax/swing/text/html/StyleSheet/bug4218254.java b/test/jdk/javax/swing/text/html/StyleSheet/bug4218254.java
new file mode 100644
index 0000000..128fd07
--- /dev/null
+++ b/test/jdk/javax/swing/text/html/StyleSheet/bug4218254.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+   @bug 4218254
+   @summary Serialization Bug on StyleSheet.
+   @run main bug4218254
+*/
+
+import javax.swing.text.html.StyleSheet;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+
+public class bug4218254 {
+
+    public static void main(String[] args) throws Exception {
+        StyleSheet ssw = new StyleSheet();
+        StyleSheet ssr = null;
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ObjectOutputStream oos = new ObjectOutputStream(baos);
+        oos.writeObject(ssw);
+        byte[] buf = baos.toByteArray();
+        oos.close();
+        ByteArrayInputStream bais = new ByteArrayInputStream(buf);
+        ObjectInputStream ois = new ObjectInputStream(bais);
+        ssr = (StyleSheet)ois.readObject();
+        ois.close();
+    }
+}
diff --git a/test/jdk/javax/swing/text/html/StyleSheet/bug4243463.java b/test/jdk/javax/swing/text/html/StyleSheet/bug4243463.java
new file mode 100644
index 0000000..a84c4b4
--- /dev/null
+++ b/test/jdk/javax/swing/text/html/StyleSheet/bug4243463.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+   @bug 4243463
+   @summary Tests that StyleSheet has following methods:
+            public void addStyleSheet(StyleSheet ss);
+            public void removeStyleSheet(StyleSheet ss);
+            public Enumeration getStyleSheets()
+   @run main bug4243463
+*/
+
+import javax.swing.text.html.StyleSheet;
+
+public class bug4243463 {
+
+    public static void main(String[] argv) throws Exception {
+        StyleSheet main = new StyleSheet();
+        StyleSheet ss = new StyleSheet();
+        ss.addRule("p {color:red;}");
+
+        main.addStyleSheet(ss);
+        StyleSheet[] sheets = main.getStyleSheets();
+        if (sheets.length != 1 || sheets[0] != ss) {
+            throw new RuntimeException("getStyleSheets failed");
+        }
+
+        main.removeStyleSheet(ss);
+        sheets = main.getStyleSheets();
+        if (sheets != null) {
+            throw new RuntimeException("StyleSheet is not removed");
+        }
+    }
+}
diff --git a/test/jdk/javax/swing/text/html/TableView/bug4813831.java b/test/jdk/javax/swing/text/html/TableView/bug4813831.java
new file mode 100644
index 0000000..4d7f286
--- /dev/null
+++ b/test/jdk/javax/swing/text/html/TableView/bug4813831.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4813831
+ * @summary Verifies contents of table cells in HTML in JEditorPane wraps correctly
+ * @key headful
+ * @run main bug4813831
+*/
+
+import javax.swing.JEditorPane;
+import javax.swing.JFrame;
+import javax.swing.SwingUtilities;
+import javax.swing.text.View;
+import javax.swing.text.ParagraphView;
+import javax.swing.text.html.HTMLEditorKit;
+
+import java.awt.Robot;
+import java.awt.Shape;
+
+public class bug4813831 {
+
+    private static boolean passed = false;
+    private boolean finished = false;
+
+    private static JEditorPane jep;
+    private static JFrame f;
+
+    public void init() {
+
+        String text =
+            "<html><body>" +
+            "<table border><tr>" +
+            "<td align=center>XXXXXXXXXXXXXX<BR>X<BR>X</td>" +
+            "</tr></table>" +
+            "</body></html>";
+
+        f = new JFrame();
+        jep = new JEditorPane();
+        jep.setEditorKit(new HTMLEditorKit());
+        jep.setEditable(false);
+
+        jep.setText(text);
+
+        f.getContentPane().add(jep);
+        f.setSize(20,500);
+        f.setLocationRelativeTo(null);
+        f.setVisible(true);
+    }
+
+
+    public static void main(String args[]) throws Exception {
+        Robot robot = new Robot();
+        robot.setAutoDelay(100);
+        bug4813831 test = new bug4813831();
+        try {
+            SwingUtilities.invokeAndWait(() -> test.init());
+            robot.waitForIdle();
+            robot.delay(1000);
+            Shape r = jep.getBounds();
+            View v = jep.getUI().getRootView(jep);
+            do {
+                int n = v.getViewCount();
+                Shape sh = v.getChildAllocation(n - 1, r);
+                if (sh != null) {
+                    r = sh;
+                }
+                v = v.getView(n - 1);
+            } while (!(v instanceof ParagraphView));
+
+            int n = v.getViewCount();
+            // there should be 3 lines or more (if the first long line was wrapped) in a cell
+            passed = n >= 3;
+
+            if (passed) {
+                Shape sh = v.getChildAllocation(n - 2, r);
+                int x1 = sh.getBounds().x;
+                sh = v.getChildAllocation(n - 1, r);
+                int x2 = sh.getBounds().x;
+                System.out.println("x1: " + x1 + " x2: " + x2);
+                // lines should be equally aligned
+                passed = (x1 == x2);
+            }
+            if (!passed) {
+                throw new RuntimeException("Test failed.");
+            }
+        } finally {
+            SwingUtilities.invokeAndWait(() -> {
+                if (f != null) {
+                    f.dispose();
+                }
+            });
+        }
+    }
+}
diff --git a/test/jdk/javax/swing/text/rtf/RTFReadFontCharsetTest.java b/test/jdk/javax/swing/text/rtf/RTFReadFontCharsetTest.java
new file mode 100644
index 0000000..629b372
--- /dev/null
+++ b/test/jdk/javax/swing/text/rtf/RTFReadFontCharsetTest.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6928542
+ * @summary Verify RTFEditorKit.read() with fcharset
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStreamReader;
+import java.io.PrintStream;
+import javax.swing.text.Document;
+import javax.swing.text.Element;
+import javax.swing.text.rtf.RTFEditorKit;
+
+import static java.nio.charset.StandardCharsets.ISO_8859_1;
+
+public class RTFReadFontCharsetTest {
+    public static void main(String[] args) throws Exception {
+        String s =
+            "{\\rtf1\\fbidis\\ansi\\ansicpg932\\deff0\\nouicomp" +
+            "at\\deflang1033\\deflangfe1041{\\fonttbl{\\f0\\fni" +
+            "l\\fcharset0 Segoe UI;}{\\f1\\fnil\\fcharset128 Yu" +
+            " Gothic UI;}{\\f2\\fswiss\\fprq2\\fcharset129 Malg" +
+            "un Gothic;}{\\f3\\fnil\\fcharset134 Microsoft YaHe" +
+            "i;}{\\f4\\fnil\\fcharset136 Microsoft JhengHei;}{\\" +
+            "f5\\fnil\\fcharset161 Segoe UI;}{\\f6\\fnil\\fcha" +
+            "rset162 Segoe UI;}{\\f7\\fnil\\fcharset163 Segoe U" +
+            "I;}{\\f8\\fnil\\fcharset177 Segoe UI;}{\\f9\\fnil\\" +
+            "fcharset178 Segoe UI;}{\\f10\\fnil\\fcharset186 S" +
+            "egoe UI;}{\\f11\\fnil\\fcharset204 Segoe UI;}{\\f1" +
+            "2\\fnil\\fcharset222 Leelawadee UI;}{\\f13\\fnil\\" +
+            "fcharset0 Leelawadee UI;}{\\f14\\fnil\\fcharset238" +
+            " Segoe UI;}}\r\n{\\*\\generator Riched20 10.0.1904" +
+            "1}\\viewkind4\\uc1 \r\n\\pard\\ltrpar\\nowidctlpar" +
+            "\\sa200\\sl276\\slmult1\\f0\\fs22\\lang1041 Gr\\'f" +
+            "cezi -  Switzerland 0\\line\\f1\\'82\\'b1\\'82\\'f" +
+            "1\\'82\\'c9\\'82\\'bf\\'82\\'cd - Japanese 128\\li" +
+            "ne\\f2\\lang17\\'be\\'c8\\'b3\\'e7\\'c7\\'cf\\'bc\\" +
+            "'bc\\'bf\\'e4\\lang1041  - Korean 129\\line\\kern" +
+            "ing2\\f3\\lang1033\\'c4\\'e3\\'ba\\'c3 - China 134" +
+            "\\line\\f4\\'bb\\'4f\\'c6\\'57 - Traditional Chine" +
+            "se - Taiwan 136\\line\\kerning0\\f5\\lang17\\'e3\\" +
+            "'e5\\'e9\\'e1 \\'f3\\'ef\\'f5 - Greek\\f0\\lang104" +
+            "1  161\\line\\f6\\lang17 A\\'f0a\\'e7 - \\f0 Turki" +
+            "sh (Tree) 162\\line\\f7\\'fe\\f0\\lang1041  \\lang" +
+            "1033 - \\lang17 Vietnam currency\\lang1041  163\\l" +
+            "ine\\f8\\rtlch\\lang17\\'f9\\'c8\\'d1\\'ec\\'e5\\'" +
+            "c9\\'ed\\f0\\ltrch  - Hebrew 177\\line\\f9\\rtlch\\" +
+            "lang1025\\'e3\\'d1\\'cd\\'c8\\'c7\\f0\\ltrch\\lan" +
+            "g17  - Arabic 178\\line\\kerning2\\f10\\lang1033 A" +
+            "\\'e8i\\'fb - Lithuanian (Thank you) 186\\kerning0" +
+            "\\f0\\lang1041\\line\\kerning2\\f11\\lang1049\\'c7" +
+            "\\'e4\\'f0\\'e0\\'e2\\'f1\\'f2\\'e2\\'f3\\'e9\\'f2" +
+            "\\'e5\\f0\\lang1033  - Russian 204\\line\\kerning0" +
+            "\\f12\\lang1054\\'ca\\'c7\\'d1\\'ca\\'b4\\'d5 \\f1" +
+            "3\\lang1033 - Thailand 222\\line\\kerning2\\f14 cz" +
+            "e\\'9c\\'e6 - Polish 238\\par\r\n}\r\n\u0000";
+        String expected =
+            "Gr\u00fcezi -  Switzerland 0\n" +
+            "\u3053\u3093\u306b\u3061\u306f - Japanese 128\n" +
+            "\uc548\ub155\ud558\uc138\uc694 - Korean 129\n" +
+            "\u4f60\u597d - China 134\n" +
+            "\u81fa\u7063 - Traditional Chinese - Taiwan 136\n" +
+            "\u03b3\u03b5\u03b9\u03b1 \u03c3\u03bf\u03c5 - Greek 161\n" +
+            "A\u011fa\u00e7 - Turkish (Tree) 162\n" +
+            "\u20ab - Vietnam currency 163\n" +
+            "\u05e9\u05b8\u05c1\u05dc\u05d5\u05b9\u05dd - Hebrew 177\n" +
+            "\u0645\u0631\u062d\u0628\u0627 - Arabic 178\n" +
+            "A\u010di\u016b - Lithuanian (Thank you) 186\n" +
+            "\u0417\u0434\u0440\u0430\u0432\u0441\u0442" +
+            "\u0432\u0443\u0439\u0442\u0435 - Russian 204\n" +
+            "\u0e2a\u0e27\u0e31\u0e2a\u0e14\u0e35 - Thailand 222\n" +
+            "cze\u015b\u0107 - Polish 238\n" +
+            "\n";
+        ByteArrayInputStream bais = new ByteArrayInputStream(
+            s.getBytes(ISO_8859_1));
+        InputStreamReader isr = new InputStreamReader(bais, ISO_8859_1);
+        RTFEditorKit kit = new RTFEditorKit();
+        Document doc = kit.createDefaultDocument();
+        kit.read(isr, doc, 0);
+        Element elem = doc.getDefaultRootElement();
+        int elemStart = elem.getStartOffset();
+        int elemEnd = elem.getEndOffset();
+        String text = doc.getText(elemStart, elemEnd - elemStart);
+        if (!expected.equals(text)) {
+            System.err.println("Read data");
+            System.err.println("=========");
+            dump(text, System.err);
+            System.err.println("Expected data");
+            System.err.println("=============");
+            dump(expected, System.err);
+            throw new RuntimeException("Test failed");
+        }
+    }
+
+    private static void dump(String s, PrintStream ps) {
+        for(char ch : s.toCharArray()) {
+            if (ch == '\\')
+                ps.print("\\\\");
+            else if (ch >= 0x20 && ch <= 0x7e)
+                ps.print(ch);
+            else if (ch == '\n')
+                ps.println();
+            else
+                ps.printf("\\u%04x", (int)ch);
+        }
+    }
+
+}
diff --git a/test/jdk/javax/swing/text/rtf/bug4178276.java b/test/jdk/javax/swing/text/rtf/bug4178276.java
new file mode 100644
index 0000000..fc6ea8e
--- /dev/null
+++ b/test/jdk/javax/swing/text/rtf/bug4178276.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4178276
+ * @key headful
+ * @summary  RTFEditorkit.write(...) doesn't throw NPE when used in SecurityManager
+ * @run main/othervm/secure=allow bug4178276
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.nio.charset.StandardCharsets;
+import javax.swing.text.Document;
+import javax.swing.text.rtf.RTFEditorKit;
+
+public class bug4178276 {
+
+    public static void main(String[] argv) throws Exception {
+        System.setSecurityManager(new SecurityManager());
+
+        String test="{\\rtf1\\ansi\\deff0\\deftab720{\\fonttbl{\\f0\\f swiss MS Sans Serif;}}{\\colortbl\\red0\\green0\\blue0;}\\qc\\plain\\f0 Test 1 \\par \\ql\\plain\\f0 Test 2 \\par \\qr\\plain\\f0 Test 3 \\par \\qj\\plain\\f0 Test 4}";
+        RTFEditorKit c = new RTFEditorKit();
+        Document doc = c.createDefaultDocument();
+        try {
+            c.read(new ByteArrayInputStream(test.getBytes(
+                                        StandardCharsets.ISO_8859_1)), doc, 0);
+            ByteArrayOutputStream sw = new ByteArrayOutputStream();
+            c.write(sw, doc, 0, 0);
+        } catch (Exception e) {
+            throw new RuntimeException("Unexpected NPE exception...", e);
+        }
+    }
+}
diff --git a/test/jdk/javax/swing/tree/DefaultTreeCellEditor/bug4480602.java b/test/jdk/javax/swing/tree/DefaultTreeCellEditor/bug4480602.java
new file mode 100644
index 0000000..d907329
--- /dev/null
+++ b/test/jdk/javax/swing/tree/DefaultTreeCellEditor/bug4480602.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4480602
+ * @summary Verifies if DefaultTreeCellEditor.inHitRegion() incorrectly
+ *          handles row bounds
+ * @key headful
+ * @run main bug4480602
+*/
+
+import java.awt.ComponentOrientation;
+import java.awt.Rectangle;
+import java.awt.Robot;
+import java.awt.event.MouseEvent;
+import javax.swing.JFrame;
+import javax.swing.JScrollPane;
+import javax.swing.JTree;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeCellEditor;
+import javax.swing.tree.DefaultTreeCellRenderer;
+import javax.swing.SwingUtilities;
+
+import java.util.Date;
+
+public class bug4480602 {
+
+    static JTree tree;
+    static JFrame fr;
+    static MyTreeCellEditor editor;
+
+    static Robot robot;
+    boolean passed = false;
+    boolean do_test = false;
+
+    public static void main(String[] args) throws Exception {
+        Robot robot = new Robot();
+        robot.setAutoDelay(100);
+        try {
+            SwingUtilities.invokeAndWait(() -> {
+                fr = new JFrame("Test");
+
+                String s = "0\u05D01\u05D02\u05D03\u05D04\u05D05";
+                DefaultMutableTreeNode root = new DefaultMutableTreeNode(s);
+                root.add(new DefaultMutableTreeNode(s));
+                root.add(new DefaultMutableTreeNode(s));
+
+                tree = new JTree(root);
+                editor = new MyTreeCellEditor(tree, new DefaultTreeCellRenderer());
+                tree.setCellEditor(editor);
+                tree.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
+                tree.setEditable(true);
+                JScrollPane sp = new JScrollPane(tree);
+                fr.getContentPane().add(sp);
+
+                fr.setSize(250,200);
+                fr.setLocationRelativeTo(null);
+                fr.setVisible(true);
+            });
+            robot.waitForIdle();
+            robot.delay(1000);
+            SwingUtilities.invokeAndWait(() -> {
+                Rectangle rect = tree.getRowBounds(1);
+                editor.testTreeCellEditor(rect);
+            });
+        } finally {
+            SwingUtilities.invokeAndWait(() -> {
+                if (fr != null) {
+                    fr.dispose();
+                }
+            });
+        }
+    }
+
+    static class MyTreeCellEditor extends DefaultTreeCellEditor {
+
+        public MyTreeCellEditor(JTree tree, DefaultTreeCellRenderer renderer) {
+            super(tree, renderer);
+        }
+
+        public void testTreeCellEditor(Rectangle rect) {
+            int x = rect.x + 10;
+            int y = rect.y + rect.height / 2;
+            MouseEvent me = new MouseEvent(tree,
+                                           MouseEvent.MOUSE_PRESSED,
+                                           (new Date()).getTime(),
+                                           MouseEvent.BUTTON1_DOWN_MASK,
+                                           rect.x + 10, rect.y + 10,
+                                           1, true);
+            isCellEditable(me);
+
+            if (tree == null) {
+                throw new RuntimeException("isCellEditable() should set the tree");
+            }
+            if (lastRow != 1) {
+                throw new RuntimeException("isCellEditable() should set the lastRow");
+            }
+            if (offset == 0) {
+                throw new RuntimeException("isCellEditable() should determine offset");
+            }
+
+            if (!inHitRegion(x,y)) {
+                throw new RuntimeException("Hit region should contain point ("+x+", "+y+")");
+            }
+            x = rect.x + rect.width - 10;
+            if (inHitRegion(x,y)) {
+                throw new RuntimeException("Hit region shouldn't contain point ("+x+", "+y+")");
+            }
+        }
+    }
+
+}
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnilocalreflock04/TestDescription.java b/test/jdk/javax/swing/tree/DefaultTreeCellRenderer/bug4180224.java
similarity index 66%
copy from test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnilocalreflock04/TestDescription.java
copy to test/jdk/javax/swing/tree/DefaultTreeCellRenderer/bug4180224.java
index 42d7299..f9d88f2 100644
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnilocalreflock04/TestDescription.java
+++ b/test/jdk/javax/swing/tree/DefaultTreeCellRenderer/bug4180224.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -21,20 +21,26 @@
  * questions.
  */
 
-
 /*
  * @test
- * @key stress randomness
- *
- * @summary converted from VM Testbase gc/lock/jniref/jnilocalreflock04.
- * VM Testbase keywords: [gc, stress, stressopt, nonconcurrent]
- *
- * @library /vmTestbase
- *          /test/lib
- * @run main/othervm/native
- *      -XX:-UseGCOverheadLimit
- *      gc.lock.LockerTest
- *      -gp1 class
- *      -lockers jniLocalRef
- */
+ * @bug 4180224
+ * @summary DefaultTreeCellRenderer.hasFocus protected (not private) now.
+ * @key headful
+ * @run main bug4180224
+*/
 
+import javax.swing.tree.DefaultTreeCellRenderer;
+
+public class bug4180224 {
+
+    static class MyDTCR extends DefaultTreeCellRenderer {
+        void test() {
+            hasFocus = false;
+        }
+    }
+
+    public static void main(String[] argv) {
+        MyDTCR m = new MyDTCR();
+        m.test();
+    }
+}
diff --git a/test/jdk/javax/swing/tree/DefaultTreeSelectionModel/bug4485322.java b/test/jdk/javax/swing/tree/DefaultTreeSelectionModel/bug4485322.java
new file mode 100644
index 0000000..47ff2a1
--- /dev/null
+++ b/test/jdk/javax/swing/tree/DefaultTreeSelectionModel/bug4485322.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+   @bug 4485322
+   @summary DefaultTreeSelectionModel.insureRowContinuity is broken for CONTIGUOUS_TREE_SELECTION
+   @run main bug4485322
+*/
+
+import javax.swing.SwingUtilities;
+import javax.swing.tree.DefaultTreeSelectionModel;
+import javax.swing.tree.TreeSelectionModel;
+import javax.swing.tree.RowMapper;
+import javax.swing.tree.TreePath;
+
+import java.util.Arrays;
+
+public class bug4485322 {
+
+    Object obj1[] = {"9", "2", "5", "3", "1"};
+    Object obj2[] = {"1", "2", "3"};
+
+    public void init() {
+        DummyDefaultTreeSelectionModel model = new DummyDefaultTreeSelectionModel();
+
+        TreePath sPaths[] = new TreePath[obj1.length];
+        for (int i=0; i<obj1.length; i++) {
+            sPaths[i] = new TreePath(obj1[i]);
+        };
+        model.setSelectionPaths(sPaths);
+
+        model.setRowMapper(new DummyRowMapper());
+        model.setSelectionMode(TreeSelectionModel.CONTIGUOUS_TREE_SELECTION);
+        model.insureRowContinuity();
+
+        TreePath real[] = model.getSelectionPaths();
+        TreePath expected[] = new TreePath[obj2.length];
+        for (int i=0; i<obj2.length; i++) {
+            expected[i] = new TreePath(obj2[i]);
+        };
+
+        if ( !Arrays.equals(real, expected) ) {
+            throw new RuntimeException("The tree selection path is wrong.");
+        }
+    }
+
+    public static class DummyDefaultTreeSelectionModel extends DefaultTreeSelectionModel {
+        public void insureRowContinuity() {
+            super.insureRowContinuity();
+        }
+    }
+
+    public static class DummyRowMapper implements RowMapper {
+        public int[] getRowsForPaths(TreePath[] path) {
+            int rows[] = new int[path.length];
+            for (int i = 0;i < path.length; i++) {
+                String userObject = path[i].getPathComponent(0).toString();
+                rows[i] = Integer.valueOf(userObject);
+            }
+            return rows;
+        }
+    }
+
+    public static void main(String[] argv) throws Exception {
+        bug4485322 b = new bug4485322();
+        SwingUtilities.invokeAndWait(() -> b.init());
+    }
+}
diff --git a/test/jdk/javax/swing/tree/FixedHeightLayoutCache/bug4210354.java b/test/jdk/javax/swing/tree/FixedHeightLayoutCache/bug4210354.java
new file mode 100644
index 0000000..92fdd24
--- /dev/null
+++ b/test/jdk/javax/swing/tree/FixedHeightLayoutCache/bug4210354.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4210354
+ * @summary Tests whether method FixedHeightLayoutCache.getBounds returns bad Rectangle
+ * @run main bug4210354
+ */
+
+import java.awt.Rectangle;
+
+import javax.swing.tree.AbstractLayoutCache;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.FixedHeightLayoutCache;
+import javax.swing.tree.TreePath;
+
+public class bug4210354 {
+    static class DummyNodeDimensions extends AbstractLayoutCache.NodeDimensions {
+        private final Rectangle rectangle;
+
+        public DummyNodeDimensions(Rectangle r) {
+            rectangle = r;
+        }
+        public Rectangle getNodeDimensions(Object value, int row, int depth,
+                                           boolean expanded, Rectangle bounds) {
+            return rectangle;
+        }
+
+        /* create the TreeModel of depth 1 with specified num of children */
+        public DefaultTreeModel getTreeModelILike(int childrenCount) {
+            DefaultMutableTreeNode root = new DefaultMutableTreeNode("root");
+            for (int i = 0; i < childrenCount; i++) {
+                DefaultMutableTreeNode child =
+                        new DefaultMutableTreeNode("root.child" + i);
+                root.insert(child, i);
+            }
+            return new DefaultTreeModel(root);
+        }
+    }
+
+    public void init() {
+        int x = 1, y = 2, dx = 3, dy = 4, h = 3;
+        DummyNodeDimensions dim = new DummyNodeDimensions(new Rectangle(x, y, dx, dy));
+        FixedHeightLayoutCache fhlc = new FixedHeightLayoutCache();
+        fhlc.setModel(dim.getTreeModelILike(3));
+        fhlc.setRootVisible(true);
+        fhlc.setNodeDimensions(dim);
+        fhlc.setRowHeight(h);
+        int row = 0;
+        TreePath path = fhlc.getPathForRow(row);
+        Rectangle r = fhlc.getBounds(path, new Rectangle());
+        Rectangle r2 = new Rectangle(x, row * h, dx, h);
+        if (r.width != r2.width) {
+            throw new RuntimeException("FixedHeightLayoutCache.getBounds returns bad Rectangle");
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        bug4210354 b = new bug4210354();
+        b.init();
+    }
+}
diff --git a/test/jdk/javax/swing/tree/FixedHeightLayoutCache/bug4745001.java b/test/jdk/javax/swing/tree/FixedHeightLayoutCache/bug4745001.java
new file mode 100644
index 0000000..d2befac
--- /dev/null
+++ b/test/jdk/javax/swing/tree/FixedHeightLayoutCache/bug4745001.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4745001
+ * @summary JTree with setLargeModel(true) not display correctly
+ *          when we expand/collapse nodes
+ * @key headful
+ * @run main bug4745001
+*/
+
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.Robot;
+
+import javax.swing.JFrame;
+import javax.swing.JTree;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.TreePath;
+import javax.swing.event.TreeExpansionEvent;
+import javax.swing.event.TreeExpansionListener;
+import javax.swing.SwingUtilities;
+
+public class bug4745001 {
+
+    static JTree tree;
+    static JFrame fr;
+    boolean stateChanged;
+
+    public static void main(String[] args) throws Exception {
+        Robot robot = new Robot();
+        robot.setAutoDelay(100);
+        bug4745001 test = new bug4745001();
+        try {
+            SwingUtilities.invokeAndWait(() -> test.init());
+            robot.waitForIdle();
+            robot.delay(1000);
+            test.start();
+            robot.delay(1000);
+            test.destroy();
+        } finally {
+            SwingUtilities.invokeAndWait(() -> {
+                if (fr != null) {
+                    fr.dispose();
+                }
+            });
+        }
+    }
+
+    public void init() {
+        fr = new JFrame("Test");
+        fr.getContentPane().setLayout(new FlowLayout());
+
+        tree = new JTree();
+        tree.setRowHeight(20);
+        tree.setLargeModel(true);
+        tree.setPreferredSize(new Dimension(100, 400));
+        tree.setRootVisible(false);
+        tree.setShowsRootHandles(true);
+
+        DefaultMutableTreeNode root = new DefaultMutableTreeNode("");
+        DefaultMutableTreeNode a = new DefaultMutableTreeNode("a");
+        DefaultMutableTreeNode b = new DefaultMutableTreeNode("b");
+        DefaultMutableTreeNode c = new DefaultMutableTreeNode("c");
+        root.add(a);
+        root.add(b);
+        root.add(c);
+        b.add(new DefaultMutableTreeNode("b1"));
+        c.add(new DefaultMutableTreeNode("c2"));
+        tree.setModel(new DefaultTreeModel(root));
+
+        fr.getContentPane().add(tree);
+
+        tree.addTreeExpansionListener(new TreeExpansionListener() {
+            public void treeExpanded(TreeExpansionEvent e) {
+                TreePath path = e.getPath();
+                if (path != null) {
+                    DefaultMutableTreeNode node =
+                        (DefaultMutableTreeNode)path.getLastPathComponent();
+                    node.removeAllChildren();
+                    String s = (String)node.getUserObject();
+                    node.add(new DefaultMutableTreeNode(s + "1"));
+                    node.add(new DefaultMutableTreeNode(s + "2"));
+                    node.add(new DefaultMutableTreeNode(s + "3"));
+                    DefaultTreeModel model = (DefaultTreeModel)tree.getModel();
+                    model.nodeStructureChanged(node);
+                    synchronized (bug4745001.this) {
+                        stateChanged = true;
+                        bug4745001.this.notifyAll();
+                    }
+                }
+            }
+
+            public void treeCollapsed(TreeExpansionEvent e) {
+                synchronized (bug4745001.this) {
+                    stateChanged = true;
+                    bug4745001.this.notifyAll();
+                }
+            }
+        });
+
+        fr.pack();
+        fr.setVisible(true);
+    }
+
+    void changeNodeStateForRow(final int row, final boolean expand) throws Exception {
+        try {
+            stateChanged = false;
+            SwingUtilities.invokeAndWait(new Runnable() {
+                public void run() {
+                    try {
+                        if (expand) {
+                            tree.expandRow(row);
+                        } else {
+                            tree.collapseRow(row);
+                        }
+                    } catch (Exception ex) {
+                        ex.printStackTrace();
+                    }
+                 }
+            });
+            synchronized (this) {
+                while (!stateChanged) {
+                    bug4745001.this.wait();
+                }
+            }
+        } catch (Throwable t) {
+            t.printStackTrace();
+        }
+    }
+
+    public void start() throws Exception {
+        // expand node "c"
+        changeNodeStateForRow(2, true);
+        // expand node "b"
+        changeNodeStateForRow(1, true);
+        // collapse node "c"
+        changeNodeStateForRow(1, false);
+    }
+
+    String[] expected = new String[] {"a", "b", "c", "c1", "c2", "c3"};
+
+    public void destroy() {
+        for (int i = 0; i < expected.length; i++) {
+            Object obj = tree.getPathForRow(i).getLastPathComponent();
+            if (!obj.toString().equals(expected[i])) {
+                throw new RuntimeException("Unexpected node at row "+i);
+            }
+        }
+    }
+
+}
diff --git a/test/jdk/javax/swing/undo/UndoManager/bug4706533.java b/test/jdk/javax/swing/undo/UndoManager/bug4706533.java
new file mode 100644
index 0000000..5d8091a
--- /dev/null
+++ b/test/jdk/javax/swing/undo/UndoManager/bug4706533.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4706533
+ * @summary UndoManager.setLimit(0) doesn't correctly trim the UndoManager size
+ * @run main bug4706533
+ */
+
+import javax.swing.undo.AbstractUndoableEdit;
+import javax.swing.undo.CannotUndoException;
+import javax.swing.undo.CannotRedoException;
+import javax.swing.undo.UndoManager;
+
+public class bug4706533 {
+
+    public static void main(String[] args) throws Exception {
+        UndoManager manager = new UndoManager();
+        manager.setLimit(1);
+        AbstractUndoableEdit edit = new MyUndoableEdit();
+        manager.addEdit(edit);
+        manager.setLimit(0);
+        try {
+            manager.undo();
+            throw new RuntimeException("The limit should be zero");
+        } catch (CannotUndoException e) {
+            //Expected to be thrown
+        }
+    }
+
+    static class MyUndoableEdit extends AbstractUndoableEdit {
+        @Override
+        public void undo() throws CannotUndoException {}
+        @Override
+        public void redo() throws CannotRedoException {}
+    }
+}
diff --git a/test/jdk/javax/swing/undo/bug4992178.java b/test/jdk/javax/swing/undo/bug4992178.java
new file mode 100644
index 0000000..6edec55
--- /dev/null
+++ b/test/jdk/javax/swing/undo/bug4992178.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4992178
+ * @summary REGRESSION: Allow unlimited number of edits in an UndoManager
+ * @run main bug4992178
+ */
+
+import javax.swing.undo.AbstractUndoableEdit;
+import javax.swing.undo.CannotRedoException;
+import javax.swing.undo.CannotUndoException;
+import javax.swing.undo.UndoManager;
+
+public class bug4992178 {
+
+    public static void main(String[] argv) throws Exception {
+        TestUndoManager manager = new TestUndoManager();
+        manager.setLimit(1);
+        AbstractUndoableEdit edit = new MyUndoableEdit();
+        manager.addEdit(edit);
+
+        manager.setLimit(-1);
+
+        manager.discardAllEdits();
+
+        if (manager.getVectorSize() != 0) {
+            throw new RuntimeException(
+                "UndoManager's vector size should be 0 after discarding all changes");
+        }
+    }
+
+    static class TestUndoManager extends UndoManager {
+        public int getVectorSize() {
+            return edits.size();
+        }
+    }
+
+    static class MyUndoableEdit extends AbstractUndoableEdit {
+        @Override
+        public void undo() throws CannotUndoException {}
+        @Override
+        public void redo() throws CannotRedoException {}
+    }
+
+}
diff --git a/test/jdk/javax/xml/crypto/dsig/Basic.java b/test/jdk/javax/xml/crypto/dsig/Basic.java
new file mode 100644
index 0000000..4c2e6ed
--- /dev/null
+++ b/test/jdk/javax/xml/crypto/dsig/Basic.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import jdk.test.lib.Asserts;
+import jdk.test.lib.SecurityTools;
+import jdk.test.lib.Utils;
+
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.security.KeyStore;
+import java.security.PrivateKey;
+import java.security.cert.X509Certificate;
+import java.util.List;
+
+import static jdk.test.lib.security.XMLUtils.*;
+/**
+ * @test
+ * @bug 8305972
+ * @summary Basic tests using XMLUtils
+ * @library /test/lib
+ * @modules java.xml.crypto
+ */
+public class Basic {
+
+    public static void main(String[] args) throws Exception {
+        var x = "<a><b>c</b>x</a>";
+        var p = Files.write(Path.of("x.xml"), List.of(x));
+        var b = Path.of("").toUri().toString();
+        var d = string2doc(x);
+        var pass = "changeit".toCharArray();
+        for (String alg: List.of("DSA", "RSA", "RSASSA-PSS", "EC", "EdDSA", "Ed25519", "Ed448")) {
+            SecurityTools.keytool(String.format(
+                    "-keystore ks -keyalg %s -storepass changeit -genkeypair -alias %s -dname CN=%s",
+                    alg, alg, alg)).shouldHaveExitValue(0);
+            var ks = KeyStore.getInstance(new File("ks"), pass);
+            var c = (X509Certificate) ks.getCertificate(alg);
+            var pr = (PrivateKey) ks.getKey(alg, pass);
+            var pu = c.getPublicKey();
+
+            var s0 = signer(pr); // No KeyInfo
+            var s1 = signer(pr, c); // KeyInfo is X509Data
+            var s2 = signer(ks, alg, pass); // KeyInfo is KeyName
+            var v1 = validator(); // knows nothing
+            var v2 = validator(ks); // knows KeyName
+
+            Utils.runAndCheckException(() -> v1.validate(s0.sign(d)), IllegalArgumentException.class); // need PublicKey
+            s0.sign(string2doc(x));
+            Asserts.assertTrue(v1.validate(s0.sign(d), pu)); // need PublicKey
+            Asserts.assertTrue(v1.validate(s1.sign(d))); // can read KeyInfo
+            Asserts.assertTrue(v2.validate(s2.sign(d))); // can read KeyInfo
+            Asserts.assertTrue(v2.secureValidation(false).validate(s2.sign(p.toUri()))); // can read KeyInfo
+            Asserts.assertTrue(v2.secureValidation(false).baseURI(b).validate(
+                    s2.sign(p.toAbsolutePath().getParent().toUri(), p.getFileName().toUri()))); // can read KeyInfo
+
+            Asserts.assertTrue(v1.validate(s0.sign("text"), pu)); // plain text
+            Asserts.assertTrue(v1.validate(s0.sign("binary".getBytes()), pu)); // raw data
+            Asserts.assertTrue(v1.validate(s0.signEnveloping(d, "x", "#x"), pu));
+            Asserts.assertTrue(v1.validate(s0.signEnveloping(d, "x", "#xpointer(id('x'))"), pu));
+
+            // No KeyValue defined for RSASSA-PSS or EdDSA yet
+            if (!alg.startsWith("Ed") && !alg.equals("RSASSA-PSS")) {
+                var ss = signer(pr, pu); // KeyInfo is PublicKey
+                Asserts.assertTrue(v1.validate(ss.sign(d))); // can read KeyInfo
+                Asserts.assertTrue(v1.validate(ss.sign("text"))); // plain text
+                Asserts.assertTrue(v1.validate(ss.sign("binary".getBytes()))); // raw data
+                Asserts.assertTrue(v1.validate(ss.signEnveloping(d, "x", "#x")));
+                Asserts.assertTrue(v1.validate(ss.signEnveloping(d, "x", "#xpointer(id('x'))")));
+            }
+        }
+    }
+
+}
diff --git a/test/jdk/javax/xml/crypto/dsig/GenerationTests.java b/test/jdk/javax/xml/crypto/dsig/GenerationTests.java
index e78ec02..45b7223 100644
--- a/test/jdk/javax/xml/crypto/dsig/GenerationTests.java
+++ b/test/jdk/javax/xml/crypto/dsig/GenerationTests.java
@@ -24,7 +24,7 @@
 /**
  * @test
  * @bug 4635230 6283345 6303830 6824440 6867348 7094155 8038184 8038349 8046949
- *      8046724 8079693 8177334 8205507 8210736 8217878 8241306
+ *      8046724 8079693 8177334 8205507 8210736 8217878 8241306 8305972
  * @summary Basic unit tests for generating XML Signatures with JSR 105
  * @modules java.base/sun.security.util
  *          java.base/sun.security.x509
@@ -56,18 +56,8 @@
 import java.security.cert.Certificate;
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509CRL;
-import java.security.spec.KeySpec;
-import java.security.spec.DSAPrivateKeySpec;
-import java.security.spec.DSAPublicKeySpec;
-import java.security.spec.ECField;
-import java.security.spec.ECFieldFp;
-import java.security.spec.ECParameterSpec;
-import java.security.spec.ECPoint;
-import java.security.spec.ECPrivateKeySpec;
-import java.security.spec.ECPublicKeySpec;
-import java.security.spec.EllipticCurve;
-import java.security.spec.RSAPrivateKeySpec;
-import java.security.spec.RSAPublicKeySpec;
+import java.security.cert.X509Certificate;
+import java.security.spec.*;
 import java.util.*;
 import java.util.stream.Stream;
 import javax.crypto.KeyGenerator;
@@ -110,12 +100,15 @@
             rsaSha1, rsaSha224, rsaSha256, rsaSha384, rsaSha512,
             ecdsaSha1, ecdsaSha224, ecdsaSha256, ecdsaSha384, ecdsaSha512,
             hmacSha1, hmacSha224, hmacSha256, hmacSha384, hmacSha512,
-            rsaSha1mgf1, rsaSha224mgf1, rsaSha256mgf1, rsaSha384mgf1, rsaSha512mgf1, rsaShaPSS;
+            rsaSha1mgf1, rsaSha224mgf1, rsaSha256mgf1, rsaSha384mgf1, rsaSha512mgf1,
+            rsaSha3_224mgf1, rsaSha3_256mgf1, rsaSha3_384mgf1, rsaSha3_512mgf1,
+            rsaShaPSS, ed25519, ed448;
     private static DigestMethod sha1, sha224, sha256, sha384, sha512,
                                 sha3_224, sha3_256, sha3_384, sha3_512;
     private static KeyInfo dsa1024, dsa2048, rsa, rsa1024, rsa2048,
-                           p256ki, p384ki, p521ki;
+                           p256ki, p384ki, p521ki, ed25519ki, ed448ki;
     private static KeySelector kvks = new KeySelectors.KeyValueKeySelector();
+    private static KeySelector x5ks = new KeySelectors.RawX509KeySelector();
     private static KeySelector sks;
     private static Key signingKey;
     private static PublicKey validatingKey;
@@ -217,7 +210,9 @@
             SignatureMethod.ECDSA_SHA256,
             SignatureMethod.HMAC_SHA256,
             SignatureMethod.SHA256_RSA_MGF1,
-            SignatureMethod.RSA_PSS);
+            "http://www.w3.org/2007/05/xmldsig-more#sha3-256-rsa-MGF1",
+            SignatureMethod.RSA_PSS,
+            "http://www.w3.org/2021/04/xmldsig-more#eddsa-ed25519");
 
     private static final String[] allSignatureMethods
             = Stream.of(SignatureMethod.class.getDeclaredFields())
@@ -249,7 +244,7 @@
                 })
                 .toArray(String[]::new);
 
-    // As of JDK 17, the number of defined algorithms are...
+    // As of JDK 21, the number of defined algorithms are...
     static {
         if (allSignatureMethods.length != 23
                 || allDigestMethods.length != 9) {
@@ -312,6 +307,8 @@
         test_create_signature_enveloping_p256_sha512();
         test_create_signature_enveloping_p384_sha1();
         test_create_signature_enveloping_p521_sha1();
+        test_create_signature_enveloping_ed25519();
+        test_create_signature_enveloping_ed448();
         test_create_signature_external_b64_dsa();
         test_create_signature_external_dsa();
         test_create_signature_keyname();
@@ -339,6 +336,10 @@
         test_create_signature_enveloping_sha512_rsa_sha256_mgf1();
         test_create_signature_enveloping_sha512_rsa_sha384_mgf1();
         test_create_signature_enveloping_sha512_rsa_sha512_mgf1();
+        test_create_signature_enveloping_sha512_rsa_sha3_224_mgf1();
+        test_create_signature_enveloping_sha512_rsa_sha3_256_mgf1();
+        test_create_signature_enveloping_sha512_rsa_sha3_384_mgf1();
+        test_create_signature_enveloping_sha512_rsa_sha3_512_mgf1();
         test_create_signature_enveloping_sha512_rsa_pss();
         test_create_signature_reference_dependency();
         test_create_signature_with_attr_in_no_namespace();
@@ -359,8 +360,10 @@
                         Arrays.stream(xml_transforms).forEach(t ->
                             Arrays.stream(KeyInfoType.values()).forEach(k -> {
                                 if (isMajor(s, d)) {
-                                    test_create_detached_signature(c, s, d, t, k,
-                                            Content.Xml, server.getPort(), false, null);
+                                    if (!s.contains("#eddsa") || k != KeyInfoType.KeyValue) {
+                                        test_create_detached_signature(c, s, d, t, k,
+                                                Content.Xml, server.getPort(), false, null);
+                                    }
                                 }
                         })))));
 
@@ -370,8 +373,10 @@
                     Arrays.stream(allDigestMethods).forEach(d ->
                         Arrays.stream(KeyInfoType.values()).forEach(k -> {
                             if (isMajor(s, d)) {
-                                test_create_detached_signature(c, s, d, null, k,
-                                        Content.Text, server.getPort(), false, null);
+                                if (!s.contains("#eddsa") || k != KeyInfoType.KeyValue) {
+                                    test_create_detached_signature(c, s, d, null, k,
+                                            Content.Text, server.getPort(), false, null);
+                                }
                             }
                         }))));
 
@@ -382,9 +387,11 @@
                         Arrays.stream(non_xml_transforms).forEach(t ->
                             Arrays.stream(KeyInfoType.values()).forEach(k -> {
                                 if (isMajor(s, d)) {
-                                    test_create_detached_signature(c, s, d, t, k,
-                                            Content.Base64, server.getPort(),
-                                            false, null);
+                                    if (!s.contains("#eddsa") || k != KeyInfoType.KeyValue) {
+                                        test_create_detached_signature(c, s, d, t, k,
+                                                Content.Base64, server.getPort(),
+                                                false, null);
+                                    }
                                 }
                         })))));
 
@@ -525,6 +532,11 @@
         p521ki = kifac.newKeyInfo(Collections.singletonList
             (kifac.newKeyValue(getECPublicKey("P521"))));
 
+        ed25519ki = kifac.newKeyInfo(Collections.singletonList
+            (kifac.newX509Data(List.of(getEd25519Certificate()))));
+        ed448ki = kifac.newKeyInfo(Collections.singletonList
+                (kifac.newX509Data(List.of(getEd448Certificate()))));
+
         rsaSha1 = fac.newSignatureMethod(SignatureMethod.RSA_SHA1, null);
         rsaSha224 = fac.newSignatureMethod(SignatureMethod.RSA_SHA224, null);
         rsaSha256 = fac.newSignatureMethod(SignatureMethod.RSA_SHA256, null);
@@ -536,6 +548,10 @@
         rsaSha256mgf1 = fac.newSignatureMethod(SignatureMethod.SHA256_RSA_MGF1, null);
         rsaSha384mgf1 = fac.newSignatureMethod(SignatureMethod.SHA384_RSA_MGF1, null);
         rsaSha512mgf1 = fac.newSignatureMethod(SignatureMethod.SHA512_RSA_MGF1, null);
+        rsaSha3_224mgf1 = fac.newSignatureMethod("http://www.w3.org/2007/05/xmldsig-more#sha3-224-rsa-MGF1", null);
+        rsaSha3_256mgf1 = fac.newSignatureMethod("http://www.w3.org/2007/05/xmldsig-more#sha3-256-rsa-MGF1", null);
+        rsaSha3_384mgf1 = fac.newSignatureMethod("http://www.w3.org/2007/05/xmldsig-more#sha3-384-rsa-MGF1", null);
+        rsaSha3_512mgf1 = fac.newSignatureMethod("http://www.w3.org/2007/05/xmldsig-more#sha3-512-rsa-MGF1", null);
         rsaShaPSS = fac.newSignatureMethod(SignatureMethod. RSA_PSS, null);
 
         ecdsaSha1 = fac.newSignatureMethod(SignatureMethod.ECDSA_SHA1, null);
@@ -544,6 +560,9 @@
         ecdsaSha384 = fac.newSignatureMethod(SignatureMethod.ECDSA_SHA384, null);
         ecdsaSha512 = fac.newSignatureMethod(SignatureMethod.ECDSA_SHA512, null);
 
+        ed25519 = fac.newSignatureMethod("http://www.w3.org/2021/04/xmldsig-more#eddsa-ed25519", null);
+        ed448 = fac.newSignatureMethod("http://www.w3.org/2021/04/xmldsig-more#eddsa-ed448", null);
+
         hmacSha1 = fac.newSignatureMethod(SignatureMethod.HMAC_SHA1, null);
         hmacSha224 = fac.newSignatureMethod(SignatureMethod.HMAC_SHA224, null);
         hmacSha256 = fac.newSignatureMethod(SignatureMethod.HMAC_SHA256, null);
@@ -798,6 +817,38 @@
         System.out.println();
     }
 
+    static void test_create_signature_enveloping_sha512_rsa_sha3_224_mgf1()
+            throws Exception {
+        System.out.println("* Generating signature-enveloping-sha512-rsa_sha3_224_mgf1.xml");
+        test_create_signature_enveloping(sha512, rsaSha3_224mgf1, rsa1024,
+                getPrivateKey("RSA", 1024), kvks, false, true);
+        System.out.println();
+    }
+
+    static void test_create_signature_enveloping_sha512_rsa_sha3_256_mgf1()
+            throws Exception {
+        System.out.println("* Generating signature-enveloping-sha512-rsa_sha3_256_mgf1.xml");
+        test_create_signature_enveloping(sha512, rsaSha3_256mgf1, rsa1024,
+                getPrivateKey("RSA", 1024), kvks, false, true);
+        System.out.println();
+    }
+
+    static void test_create_signature_enveloping_sha512_rsa_sha3_384_mgf1()
+            throws Exception {
+        System.out.println("* Generating signature-enveloping-sha512-rsa_sha3_384_mgf1.xml");
+        test_create_signature_enveloping(sha512, rsaSha3_384mgf1, rsa1024,
+                getPrivateKey("RSA", 1024), kvks, false, true);
+        System.out.println();
+    }
+
+    static void test_create_signature_enveloping_sha512_rsa_sha3_512_mgf1()
+            throws Exception {
+        System.out.println("* Generating signature-enveloping-sha512-rsa_sha3_512_mgf1.xml");
+        test_create_signature_enveloping(sha512, rsaSha3_512mgf1, rsa2048,
+                getPrivateKey("RSA", 2048), kvks, false, true);
+        System.out.println();
+    }
+
     static void test_create_signature_enveloping_sha512_rsa_pss()
             throws Exception {
         System.out.println("* Generating signature-enveloping-sha512_rsa_pss.xml");
@@ -855,6 +906,20 @@
         System.out.println();
     }
 
+    static void test_create_signature_enveloping_ed25519() throws Exception {
+        System.out.println("* Generating signature-enveloping-ed25519.xml");
+        test_create_signature_enveloping(sha1, ed25519, ed25519ki,
+                getEd25519PrivateKey(), x5ks, false, true);
+        System.out.println();
+    }
+
+    static void test_create_signature_enveloping_ed448() throws Exception {
+        System.out.println("* Generating signature-enveloping-ed448.xml");
+        test_create_signature_enveloping(sha1, ed448, ed448ki,
+                getEd448PrivateKey(), x5ks, false, true);
+        System.out.println();
+    }
+
     static void test_create_signature_external_b64_dsa() throws Exception {
         System.out.println("* Generating signature-external-b64-dsa.xml");
         test_create_signature_external(dsaSha1, dsa1024, signingKey, kvks, true);
@@ -1950,13 +2015,15 @@
                             || sm.contains("-rsa-MGF1")) {
                         kpg = KeyPairGenerator.getInstance("RSA");
                         kpg.initialize(
-                                sm.contains("#sha512-rsa-MGF1") ? 2048 : 1024);
+                                sm.contains("512-rsa-MGF1") ? 2048 : 1024);
                     } else if (sm.contains("#dsa-")) {
                         kpg = KeyPairGenerator.getInstance("DSA");
                         kpg.initialize(1024);
                     } else if (sm.contains("#ecdsa-")) {
                         kpg = KeyPairGenerator.getInstance("EC");
                         kpg.initialize(256);
+                    } else if (sm.contains("#eddsa-")) {
+                        kpg = KeyPairGenerator.getInstance(sm.substring(sm.lastIndexOf('-') + 1));
                     } else {
                         throw new RuntimeException("Unsupported signature algorithm");
                     }
@@ -2085,6 +2152,20 @@
         1
     );
 
+    private static final String ED25519_CERT =
+            "3081d730818aa003020102020822bc4997b1893265300506032b657030123110300e0603550403130745643235353139301e170d3233303431333033303732365a170d3433303430383033303" +
+            "732365a30123110300e0603550403130745643235353139302a300506032b657003210012ecd7383ac90c30035dc531285bdb897faafddfc6969271c2ebd9a82b6078e5300506032b65700341" +
+            "00a3cb7c03bbb3e9fa92eaf3f9a6f2608460d472c6a6ce3bebf0f57f45612e87ebdc6aa6d7527ae9e86c8e10bcccf98963f9b082c0bb44adb240c5fce9bb68b301";
+    private static final String ED25519_KEY =
+            "b59e57e352fa03b3a643946ae60b7f1e276f9ab41f25accaa63b660ba36168b2";
+    private static final String ED448_CERT =
+            "3082011f3081a0a003020102020900ceaefd75473d52b2300506032b65713010310e300c060355040313054564343438301e170d3233303431333033303735345a170d3433303430383033303" +
+            "735345a3010310e300c0603550403130545643434383043300506032b6571033a00d605be958f21faf6a1181fa96ebe8580cca3cae9b48dfad5145ee999d9df4ef77c355d33ae8b21e9a3541f" +
+            "b985ae366b9678db1a3fd1fd5c00300506032b65710373000b4dc8de20b261f5ca7cf41777725a2ec6cd107d6b75cd6ad02c00af8096ecf97c7445596aabd70381ce087d2b3b280ca4181566b" +
+            "9230fd6801e22e53f1514989bc5b06cfb5f7cac222ea9a37a0771a3f7cfcbfd1ba9546bbe333d37ee81c3a53d86247d377225114e1e81123f947a391800";
+    private static final String ED448_KEY =
+            "50b72f081f7f2f3383c4b03975cf49a76ba8b17dec51eaea3cd267b6989b81786e8dd8af4df305eaad60bdd24345b8490548c371d62e926f80";
+
     private static ECParameterSpec initECParams(
             String sfield, String a, String b, String gx, String gy,
             String n, int h) {
@@ -2158,6 +2239,16 @@
         return kf.generatePublic(kspec);
     }
 
+    private static X509Certificate getEd25519Certificate() throws Exception {
+        return (X509Certificate) CertificateFactory.getInstance("X.509")
+                .generateCertificate(new ByteArrayInputStream(HexFormat.of().parseHex(ED25519_CERT)));
+    }
+
+    private static X509Certificate getEd448Certificate() throws Exception {
+        return (X509Certificate) CertificateFactory.getInstance("X.509")
+                .generateCertificate(new ByteArrayInputStream(HexFormat.of().parseHex(ED448_CERT)));
+    }
+
     private static PrivateKey getPrivateKey(String algo, int keysize)
         throws Exception {
         KeyFactory kf = KeyFactory.getInstance(algo);
@@ -2211,6 +2302,16 @@
         return kf.generatePrivate(kspec);
     }
 
+    private static PrivateKey getEd25519PrivateKey() throws Exception {
+        return KeyFactory.getInstance("Ed25519").generatePrivate(new EdECPrivateKeySpec(
+                NamedParameterSpec.ED25519, HexFormat.of().parseHex(ED25519_KEY)));
+    }
+
+    private static PrivateKey getEd448PrivateKey() throws Exception {
+        return KeyFactory.getInstance("Ed448").generatePrivate(new EdECPrivateKeySpec(
+                NamedParameterSpec.ED448, HexFormat.of().parseHex(ED448_KEY)));
+    }
+
     private static SecretKey getSecretKey(final byte[] secret) {
         return new SecretKey() {
             public String getFormat()   { return "RAW"; }
diff --git a/test/jdk/javax/xml/crypto/dsig/HereFunction.java b/test/jdk/javax/xml/crypto/dsig/HereFunction.java
new file mode 100644
index 0000000..4910d0e
--- /dev/null
+++ b/test/jdk/javax/xml/crypto/dsig/HereFunction.java
@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8305972
+ * @summary Demonstrate here() support for validating XML Signatures
+ * @modules java.base/sun.security.util
+ *          java.base/sun.security.x509
+ *          java.xml.crypto/org.jcp.xml.dsig.internal.dom
+ * @library /test/lib
+ * @compile -XDignore.symbol.file KeySelectors.java SignatureValidator.java
+ *     X509KeySelector.java ValidationTests.java
+ * @run main/othervm HereFunction default true
+ * @run main/othervm HereFunction true true
+ * @run main/othervm HereFunction false false
+ */
+import java.io.File;
+import java.io.FileInputStream;
+import java.security.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import javax.xml.crypto.Data;
+import javax.xml.crypto.KeySelector;
+import javax.xml.crypto.OctetStreamData;
+import javax.xml.crypto.URIDereferencer;
+import javax.xml.crypto.URIReference;
+import javax.xml.crypto.URIReferenceException;
+import javax.xml.crypto.XMLCryptoContext;
+import javax.xml.crypto.dsig.*;
+import javax.xml.crypto.dsig.dom.DOMSignContext;
+import javax.xml.crypto.dsig.dom.DOMValidateContext;
+import javax.xml.crypto.dsig.keyinfo.KeyInfo;
+import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
+import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
+import javax.xml.crypto.dsig.spec.XPathFilterParameterSpec;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import jdk.test.lib.Asserts;
+import jdk.test.lib.Utils;
+import jdk.test.lib.security.SecurityUtils;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+public class HereFunction {
+
+    private final static String DIR = System.getProperty("test.src", ".");
+    private final static String DATA_DIR =
+            DIR + System.getProperty("file.separator") + "data";
+    private final static String KEYSTORE_VERIFY =
+            DATA_DIR + System.getProperty("file.separator") + "certs" +
+                    System.getProperty("file.separator") + "xmldsig.jks";
+    private final static String KEYSTORE_SIGN =
+            DATA_DIR + System.getProperty("file.separator") + "certs" +
+                    System.getProperty("file.separator") + "test.jks";
+    private final static String STYLESHEET =
+            "http://www.w3.org/TR/xml-stylesheet";
+    private final static String STYLESHEET_B64 =
+            "http://www.w3.org/Signature/2002/04/xml-stylesheet.b64";
+    private final static char[] PASS = "changeit".toCharArray();
+
+    public static void main(String args[]) throws Throwable {
+        if (!args[0].equals("default")) {
+            Security.setProperty("jdk.xml.dsig.hereFunctionSupported", args[0]);
+        }
+        // Re-enable sha1 algs
+        SecurityUtils.removeAlgsFromDSigPolicy("sha1");
+
+        boolean expected = Boolean.parseBoolean(args[1]);
+
+        sign(expected);
+
+        // Validating an old signature signed by JDK < 21
+        validate(expected);
+    }
+
+    static void validate(boolean expected) throws Exception {
+        SignatureValidator validator = new SignatureValidator(new File(DATA_DIR));
+
+        KeyStore keystore = KeyStore.getInstance(new File(KEYSTORE_VERIFY), PASS);
+        KeySelector ks = new X509KeySelector(keystore, false);
+
+        if (expected) {
+            Asserts.assertTrue(validator.validate(
+                    "signature.xml", ks, new HttpURIDereferencer(), false));
+        } else {
+            Utils.runAndCheckException(() -> validator.validate(
+                    "signature.xml", ks, new HttpURIDereferencer(), false),
+                    XMLSignatureException.class);
+        }
+    }
+
+    static void sign(boolean expected) throws Exception {
+        XMLSignatureFactory fac = XMLSignatureFactory.getInstance();
+        DigestMethod sha1 = fac.newDigestMethod(DigestMethod.SHA1, null);
+        CanonicalizationMethod withoutComments = fac.newCanonicalizationMethod
+                (CanonicalizationMethod.INCLUSIVE, (C14NMethodParameterSpec)null);
+        SignatureMethod dsaSha1 = fac.newSignatureMethod(SignatureMethod.DSA_SHA1, null);
+        KeyInfoFactory kifac = fac.getKeyInfoFactory();
+        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+        dbf.setNamespaceAware(true);
+
+        String ENVELOPE =
+                DATA_DIR + System.getProperty("file.separator") + "envelope.xml";
+
+        var ks = KeyStore.getInstance(new File(KEYSTORE_SIGN), PASS);
+        var signingKey = ks.getKey("user", PASS);
+        var signingCert = ks.getCertificate("user");
+
+        // create references
+        List<Reference> refs = new ArrayList<>();
+
+        // Reference 1
+        refs.add(fac.newReference(STYLESHEET, sha1));
+
+        // Reference 2
+        String expr = "\n"
+                + " ancestor-or-self::dsig:SignedInfo                  " + "\n"
+                + "  and                                               " + "\n"
+                + " count(ancestor-or-self::dsig:Reference |           " + "\n"
+                + "      here()/ancestor::dsig:Reference[1]) >         " + "\n"
+                + " count(ancestor-or-self::dsig:Reference)            " + "\n"
+                + "  or                                                " + "\n"
+                + " count(ancestor-or-self::node() |                   " + "\n"
+                + "      id('notaries')) =                             " + "\n"
+                + " count(ancestor-or-self::node())                    " + "\n";
+
+        XPathFilterParameterSpec xfp = new XPathFilterParameterSpec(expr,
+                Collections.singletonMap("dsig", XMLSignature.XMLNS));
+        refs.add(fac.newReference("", sha1, Collections.singletonList
+                        (fac.newTransform(Transform.XPATH, xfp)),
+                XMLObject.TYPE, null));
+
+        // create SignedInfo
+        SignedInfo si = fac.newSignedInfo(withoutComments, dsaSha1, refs);
+
+        // create keyinfo
+        KeyInfo ki = kifac.newKeyInfo(List.of(
+                kifac.newX509Data(List.of(signingCert))), null);
+
+        // create XMLSignature
+        XMLSignature sig = fac.newXMLSignature(si, ki, null, "signature", null);
+
+        dbf.setValidating(false);
+        Document envDoc = dbf.newDocumentBuilder()
+                .parse(new FileInputStream(ENVELOPE));
+        Element ys = (Element)
+                envDoc.getElementsByTagName("YoursSincerely").item(0);
+
+        DOMSignContext dsc = new DOMSignContext(signingKey, ys);
+        dsc.setURIDereferencer(new HttpURIDereferencer());
+
+        if (expected) {
+            sig.sign(dsc);
+        } else {
+            Utils.runAndCheckException(
+                    () -> sig.sign(dsc), XMLSignatureException.class);
+            return; // Signing fails, no need to validate
+        }
+
+//      StringWriter sw = new StringWriter();
+//        dumpDocument(envDoc, sw);
+
+        NodeList nl =
+                envDoc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
+        if (nl.getLength() == 0) {
+            throw new Exception("Couldn't find signature Element");
+        }
+        Element sigElement = (Element) nl.item(0);
+
+        DOMValidateContext dvc = new DOMValidateContext
+                (new X509KeySelector(ks), sigElement);
+        dvc.setURIDereferencer(new HttpURIDereferencer());
+        File f = new File(
+                System.getProperty("dir.test.vector.baltimore") +
+                        System.getProperty("file.separator") +
+                        "merlin-xmldsig-twenty-three" +
+                        System.getProperty("file.separator"));
+        dvc.setBaseURI(f.toURI().toString());
+
+        XMLSignature sig2 = fac.unmarshalXMLSignature(dvc);
+
+        if (sig.equals(sig2) == false) {
+            throw new Exception
+                    ("Unmarshalled signature is not equal to generated signature");
+        }
+        if (sig2.validate(dvc) == false) {
+            throw new Exception("Validation of generated signature failed");
+        }
+    }
+
+    /**
+     * This URIDereferencer returns locally cached copies of http content to
+     * avoid test failures due to network glitches, etc.
+     */
+    private static class HttpURIDereferencer implements URIDereferencer {
+        private final URIDereferencer defaultUd;
+
+        HttpURIDereferencer() {
+            defaultUd = XMLSignatureFactory.getInstance().getURIDereferencer();
+        }
+
+        public Data dereference(final URIReference ref, XMLCryptoContext ctx)
+                throws URIReferenceException {
+            String uri = ref.getURI();
+            if (uri.equals(STYLESHEET) || uri.equals(STYLESHEET_B64)) {
+                try {
+                    FileInputStream fis = new FileInputStream(new File
+                            (DATA_DIR, uri.substring(uri.lastIndexOf('/'))));
+                    return new OctetStreamData(fis,ref.getURI(),ref.getType());
+                } catch (Exception e) { throw new URIReferenceException(e); }
+            }
+
+            // fallback on builtin deref
+            return defaultUd.dereference(ref, ctx);
+        }
+    }
+}
diff --git a/test/jdk/javax/xml/crypto/dsig/SecureValidation.java b/test/jdk/javax/xml/crypto/dsig/SecureValidation.java
index 2e6669a..04291f8 100644
--- a/test/jdk/javax/xml/crypto/dsig/SecureValidation.java
+++ b/test/jdk/javax/xml/crypto/dsig/SecureValidation.java
@@ -29,6 +29,7 @@
  * @library /test/lib
  * @modules java.base/sun.security.tools.keytool
  *          java.base/sun.security.x509
+ * @run main/othervm SecureValidation
  */
 import jdk.test.lib.Asserts;
 import jdk.test.lib.security.XMLUtils;
diff --git a/test/jdk/jb/hotspot/DetectVirtualization.java b/test/jdk/jb/hotspot/DetectVirtualization.java
new file mode 100644
index 0000000..451dc02
--- /dev/null
+++ b/test/jdk/jb/hotspot/DetectVirtualization.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2022-2024 JetBrains s.r.o.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+/**
+ * @test
+ * @summary Verifies that the system property describing virtualization
+ *          is present
+ * @library /test/lib
+ * @run main DetectVirtualization
+ */
+
+public class DetectVirtualization {
+    static final String VIRT_PROPERTY_NAME = "intellij.os.virtualization";
+
+    public static void main(String args[]) {
+        String virtualization = System.getProperty(VIRT_PROPERTY_NAME);
+        System.out.println("Detected virtualization: " + virtualization);
+        switch (virtualization) {
+            case "Xen":
+            case "KVM":
+            case "VMWare":
+            case "HyperV":
+            case "none":
+                break;
+            default:
+                throw new RuntimeException(VIRT_PROPERTY_NAME + " has an unexpected value " + virtualization);
+        }
+    }
+}
diff --git a/test/jdk/jb/hotspot/RSSInCrashLog.java b/test/jdk/jb/hotspot/RSSInCrashLog.java
new file mode 100644
index 0000000..0d5709e
--- /dev/null
+++ b/test/jdk/jb/hotspot/RSSInCrashLog.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2024 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * @test
+ * @summary Verifies that the HotSpot crash log includes RSS information.
+ * @library /test/lib
+ * @run main RSSInCrashLog
+ */
+
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.process.OutputAnalyzer;
+
+import java.util.ArrayList;
+import java.util.Optional;
+
+public class RSSInCrashLog {
+    public static void main(String args[]) throws Exception {
+        if (args.length > 0 && args[0].equals("--test")) {
+            System.out.println("Proceeding to crash JVM with OOME");
+            crashJVM();
+            System.out.println("...shouldn't reach here");
+        } else {
+            generateAndVerifyCrashLogContents();
+        }
+    }
+
+    static void crashJVM() {
+        System.out.println("------- first attempt to crash -------");
+        long[][][] array = new long[100][][];
+        for (int i = 0; i < 100; i++) {
+            System.out.println("------- crash attempt #" + i + "-------");
+            array[i] = new long[1000][1000];
+        }
+        int random = (int) (Math.random() * 100);
+
+        System.out.println(array[random][42][0]);
+    }
+
+    public static void generateAndVerifyCrashLogContents() throws Exception {
+        ArrayList<String> opts = new ArrayList<>();
+        opts.add("-Xmx20m");
+        opts.add("-XX:-CreateCoredumpOnCrash");
+        opts.add("-XX:+CrashOnOutOfMemoryError");
+        opts.add("-XX:+ErrorFileToStdout");
+        opts.add(RSSInCrashLog.class.getName());
+        opts.add("--test");
+        ProcessBuilder pb = ProcessTools.createTestJvm(opts);
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+        output.outputTo(System.out);
+        output.shouldContain("Process memory usage");
+        output.shouldContain("Resident Set Size: ");
+
+        Optional<String> rssLine = output.asLines().stream().filter(it -> it.startsWith("Resident Set Size:")).findAny();
+        String rssValue = rssLine.get().split(" ")[3];
+        if (!rssValue.endsWith("K")) {
+            throw new RuntimeException("RSS '" + rssValue + "' does not end with 'K'");
+        }
+        rssValue = rssValue.substring(0, rssValue.length() - 1);
+        long rss = Long.parseLong(rssValue);
+        System.out.println("Parsed RSS: " + rss);
+        if (rss < 10) {
+            throw new RuntimeException("RSS is unusually small: " + rss + "K");
+        }
+    }
+}
diff --git a/test/jdk/jb/hotspot/RSSInVmInfo.java b/test/jdk/jb/hotspot/RSSInVmInfo.java
new file mode 100644
index 0000000..e8f0d0a
--- /dev/null
+++ b/test/jdk/jb/hotspot/RSSInVmInfo.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2024 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+/*
+ * @test
+ * @summary Verifies that the VM.info jcmd includes RSS information.
+ * @library /test/lib
+ * @run main/othervm RSSInVmInfo
+ */
+
+import jdk.test.lib.JDKToolFinder;
+import jdk.test.lib.process.OutputAnalyzer;
+
+import java.io.IOException;
+import java.util.Optional;
+
+public class RSSInVmInfo {
+    public static void main(String args[]) throws Exception {
+        long pid = ProcessHandle.current().pid();
+        final OutputAnalyzer output = runJCmd(pid);
+        output.outputTo(System.out);
+        output.shouldContain("Process memory usage");
+        output.shouldContain("Resident Set Size: ");
+
+        Optional<String> rssLine = output.asLines().stream().filter(it -> it.startsWith("Resident Set Size:")).findAny();
+        String rssValue = rssLine.get().split(" ")[3];
+        if (!rssValue.endsWith("K")) {
+            throw new RuntimeException("RSS '" + rssValue + "' does not end with 'K'");
+        }
+        rssValue = rssValue.substring(0, rssValue.length() - 1);
+        long rss = Long.parseLong(rssValue);
+        System.out.println("Parsed RSS: " + rss);
+        if (rss < 10) {
+            throw new RuntimeException("RSS is unusually small: " + rss + "K");
+        }
+    }
+
+    static OutputAnalyzer runJCmd(long pid) {
+        try {
+            final String jcmd = JDKToolFinder.getTestJDKTool("jcmd");
+            final ProcessBuilder pb = new ProcessBuilder(jcmd, String.valueOf(pid), "VM.info");
+            OutputAnalyzer output = new OutputAnalyzer(pb.start());
+            output.outputTo(System.out);
+            output.shouldHaveExitValue(0);
+            return output;
+        } catch (IOException e) {
+            throw new RuntimeException("Launching jcmd failed", e);
+        }
+    }
+}
diff --git a/test/jdk/jbMMProblemList.txt b/test/jdk/jbMMProblemList.txt
index b87eaf7..b8dbfa7 100644
--- a/test/jdk/jbMMProblemList.txt
+++ b/test/jdk/jbMMProblemList.txt
@@ -17,7 +17,6 @@
 java/awt/datatransfer/Clipboard/GetContentsInterruptedTest.java JBR-5086 linux-5.15.0-46-generic Ubuntu 20.04
 java/awt/Robot/NonEmptyErrorStream.java JBR-5442 linux-all
 java/awt/Robot/MouseLocationOnScreen/MouseLocationOnScreen.java JBR-5390 macosx-all,linux-all
-java/awt/Robot/NonEmptyErrorStream.java JBR-5442 linux-all
 java/awt/Robot/RobotMoveMultiscreen.java JBR-5442 linux-all
 java/awt/Toolkit/AWTEventListenerProxyTest/AWTEventListenerProxyTest.java JBR-6065 windows-all
 java/awt/Window/SlowMotion/SlowMotion.java JBR-5442 linux-all
diff --git a/test/jdk/jbProblemList.txt b/test/jdk/jbProblemList.txt
index 7db265d..e2c50ea 100644
--- a/test/jdk/jbProblemList.txt
+++ b/test/jdk/jbProblemList.txt
@@ -159,6 +159,7 @@
 java/awt/dnd/DropActionChangeTest.java JBR-6489 generic-all
 java/awt/dnd/DropTargetEnterExitTest/ExtraDragEnterTest.java 8029680 generic-all
 java/awt/dnd/DropTargetEnterExitTest/MissedDragExitTest.java JBR-5730 linux-all
+java/awt/dnd/DropTargetingTest.java JBR-6729 windows-all
 java/awt/dnd/MissedDragEnterTest.java JBR-6091 windows-all
 java/awt/dnd/NestedHeavyweightDropTargetTest.java JBR-6580 windows-x64
 java/awt/dnd/NextDropActionTest/NextDropActionTest.java 8313633 macosx-aarch64
@@ -170,9 +171,10 @@
 java/awt/Focus/ChoiceFocus/ChoiceFocus.java 8169103 windows-all,macosx-all
 java/awt/Focus/ClearGlobalFocusOwnerTest/ClearGlobalFocusOwnerTest.java JBR-5907 linux-all
 java/awt/Focus/ClearLwQueueBreakTest/ClearLwQueueBreakTest.java 8198618,JBR-814 macosx-all,linux-all
-java/awt/Focus/ConsumeNextKeyTypedOnModalShowTest/ConsumeNextKeyTypedOnModalShowTest.java 6986252,JBR-5178 windows-all
+java/awt/Focus/ConsumeNextKeyTypedOnModalShowTest/ConsumeNextKeyTypedOnModalShowTest.java 6986252,JBR-5178,JBR-6750 windows-all,linux-all
 java/awt/Focus/ConsumedTabKeyTest.java JBR-5833 windows-all
 java/awt/Focus/KeyEventForBadFocusOwnerTest/KeyEventForBadFocusOwnerTest.java JBR-5210 windows-all
+java/awt/Focus/ModalExcludedWindowClickTest/ModalExcludedWindowClickTest.java JBR-884 windows-x64,linux-all
 java/awt/Focus/MouseClickRequestFocusRaceTest/MouseClickRequestFocusRaceTest.java 8194753 linux-all,macosx-all
 java/awt/Focus/NoAutotransferToDisabledCompTest/NoAutotransferToDisabledCompTest.java 7152980,JBR-5210 macosx-all,windows-all
 java/awt/Focus/TypeAhead/TestFocusFreeze.java 8198622,6447537 macosx-all,windows-all,linux-all
@@ -226,7 +228,7 @@
 java/awt/Mixing/AWT_Mixing/JToggleButtonInGlassPaneOverlapping.java 8158801,JBR-5510 windows-all,linux-5.18.2-arch1-1
 java/awt/Mixing/AWT_Mixing/JToggleButtonOverlapping.java 8158801,JBR-5510 windows-all,linux-5.18.2-arch1-1
 java/awt/Mixing/AWT_Mixing/ViewportOverlapping.java 8253184,JBR-5510 windows-all,linux-5.18.2-arch1-1
-java/awt/Mixing/HWDisappear.java 8253184 windows-all
+java/awt/Mixing/HWDisappear.java 8253184,JBR-6818 windows-all,linux-all
 java/awt/Mixing/MixingInHwPanel.java 8253184 windows-all
 java/awt/Mixing/MixingOnDialog.java 8225777 linux-all
 java/awt/Mixing/NonOpaqueInternalFrame.java 7124549 macosx-all
@@ -277,7 +279,6 @@
 java/awt/Toolkit/Headless/HeadlessToolkit.java JBR-6550 macosx-all
 java/awt/Toolkit/LockingKeyStateTest/LockingKeyStateTest.java JBR-5765 macosx-all
 java/awt/Toolkit/ScreenInsetsTest/ScreenInsetsTest.java JBR-5812 linux-all
-java/awt/Toolkit/ScreenInsetsTest/ScreenInsetsTest.java JBR-5812 linux-all
 java/awt/Toolkit/SecurityTest/SecurityTest2.java JBR-5225 windows-all
 java/awt/Toolkit/SunDisplayChangerLeakTest/SunDisplayChangerLeakTest.java JBR-5051 windows-all
 java/awt/Toolkit/RealSync/Test.java 6849383,8072110 linux-all,windows-all
@@ -831,10 +832,22 @@
 
 security/infra/java/security/cert/CertPathValidator/certification/ActalisCA.java  8224768 generic-all
 security/infra/java/security/cert/CertPathValidator/certification/AmazonCA.java 8309088 generic-all
+security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java#actalisauthenticationrootca 8324583 generic-all
+security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java#certignarootca 8324583 generic-all
+security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java#quovadisrootca1g3 8324583 generic-all
 security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java#quovadisrootca3g3 8324583 generic-all
 security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java#digicerttlsrsarootg5 8324583 generic-all
 security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java#digicerttlseccrootg5 8324583 generic-all
+security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java#emsigneccrootcag3 8324583 generic-all
+security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java#emsignrootcag1 8324583 generic-all
+security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java#globalsigneccrootcar4 8324583 generic-all
+security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java#gtsrootcar1 8324583 generic-all
+security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java#gtsrootcar2 8324583 generic-all
+security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java#gtsrootecccar3 8324583 generic-all
+security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java#gtsrootecccar4 8324583 generic-all
 security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java#microsoftecc2017 8324583 generic-all
+security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java#sslrootevrsaca 8324583 generic-all
+security/infra/java/security/cert/CertPathValidator/certification/EmSignRootG2CA.java 8327084 generic-all
 security/infra/java/security/cert/CertPathValidator/certification/GoogleCA.java 8308592 generic-all
 
 sun/security/smartcardio/TestChannel.java                       8039280 generic-all
@@ -917,6 +930,7 @@
 javax/swing/JColorChooser/Test6524757.java JBR-5210 windows-all
 javax/swing/JColorChooser/Test6827032.java JBR-5210 windows-all
 javax/swing/JComboBox/6406264/bug6406264.java JBR-5210 windows-all
+javax/swing/JComboBox/6559152/bug6559152.java 8294067 macosx-all
 javax/swing/JComboBox/bug4890345.java JBR-5799 windows-all
 javax/swing/JComboBox/bug5029504.java JBR-5799 windows-all
 javax/swing/JComponent/6683775/bug6683775.java 8172337 generic-all
@@ -944,6 +958,8 @@
 javax/swing/JPopupMenu/6415145/bug6415145.java 8197552 windows-all
 javax/swing/JPopupMenu/6515446/bug6515446.java 8197552,JBR-6531 windows-all,linux-all
 javax/swing/JPopupMenu/6544309/bug6544309.java JBR-6532 windows-all,linux-all
+javax/swing/JPopupMenu/6987844/bug6987844.java JBR-6718 linux-all,windows-all
+javax/swing/JPopupMenu/8075063/ContextMenuScrollTest.java JBR-6717 linux-all
 javax/swing/JPopupMenu/SetInvokerJPopupMenuTest.java JBR-6021 linux-all
 javax/swing/JRadioButton/8033699/bug8033699.java 8197552 windows-all
 javax/swing/JRadioButton/8075609/bug8075609.java 8197552,8266085,JBR-5510 windows-all,linux-5.18.2-arch1-1
@@ -1194,6 +1210,7 @@
 java/awt/FileDialog/DefaultFocusOwner/DefaultFocusOwner.java 7187728 macosx-all,linux-all
 java/awt/FileDialog/RegexpFilterTest/RegexpFilterTest.html 7187728 macosx-all,linux-all
 java/awt/print/PageFormat/Orient.java 8016055 macosx-all
+java/awt/TextArea/AutoScrollOnSelectAndAppend/AutoScrollOnSelectAndAppend.java JBR-6839 linux-all
 java/awt/TextArea/OverScrollTest/OverScrollTest.java 8253184 windows-all
 java/awt/TextArea/ScrollbarIntersectionTest/ScrollbarIntersectionTest.java 8253184 windows-all
 java/awt/TextArea/TextAreaCaretVisibilityTest/bug7129742.java JBR-5439 linux-all
@@ -1202,12 +1219,10 @@
 java/awt/TextField/OverScrollTest/OverScrollTest.java 8253184 windows-all
 java/awt/TextField/SelectionInvisibleTest/SelectionInvisibleTest.java JBR-6748 linux-x64
 java/awt/event/MouseEvent/SpuriousExitEnter/SpuriousExitEnter.java 8254841 macosx-all
-java/awt/FlowLayout/PreferredLayoutSize.java JBR-6349 linux-all
 java/awt/Focus/AppletInitialFocusTest/AppletInitialFocusTest1.java 8256289,JBR-5359 windows-x64,windows-aarch64
 java/awt/Focus/RequestFocusByCause/RequestFocusByCauseTest.java JBR-6335 linux-all
 java/awt/Focus/RequestOnCompWithNullParent/RequestOnCompWithNullParent1.java JBR-6507 linux-all
 java/awt/Focus/RemoveAfterRequest/RemoveAfterRequest.java JBR-6052 macosx-all,linux-all
-java/awt/Focus/RequestFocusByCause/RequestFocusByCauseTest.java JBR-6335 linux-all
 java/awt/FullScreen/TranslucentWindow/TranslucentWindow.java 8258103,8253184 linux-all,windows-all
 
 java/util/Properties/PropertiesStoreTest.java 8282023 generic-all
@@ -1219,7 +1234,6 @@
 
 # various Windows are created spontaneously during test execution
 
-javax/swing/JComboBox/6559152/bug6559152.java                                       nobug windows-all
 javax/swing/JComboBox/6607130/bug6607130.java                                       nobug windows-all
 
 javax/swing/JComboBox/4199622/bug4199622.java                                       nobug windows-all
@@ -1289,7 +1303,7 @@
 java/awt/event/KeyEvent/KeyCharTest/KeyCharTest.java JBR-4880 windows-all
 java/awt/Frame/LayoutOnMaximizeTest/LayoutOnMaximizeTest.java JBR-4880 windows-all
 java/awt/Frame/MiscUndecorated/UndecoratedInitiallyIconified.java JBR-4880 windows-all
-java/awt/FullScreen/FullscreenWindowProps/FullscreenWindowProps.java JBR-4275,JBR-4880 linux-all,windows-all
+java/awt/FullScreen/FullscreenWindowProps/FullscreenWindowProps.java JBR-4275,JBR-4880,JBR-7108 linux-all,windows-all,macosx-all
 java/awt/FullScreen/SetFSWindow/FSFrame.java 8253184 windows-all
 java/awt/grab/MenuDragEvents/MenuDragEvents.java JBR-4880 windows-all
 java/awt/image/multiresolution/MenuMultiresolutionIconTest.java JBR-4880,8253184,JBR-5510 windows-all,linux-5.18.2-arch1-1
@@ -1393,7 +1407,7 @@
 java/awt/Mixing/AWT_Mixing/JGlassPaneInternalFrameOverlapping.java 8049405 windows-all,linux-all
 java/awt/Mixing/AWT_Mixing/JGlassPaneMoveOverlapping.java JBR-5359,JBR-5510 windows-aarch64,linux-5.18.2-arch1-1
 java/awt/Mixing/AWT_Mixing/JInternalFrameOverlapping.java JBR-5359,JBR-5510 windows-aarch64,linux-5.18.2-arch1-1
-java/awt/Mixing/LWPopupMenu.java JBR-824 linux-all,windows-x64
+java/awt/Mixing/LWPopupMenu.java JBR-824 generic-all
 java/awt/Mixing/OpaqueTest.java JBR-5707 linux-all
 java/awt/Mixing/OverlappingButtons.java JBR-5707 linux-all
 java/awt/Window/BackgroundIsNotUpdated/BackgroundIsNotUpdated.java JBR-5359,JBR-5510 windows-all,linux-5.18.2-arch1-1
diff --git a/test/jdk/jbScale2ProblemList.txt b/test/jdk/jbScale2ProblemList.txt
index 376eaa0..8dd709f 100644
--- a/test/jdk/jbScale2ProblemList.txt
+++ b/test/jdk/jbScale2ProblemList.txt
@@ -48,7 +48,9 @@
 java/awt/Modal/BlockedMouseInputTest3.java JBR-6134 windows-x64
 java/awt/PopupMenu/PopupMenuLocation.java                                           8238720,8288415,JBR-5071 windows-all,macosx-all,linux-all
 java/awt/Window/AlwaysOnTop/AlwaysOnTopEvenOfWindow.java JBR-6686 linux-all
+java/awt/Window/AlwaysOnTop/SyncAlwaysOnTopFieldTest.java JBR-6845 linux-x64
 java/awt/Window/HandleWindowDestroyTest/HandleWindowDestroyTest.java JBR-6540 macosx-all
+java/awt/Window/TopLevelLocation/TopLevelLocation.java JBR-5799 windows-all
 java/awt/Window/WindowSizeDifferentScreens/WindowSizeDifferentScreens.java JBR-5513 linux-all
 javax/swing/JComponent/7154030/bug7154030.java 8297454,JBR-5510,JBR-6134 macosx-all,linux-5.18.2-arch1-1,windows-x64
 javax/swing/JEditorPane/8195095/ImageViewTest.java 8253184,JBR-5510,JBR-6283 windows-all,linux-all,macosx-all
@@ -90,8 +92,10 @@
 
 java/awt/event/ComponentEvent/TextComponentTextEventTest.java JBR-6287 windows-all
 
+jb/java/awt/Focus/FileDialogClosing.java JBR-5799 windows-all
 jb/java/awt/Focus/ModalDialogFromMenuTest.java JBR-5799 windows-all
 jb/java/awt/Focus/ModalDialogOverSiblingTest.java                                   JBR-5716 windows-all
+jb/java/awt/Focus/PopupFromMenuTest.java JBR-5799 windows-all
 jb/java/awt/Focus/PopupIncomingFocusTest.java                                       JBR-2651 generic-all
 jb/java/awt/Focus/RequestFocusInParent.java                                         JBR-5715 windows-all
 jb/java/awt/Focus/SecondLevelPopupTest.java                                         JBR-6090 windows-all
diff --git a/test/jdk/jdk/incubator/vector/Byte128VectorTests.java b/test/jdk/jdk/incubator/vector/Byte128VectorTests.java
index bbd7d83..958d42d 100644
--- a/test/jdk/jdk/incubator/vector/Byte128VectorTests.java
+++ b/test/jdk/jdk/incubator/vector/Byte128VectorTests.java
@@ -24,7 +24,7 @@
 /*
  * @test
  * @modules jdk.incubator.vector
- * @run testng/othervm -ea -esa -Xbatch -XX:-TieredCompilation Byte128VectorTests
+ * @run testng/othervm/timeout=300 -ea -esa -Xbatch -XX:-TieredCompilation Byte128VectorTests
  */
 
 // -- This file was mechanically generated: Do not edit! -- //
diff --git a/test/jdk/jdk/incubator/vector/Byte256VectorTests.java b/test/jdk/jdk/incubator/vector/Byte256VectorTests.java
index 8a119b4..095bb03 100644
--- a/test/jdk/jdk/incubator/vector/Byte256VectorTests.java
+++ b/test/jdk/jdk/incubator/vector/Byte256VectorTests.java
@@ -24,7 +24,7 @@
 /*
  * @test
  * @modules jdk.incubator.vector
- * @run testng/othervm -ea -esa -Xbatch -XX:-TieredCompilation Byte256VectorTests
+ * @run testng/othervm/timeout=300 -ea -esa -Xbatch -XX:-TieredCompilation Byte256VectorTests
  */
 
 // -- This file was mechanically generated: Do not edit! -- //
diff --git a/test/jdk/jdk/incubator/vector/Byte512VectorTests.java b/test/jdk/jdk/incubator/vector/Byte512VectorTests.java
index f46c2d6..543ab8a 100644
--- a/test/jdk/jdk/incubator/vector/Byte512VectorTests.java
+++ b/test/jdk/jdk/incubator/vector/Byte512VectorTests.java
@@ -24,7 +24,7 @@
 /*
  * @test
  * @modules jdk.incubator.vector
- * @run testng/othervm -ea -esa -Xbatch -XX:-TieredCompilation Byte512VectorTests
+ * @run testng/othervm/timeout=300 -ea -esa -Xbatch -XX:-TieredCompilation Byte512VectorTests
  */
 
 // -- This file was mechanically generated: Do not edit! -- //
diff --git a/test/jdk/jdk/incubator/vector/Byte64VectorTests.java b/test/jdk/jdk/incubator/vector/Byte64VectorTests.java
index 9f03f68..b489efe 100644
--- a/test/jdk/jdk/incubator/vector/Byte64VectorTests.java
+++ b/test/jdk/jdk/incubator/vector/Byte64VectorTests.java
@@ -24,7 +24,7 @@
 /*
  * @test
  * @modules jdk.incubator.vector
- * @run testng/othervm -ea -esa -Xbatch -XX:-TieredCompilation Byte64VectorTests
+ * @run testng/othervm/timeout=300 -ea -esa -Xbatch -XX:-TieredCompilation Byte64VectorTests
  */
 
 // -- This file was mechanically generated: Do not edit! -- //
diff --git a/test/jdk/jdk/incubator/vector/ByteMaxVectorTests.java b/test/jdk/jdk/incubator/vector/ByteMaxVectorTests.java
index cba42e0..5872a22 100644
--- a/test/jdk/jdk/incubator/vector/ByteMaxVectorTests.java
+++ b/test/jdk/jdk/incubator/vector/ByteMaxVectorTests.java
@@ -24,7 +24,7 @@
 /*
  * @test
  * @modules jdk.incubator.vector
- * @run testng/othervm -ea -esa -Xbatch -XX:-TieredCompilation ByteMaxVectorTests
+ * @run testng/othervm/timeout=300 -ea -esa -Xbatch -XX:-TieredCompilation ByteMaxVectorTests
  */
 
 // -- This file was mechanically generated: Do not edit! -- //
diff --git a/test/jdk/jdk/incubator/vector/Double128VectorTests.java b/test/jdk/jdk/incubator/vector/Double128VectorTests.java
index 4b71199..b00b0cb 100644
--- a/test/jdk/jdk/incubator/vector/Double128VectorTests.java
+++ b/test/jdk/jdk/incubator/vector/Double128VectorTests.java
@@ -24,7 +24,7 @@
 /*
  * @test
  * @modules jdk.incubator.vector
- * @run testng/othervm -ea -esa -Xbatch -XX:-TieredCompilation Double128VectorTests
+ * @run testng/othervm/timeout=300 -ea -esa -Xbatch -XX:-TieredCompilation Double128VectorTests
  */
 
 // -- This file was mechanically generated: Do not edit! -- //
diff --git a/test/jdk/jdk/incubator/vector/Double256VectorTests.java b/test/jdk/jdk/incubator/vector/Double256VectorTests.java
index d8e2af4..008b4dc 100644
--- a/test/jdk/jdk/incubator/vector/Double256VectorTests.java
+++ b/test/jdk/jdk/incubator/vector/Double256VectorTests.java
@@ -24,7 +24,7 @@
 /*
  * @test
  * @modules jdk.incubator.vector
- * @run testng/othervm -ea -esa -Xbatch -XX:-TieredCompilation Double256VectorTests
+ * @run testng/othervm/timeout=300 -ea -esa -Xbatch -XX:-TieredCompilation Double256VectorTests
  */
 
 // -- This file was mechanically generated: Do not edit! -- //
diff --git a/test/jdk/jdk/incubator/vector/Double512VectorTests.java b/test/jdk/jdk/incubator/vector/Double512VectorTests.java
index ceccafc..ce25f8e 100644
--- a/test/jdk/jdk/incubator/vector/Double512VectorTests.java
+++ b/test/jdk/jdk/incubator/vector/Double512VectorTests.java
@@ -24,7 +24,7 @@
 /*
  * @test
  * @modules jdk.incubator.vector
- * @run testng/othervm -ea -esa -Xbatch -XX:-TieredCompilation Double512VectorTests
+ * @run testng/othervm/timeout=300 -ea -esa -Xbatch -XX:-TieredCompilation Double512VectorTests
  */
 
 // -- This file was mechanically generated: Do not edit! -- //
diff --git a/test/jdk/jdk/incubator/vector/Double64VectorTests.java b/test/jdk/jdk/incubator/vector/Double64VectorTests.java
index e64e45f..c4270d0 100644
--- a/test/jdk/jdk/incubator/vector/Double64VectorTests.java
+++ b/test/jdk/jdk/incubator/vector/Double64VectorTests.java
@@ -24,7 +24,7 @@
 /*
  * @test
  * @modules jdk.incubator.vector
- * @run testng/othervm -ea -esa -Xbatch -XX:-TieredCompilation Double64VectorTests
+ * @run testng/othervm/timeout=300 -ea -esa -Xbatch -XX:-TieredCompilation Double64VectorTests
  */
 
 // -- This file was mechanically generated: Do not edit! -- //
diff --git a/test/jdk/jdk/incubator/vector/DoubleMaxVectorTests.java b/test/jdk/jdk/incubator/vector/DoubleMaxVectorTests.java
index 499f151..df03749 100644
--- a/test/jdk/jdk/incubator/vector/DoubleMaxVectorTests.java
+++ b/test/jdk/jdk/incubator/vector/DoubleMaxVectorTests.java
@@ -24,7 +24,7 @@
 /*
  * @test
  * @modules jdk.incubator.vector
- * @run testng/othervm -ea -esa -Xbatch -XX:-TieredCompilation DoubleMaxVectorTests
+ * @run testng/othervm/timeout=300 -ea -esa -Xbatch -XX:-TieredCompilation DoubleMaxVectorTests
  */
 
 // -- This file was mechanically generated: Do not edit! -- //
diff --git a/test/jdk/jdk/incubator/vector/Float128VectorTests.java b/test/jdk/jdk/incubator/vector/Float128VectorTests.java
index dfec604..ae38b60 100644
--- a/test/jdk/jdk/incubator/vector/Float128VectorTests.java
+++ b/test/jdk/jdk/incubator/vector/Float128VectorTests.java
@@ -24,7 +24,7 @@
 /*
  * @test
  * @modules jdk.incubator.vector
- * @run testng/othervm -ea -esa -Xbatch -XX:-TieredCompilation Float128VectorTests
+ * @run testng/othervm/timeout=300 -ea -esa -Xbatch -XX:-TieredCompilation Float128VectorTests
  */
 
 // -- This file was mechanically generated: Do not edit! -- //
diff --git a/test/jdk/jdk/incubator/vector/Float256VectorTests.java b/test/jdk/jdk/incubator/vector/Float256VectorTests.java
index 75f49d0..be55fa2 100644
--- a/test/jdk/jdk/incubator/vector/Float256VectorTests.java
+++ b/test/jdk/jdk/incubator/vector/Float256VectorTests.java
@@ -24,7 +24,7 @@
 /*
  * @test
  * @modules jdk.incubator.vector
- * @run testng/othervm -ea -esa -Xbatch -XX:-TieredCompilation Float256VectorTests
+ * @run testng/othervm/timeout=300 -ea -esa -Xbatch -XX:-TieredCompilation Float256VectorTests
  */
 
 // -- This file was mechanically generated: Do not edit! -- //
diff --git a/test/jdk/jdk/incubator/vector/Float512VectorTests.java b/test/jdk/jdk/incubator/vector/Float512VectorTests.java
index 24cf585..f1f1b88 100644
--- a/test/jdk/jdk/incubator/vector/Float512VectorTests.java
+++ b/test/jdk/jdk/incubator/vector/Float512VectorTests.java
@@ -24,7 +24,7 @@
 /*
  * @test
  * @modules jdk.incubator.vector
- * @run testng/othervm -ea -esa -Xbatch -XX:-TieredCompilation Float512VectorTests
+ * @run testng/othervm/timeout=300 -ea -esa -Xbatch -XX:-TieredCompilation Float512VectorTests
  */
 
 // -- This file was mechanically generated: Do not edit! -- //
diff --git a/test/jdk/jdk/incubator/vector/Float64VectorTests.java b/test/jdk/jdk/incubator/vector/Float64VectorTests.java
index b15496b..47f0cf3 100644
--- a/test/jdk/jdk/incubator/vector/Float64VectorTests.java
+++ b/test/jdk/jdk/incubator/vector/Float64VectorTests.java
@@ -24,7 +24,7 @@
 /*
  * @test
  * @modules jdk.incubator.vector
- * @run testng/othervm -ea -esa -Xbatch -XX:-TieredCompilation Float64VectorTests
+ * @run testng/othervm/timeout=300 -ea -esa -Xbatch -XX:-TieredCompilation Float64VectorTests
  */
 
 // -- This file was mechanically generated: Do not edit! -- //
diff --git a/test/jdk/jdk/incubator/vector/FloatMaxVectorTests.java b/test/jdk/jdk/incubator/vector/FloatMaxVectorTests.java
index 545f6e4..511afbb 100644
--- a/test/jdk/jdk/incubator/vector/FloatMaxVectorTests.java
+++ b/test/jdk/jdk/incubator/vector/FloatMaxVectorTests.java
@@ -24,7 +24,7 @@
 /*
  * @test
  * @modules jdk.incubator.vector
- * @run testng/othervm -ea -esa -Xbatch -XX:-TieredCompilation FloatMaxVectorTests
+ * @run testng/othervm/timeout=300 -ea -esa -Xbatch -XX:-TieredCompilation FloatMaxVectorTests
  */
 
 // -- This file was mechanically generated: Do not edit! -- //
diff --git a/test/jdk/jdk/incubator/vector/Int128VectorTests.java b/test/jdk/jdk/incubator/vector/Int128VectorTests.java
index 9414df9..49e9f4e 100644
--- a/test/jdk/jdk/incubator/vector/Int128VectorTests.java
+++ b/test/jdk/jdk/incubator/vector/Int128VectorTests.java
@@ -24,7 +24,7 @@
 /*
  * @test
  * @modules jdk.incubator.vector
- * @run testng/othervm -ea -esa -Xbatch -XX:-TieredCompilation Int128VectorTests
+ * @run testng/othervm/timeout=300 -ea -esa -Xbatch -XX:-TieredCompilation Int128VectorTests
  */
 
 // -- This file was mechanically generated: Do not edit! -- //
diff --git a/test/jdk/jdk/incubator/vector/Int256VectorTests.java b/test/jdk/jdk/incubator/vector/Int256VectorTests.java
index e9260e4..570163c 100644
--- a/test/jdk/jdk/incubator/vector/Int256VectorTests.java
+++ b/test/jdk/jdk/incubator/vector/Int256VectorTests.java
@@ -24,7 +24,7 @@
 /*
  * @test
  * @modules jdk.incubator.vector
- * @run testng/othervm -ea -esa -Xbatch -XX:-TieredCompilation Int256VectorTests
+ * @run testng/othervm/timeout=300 -ea -esa -Xbatch -XX:-TieredCompilation Int256VectorTests
  */
 
 // -- This file was mechanically generated: Do not edit! -- //
diff --git a/test/jdk/jdk/incubator/vector/Int512VectorTests.java b/test/jdk/jdk/incubator/vector/Int512VectorTests.java
index c20853e..e462fef 100644
--- a/test/jdk/jdk/incubator/vector/Int512VectorTests.java
+++ b/test/jdk/jdk/incubator/vector/Int512VectorTests.java
@@ -24,7 +24,7 @@
 /*
  * @test
  * @modules jdk.incubator.vector
- * @run testng/othervm -ea -esa -Xbatch -XX:-TieredCompilation Int512VectorTests
+ * @run testng/othervm/timeout=300 -ea -esa -Xbatch -XX:-TieredCompilation Int512VectorTests
  */
 
 // -- This file was mechanically generated: Do not edit! -- //
diff --git a/test/jdk/jdk/incubator/vector/Int64VectorTests.java b/test/jdk/jdk/incubator/vector/Int64VectorTests.java
index 0fdedf3..3bdad69 100644
--- a/test/jdk/jdk/incubator/vector/Int64VectorTests.java
+++ b/test/jdk/jdk/incubator/vector/Int64VectorTests.java
@@ -24,7 +24,7 @@
 /*
  * @test
  * @modules jdk.incubator.vector
- * @run testng/othervm -ea -esa -Xbatch -XX:-TieredCompilation Int64VectorTests
+ * @run testng/othervm/timeout=300 -ea -esa -Xbatch -XX:-TieredCompilation Int64VectorTests
  */
 
 // -- This file was mechanically generated: Do not edit! -- //
diff --git a/test/jdk/jdk/incubator/vector/IntMaxVectorTests.java b/test/jdk/jdk/incubator/vector/IntMaxVectorTests.java
index 74724e2..b4ab5c0 100644
--- a/test/jdk/jdk/incubator/vector/IntMaxVectorTests.java
+++ b/test/jdk/jdk/incubator/vector/IntMaxVectorTests.java
@@ -24,7 +24,7 @@
 /*
  * @test
  * @modules jdk.incubator.vector
- * @run testng/othervm -ea -esa -Xbatch -XX:-TieredCompilation IntMaxVectorTests
+ * @run testng/othervm/timeout=300 -ea -esa -Xbatch -XX:-TieredCompilation IntMaxVectorTests
  */
 
 // -- This file was mechanically generated: Do not edit! -- //
diff --git a/test/jdk/jdk/incubator/vector/Long128VectorTests.java b/test/jdk/jdk/incubator/vector/Long128VectorTests.java
index f5eaa0e..07be948 100644
--- a/test/jdk/jdk/incubator/vector/Long128VectorTests.java
+++ b/test/jdk/jdk/incubator/vector/Long128VectorTests.java
@@ -24,7 +24,7 @@
 /*
  * @test
  * @modules jdk.incubator.vector
- * @run testng/othervm -ea -esa -Xbatch -XX:-TieredCompilation Long128VectorTests
+ * @run testng/othervm/timeout=300 -ea -esa -Xbatch -XX:-TieredCompilation Long128VectorTests
  */
 
 // -- This file was mechanically generated: Do not edit! -- //
diff --git a/test/jdk/jdk/incubator/vector/Long256VectorTests.java b/test/jdk/jdk/incubator/vector/Long256VectorTests.java
index 44f0c4f..f229070 100644
--- a/test/jdk/jdk/incubator/vector/Long256VectorTests.java
+++ b/test/jdk/jdk/incubator/vector/Long256VectorTests.java
@@ -24,7 +24,7 @@
 /*
  * @test
  * @modules jdk.incubator.vector
- * @run testng/othervm -ea -esa -Xbatch -XX:-TieredCompilation Long256VectorTests
+ * @run testng/othervm/timeout=300 -ea -esa -Xbatch -XX:-TieredCompilation Long256VectorTests
  */
 
 // -- This file was mechanically generated: Do not edit! -- //
diff --git a/test/jdk/jdk/incubator/vector/Long512VectorTests.java b/test/jdk/jdk/incubator/vector/Long512VectorTests.java
index bd8d7c0..77e2c79 100644
--- a/test/jdk/jdk/incubator/vector/Long512VectorTests.java
+++ b/test/jdk/jdk/incubator/vector/Long512VectorTests.java
@@ -24,7 +24,7 @@
 /*
  * @test
  * @modules jdk.incubator.vector
- * @run testng/othervm -ea -esa -Xbatch -XX:-TieredCompilation Long512VectorTests
+ * @run testng/othervm/timeout=300 -ea -esa -Xbatch -XX:-TieredCompilation Long512VectorTests
  */
 
 // -- This file was mechanically generated: Do not edit! -- //
diff --git a/test/jdk/jdk/incubator/vector/Long64VectorTests.java b/test/jdk/jdk/incubator/vector/Long64VectorTests.java
index e832ba7..da71833 100644
--- a/test/jdk/jdk/incubator/vector/Long64VectorTests.java
+++ b/test/jdk/jdk/incubator/vector/Long64VectorTests.java
@@ -24,7 +24,7 @@
 /*
  * @test
  * @modules jdk.incubator.vector
- * @run testng/othervm -ea -esa -Xbatch -XX:-TieredCompilation Long64VectorTests
+ * @run testng/othervm/timeout=300 -ea -esa -Xbatch -XX:-TieredCompilation Long64VectorTests
  */
 
 // -- This file was mechanically generated: Do not edit! -- //
diff --git a/test/jdk/jdk/incubator/vector/LongMaxVectorTests.java b/test/jdk/jdk/incubator/vector/LongMaxVectorTests.java
index 89b927c..3d3f1e5 100644
--- a/test/jdk/jdk/incubator/vector/LongMaxVectorTests.java
+++ b/test/jdk/jdk/incubator/vector/LongMaxVectorTests.java
@@ -24,7 +24,7 @@
 /*
  * @test
  * @modules jdk.incubator.vector
- * @run testng/othervm -ea -esa -Xbatch -XX:-TieredCompilation LongMaxVectorTests
+ * @run testng/othervm/timeout=300 -ea -esa -Xbatch -XX:-TieredCompilation LongMaxVectorTests
  */
 
 // -- This file was mechanically generated: Do not edit! -- //
diff --git a/test/jdk/jdk/incubator/vector/Short128VectorTests.java b/test/jdk/jdk/incubator/vector/Short128VectorTests.java
index 79af295..cf53e29 100644
--- a/test/jdk/jdk/incubator/vector/Short128VectorTests.java
+++ b/test/jdk/jdk/incubator/vector/Short128VectorTests.java
@@ -24,7 +24,7 @@
 /*
  * @test
  * @modules jdk.incubator.vector
- * @run testng/othervm -ea -esa -Xbatch -XX:-TieredCompilation Short128VectorTests
+ * @run testng/othervm/timeout=300 -ea -esa -Xbatch -XX:-TieredCompilation Short128VectorTests
  */
 
 // -- This file was mechanically generated: Do not edit! -- //
diff --git a/test/jdk/jdk/incubator/vector/Short256VectorTests.java b/test/jdk/jdk/incubator/vector/Short256VectorTests.java
index 25345de..3c80891 100644
--- a/test/jdk/jdk/incubator/vector/Short256VectorTests.java
+++ b/test/jdk/jdk/incubator/vector/Short256VectorTests.java
@@ -24,7 +24,7 @@
 /*
  * @test
  * @modules jdk.incubator.vector
- * @run testng/othervm -ea -esa -Xbatch -XX:-TieredCompilation Short256VectorTests
+ * @run testng/othervm/timeout=300 -ea -esa -Xbatch -XX:-TieredCompilation Short256VectorTests
  */
 
 // -- This file was mechanically generated: Do not edit! -- //
diff --git a/test/jdk/jdk/incubator/vector/Short512VectorTests.java b/test/jdk/jdk/incubator/vector/Short512VectorTests.java
index 0459845..ac97097 100644
--- a/test/jdk/jdk/incubator/vector/Short512VectorTests.java
+++ b/test/jdk/jdk/incubator/vector/Short512VectorTests.java
@@ -24,7 +24,7 @@
 /*
  * @test
  * @modules jdk.incubator.vector
- * @run testng/othervm -ea -esa -Xbatch -XX:-TieredCompilation Short512VectorTests
+ * @run testng/othervm/timeout=300 -ea -esa -Xbatch -XX:-TieredCompilation Short512VectorTests
  */
 
 // -- This file was mechanically generated: Do not edit! -- //
diff --git a/test/jdk/jdk/incubator/vector/Short64VectorTests.java b/test/jdk/jdk/incubator/vector/Short64VectorTests.java
index cbf84a8..72860e0 100644
--- a/test/jdk/jdk/incubator/vector/Short64VectorTests.java
+++ b/test/jdk/jdk/incubator/vector/Short64VectorTests.java
@@ -24,7 +24,7 @@
 /*
  * @test
  * @modules jdk.incubator.vector
- * @run testng/othervm -ea -esa -Xbatch -XX:-TieredCompilation Short64VectorTests
+ * @run testng/othervm/timeout=300 -ea -esa -Xbatch -XX:-TieredCompilation Short64VectorTests
  */
 
 // -- This file was mechanically generated: Do not edit! -- //
diff --git a/test/jdk/jdk/incubator/vector/ShortMaxVectorTests.java b/test/jdk/jdk/incubator/vector/ShortMaxVectorTests.java
index 64e377b..96ec830 100644
--- a/test/jdk/jdk/incubator/vector/ShortMaxVectorTests.java
+++ b/test/jdk/jdk/incubator/vector/ShortMaxVectorTests.java
@@ -24,7 +24,7 @@
 /*
  * @test
  * @modules jdk.incubator.vector
- * @run testng/othervm -ea -esa -Xbatch -XX:-TieredCompilation ShortMaxVectorTests
+ * @run testng/othervm/timeout=300 -ea -esa -Xbatch -XX:-TieredCompilation ShortMaxVectorTests
  */
 
 // -- This file was mechanically generated: Do not edit! -- //
diff --git a/test/jdk/jdk/incubator/vector/templates/Unit-header.template b/test/jdk/jdk/incubator/vector/templates/Unit-header.template
index fe0303d..3e78d58 100644
--- a/test/jdk/jdk/incubator/vector/templates/Unit-header.template
+++ b/test/jdk/jdk/incubator/vector/templates/Unit-header.template
@@ -24,7 +24,7 @@
 /*
  * @test
  * @modules jdk.incubator.vector
- * @run testng/othervm -ea -esa -Xbatch -XX:-TieredCompilation $vectorteststype$
+ * @run testng/othervm/timeout=300 -ea -esa -Xbatch -XX:-TieredCompilation $vectorteststype$
  */
 
 #warn This file is preprocessed before being compiled
diff --git a/test/jdk/jdk/internal/math/FloatingDecimal/TestFloatingDecimal.java b/test/jdk/jdk/internal/math/FloatingDecimal/TestFloatingDecimal.java
index 5fcb5b5..de245ff 100644
--- a/test/jdk/jdk/internal/math/FloatingDecimal/TestFloatingDecimal.java
+++ b/test/jdk/jdk/internal/math/FloatingDecimal/TestFloatingDecimal.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,12 @@
 import java.util.Random;
 import jdk.internal.math.FloatingDecimal;
 
+import jdk.test.lib.RandomFactory;
+
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
 /*
 OldFloatingDecimalForTest
 
@@ -57,48 +63,35 @@
 /**
  * @test
  * @bug 7032154
- * @summary unit tests of FloatingDecimal
+ * @summary unit tests of FloatingDecimal (use -Dseed=X to set PRANDOM seed)
  * @modules java.base/jdk.internal.math
+ * @library ..
+ * @library /test/lib
  * @library /java/lang/Math
+ * @build jdk.test.lib.RandomFactory
  * @build DoubleConsts FloatConsts
- * @run main TestFloatingDecimal
+ * @run junit TestFloatingDecimal
  * @author Brian Burkhalter
  * @key randomness
  */
 public class TestFloatingDecimal {
-    private static enum ResultType {
-        RESULT_EXCEPTION,
-        RESULT_PRINT
-    }
+    private static final int NUM_RANDOM_TESTS = 100_000;
 
-    private static final ResultType RESULT_TYPE = ResultType.RESULT_PRINT;
-    private static final int NUM_RANDOM_TESTS = 100000;
-
-    private static final Random RANDOM = new Random();
-
-    private static void result(String message) {
-        switch (RESULT_TYPE) {
-            case RESULT_EXCEPTION:
-                throw new RuntimeException(message);
-            case RESULT_PRINT:
-                System.err.println(message);
-                break;
-            default:
-                assert false;
-        }
-    }
+    private static final Random RANDOM = RandomFactory.getRandom();
 
     private static int check(String test, Object expected, Object actual) {
         int failures = 0;
         if(!actual.equals(expected)) {
             failures++;
-            result("Test "+test+" expected "+expected+" but obtained "+actual);
+            System.err.println("Test " + test +
+                               " expected " + expected +
+                               " but obtained " + actual);
         }
         return failures;
     }
 
-    private static int testAppendToDouble() {
-        System.out.println("  testAppendToDouble");
+    @Test
+    public void testAppendToDouble() {
         int failures = 0;
 
         for(int i = 0; i < NUM_RANDOM_TESTS; i++) {
@@ -119,11 +112,11 @@
             }
         }
 
-        return failures;
+        assertEquals(0, failures);
     }
 
-    private static int testAppendToFloat() {
-        System.out.println("  testAppendToFloat");
+    @Test
+    public void testAppendToFloat() {
         int failures = 0;
 
         for(int i = 0; i < NUM_RANDOM_TESTS; i++) {
@@ -144,21 +137,11 @@
             }
         }
 
-        return failures;
+        assertEquals(0, failures);
     }
 
-    private static int testAppendTo() {
-        System.out.println("testAppendTo");
-        int failures = 0;
-
-        failures += testAppendToDouble();
-        failures += testAppendToFloat();
-
-        return failures;
-    }
-
-    private static int testParseDouble() {
-        System.out.println("  testParseDouble");
+    @Test
+    public void testParseDouble() {
         int failures = 0;
 
         for(int i = 0; i < NUM_RANDOM_TESTS; i++) {
@@ -177,11 +160,11 @@
             }
         }
 
-        return failures;
+        assertEquals(0, failures);
     }
 
-    private static int testParseFloat() {
-        System.out.println("  testParseFloat");
+    @Test
+    public void testParseFloat() {
         int failures = 0;
 
         for(int i = 0; i < NUM_RANDOM_TESTS; i++) {
@@ -200,21 +183,11 @@
             }
         }
 
-        return failures;
+        assertEquals(0, failures);
     }
 
-    private static int testParse() {
-        System.out.println("testParse");
-        int failures = 0;
-
-        failures += testParseDouble();
-        failures += testParseFloat();
-
-        return failures;
-    }
-
-    private static int testToJavaFormatStringDoubleFixed() {
-        System.out.println("    testToJavaFormatStringDoubleFixed");
+    @Test
+    public void testToJavaFormatStringDoubleFixed() {
         int failures = 0;
 
         double[] d = new double [] {
@@ -228,11 +201,11 @@
             failures += check("testToJavaFormatStringDoubleFixed", ofd.toJavaFormatString(), FloatingDecimal.toJavaFormatString(d[i]));
         }
 
-        return failures;
+        assertEquals(0, failures);
     }
 
-    private static int testToJavaFormatStringDoubleRandom() {
-        System.out.println("    testToJavaFormatStringDoubleRandom");
+    @Test
+    public void testToJavaFormatStringDoubleRandom() {
         int failures = 0;
 
         for(int i = 0; i < NUM_RANDOM_TESTS; i++) {
@@ -247,19 +220,11 @@
             }
         }
 
-        return failures;
+        assertEquals(0, failures);
     }
 
-    private static int testToJavaFormatStringDouble() {
-        System.out.println("  testToJavaFormatStringDouble");
-        int failures = 0;
-        failures += testToJavaFormatStringDoubleFixed();
-        failures += testToJavaFormatStringDoubleRandom();
-        return failures;
-    }
-
-    private static int testToJavaFormatStringFloatFixed() {
-        System.out.println("    testToJavaFormatStringFloatFixed");
+    @Test
+    public void testToJavaFormatStringFloatFixed() {
         int failures = 0;
 
         float[] f = new float[] {
@@ -273,11 +238,11 @@
             failures += check("testToJavaFormatStringFloatFixed", ofd.toJavaFormatString(), FloatingDecimal.toJavaFormatString(f[i]));
         }
 
-        return failures;
+        assertEquals(0, failures);
     }
 
-    private static int testToJavaFormatStringFloatRandom() {
-        System.out.println("    testToJavaFormatStringFloatRandom");
+    @Test
+    public void testToJavaFormatStringFloatRandom() {
         int failures = 0;
 
         for(int i = 0; i < NUM_RANDOM_TESTS; i++) {
@@ -292,38 +257,6 @@
             }
         }
 
-        return failures;
-    }
-
-    private static int testToJavaFormatStringFloat() {
-        System.out.println("  testToJavaFormatStringFloat");
-        int failures = 0;
-
-        failures += testToJavaFormatStringFloatFixed();
-        failures += testToJavaFormatStringFloatRandom();
-
-        return failures;
-    }
-
-    private static int testToJavaFormatString() {
-        System.out.println("testToJavaFormatString");
-        int failures = 0;
-
-        failures += testToJavaFormatStringDouble();
-        failures += testToJavaFormatStringFloat();
-
-        return failures;
-    }
-
-    public static void main(String[] args) {
-        int failures = 0;
-
-        failures += testAppendTo();
-        failures += testParse();
-        failures += testToJavaFormatString();
-
-        if (failures != 0) {
-            throw new RuntimeException("" + failures + " failures while testing FloatingDecimal");
-        }
+        assertEquals(0, failures);
     }
 }
diff --git a/test/jdk/jdk/internal/platform/docker/MetricsMemoryTester.java b/test/jdk/jdk/internal/platform/docker/MetricsMemoryTester.java
index 08773b3..6307a93 100644
--- a/test/jdk/jdk/internal/platform/docker/MetricsMemoryTester.java
+++ b/test/jdk/jdk/internal/platform/docker/MetricsMemoryTester.java
@@ -72,12 +72,12 @@
         } else {
             long count = Metrics.systemMetrics().getMemoryFailCount();
 
-            // Allocate 512M of data
-            byte[][] bytes = new byte[64][];
+            // Allocate 512M of data in 1M chunks per iteration
+            byte[][] bytes = new byte[64 * 8][];
             boolean atLeastOneAllocationWorked = false;
-            for (int i = 0; i < 64; i++) {
+            for (int i = 0; i < 64 * 8; i++) {
                 try {
-                    bytes[i] = new byte[8 * 1024 * 1024];
+                    bytes[i] = new byte[1024 * 1024];
                     atLeastOneAllocationWorked = true;
                     // Break out as soon as we see an increase in failcount
                     // to avoid getting killed by the OOM killer.
diff --git a/test/jdk/jdk/jfr/event/gc/collection/TestGCCauseWithParallelOld.java b/test/jdk/jdk/jfr/event/gc/collection/TestGCCauseWithParallelOld.java
index 9f1e1db..0715d3c 100644
--- a/test/jdk/jdk/jfr/event/gc/collection/TestGCCauseWithParallelOld.java
+++ b/test/jdk/jdk/jfr/event/gc/collection/TestGCCauseWithParallelOld.java
@@ -39,7 +39,7 @@
         String testID = "ParallelOld";
         String[] vmFlags = {"-XX:+UseParallelGC"};
         String[] gcNames = {GCHelper.gcParallelScavenge, GCHelper.gcParallelOld};
-        String[] gcCauses = {"Allocation Failure", "Ergonomics", "System.gc()"};
+        String[] gcCauses = {"Allocation Failure", "Ergonomics", "System.gc()", "GCLocker Initiated GC"};
         GCGarbageCollectionUtil.test(testID, vmFlags, gcNames, gcCauses);
     }
 }
diff --git a/test/jdk/jdk/jfr/event/gc/collection/TestGCCauseWithSerial.java b/test/jdk/jdk/jfr/event/gc/collection/TestGCCauseWithSerial.java
index 0d1811f..403bd07 100644
--- a/test/jdk/jdk/jfr/event/gc/collection/TestGCCauseWithSerial.java
+++ b/test/jdk/jdk/jfr/event/gc/collection/TestGCCauseWithSerial.java
@@ -39,7 +39,7 @@
         String testID = "Serial";
         String[] vmFlags = {"-XX:+UseSerialGC"};
         String[] gcNames = {GCHelper.gcDefNew, GCHelper.gcSerialOld};
-        String[] gcCauses = {"Allocation Failure", "System.gc()"};
+        String[] gcCauses = {"Allocation Failure", "System.gc()", "GCLocker Initiated GC"};
         GCGarbageCollectionUtil.test(testID, vmFlags, gcNames, gcCauses);
     }
 }
diff --git a/test/jdk/jdk/jfr/event/sampling/TestNative.java b/test/jdk/jdk/jfr/event/sampling/TestNative.java
index 2e8753d..66640c2 100644
--- a/test/jdk/jdk/jfr/event/sampling/TestNative.java
+++ b/test/jdk/jdk/jfr/event/sampling/TestNative.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -48,9 +48,12 @@
 
     static volatile boolean alive = true;
 
+    // Please resist the temptation to speed up the test by decreasing
+    // the period. It is explicity set to 1100 ms to provoke the 1000 ms
+    // threshold in the JVM for os::naked_short_sleep().
     public static void main(String[] args) throws Exception {
         try (RecordingStream rs = new RecordingStream()) {
-            rs.enable(NATIVE_EVENT).withPeriod(Duration.ofMillis(1));
+            rs.enable(NATIVE_EVENT).withPeriod(Duration.ofMillis(1100));
             rs.onEvent(NATIVE_EVENT, e -> {
                 alive = false;
                 rs.close();
diff --git a/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java b/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java
index b5bb698..0ef3737 100644
--- a/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java
+++ b/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -451,6 +451,24 @@
  * @run main/othervm -Djava.security.debug=certpath CAInterop emsigneccrootcag3 CRL
  */
 
+/*
+ * @test id=certainlyrootr1
+ * @bug 8321408
+ * @summary Interoperability tests with Certainly Root R1
+ * @library /test/lib
+ * @build jtreg.SkippedException ValidatePathWithURL CAInterop
+ * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop certainlyrootr1 DEFAULT
+ */
+
+/*
+ * @test id=certainlyroote1
+ * @bug 8321408
+ * @summary Interoperability tests with Certainly Root E1
+ * @library /test/lib
+ * @build jtreg.SkippedException ValidatePathWithURL CAInterop
+ * @run main/othervm -Djava.security.debug=certpath,ocsp CAInterop certainlyroote1 DEFAULT
+ */
+
 /**
  * Collection of certificate validation tests for interoperability with external CAs
  */
@@ -613,6 +631,13 @@
                     new CATestURLs("https://testovg3.emsign.com/RootOVG3.html",
                             "https://testovg3r.emsign.com/RootOVG3MR.html");
 
+            case "certainlyrootr1" ->
+                    new CATestURLs("https://valid.root-r1.certainly.com",
+                            "https://revoked.root-r1.certainly.com");
+            case "certainlyroote1" ->
+                    new CATestURLs("https://valid.root-e1.certainly.com",
+                            "https://revoked.root-e1.certainly.com");
+
             default -> throw new RuntimeException("No test setup found for: " + alias);
         };
     }
diff --git a/test/jdk/sun/java2d/marlin/ClipShapeTest.java b/test/jdk/sun/java2d/marlin/ClipShapeTest.java
index 65de6e7..3bdbd41 100644
--- a/test/jdk/sun/java2d/marlin/ClipShapeTest.java
+++ b/test/jdk/sun/java2d/marlin/ClipShapeTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -52,20 +52,43 @@
 import javax.imageio.ImageWriter;
 import javax.imageio.stream.ImageOutputStream;
 
-/**
- * @test
+/*
+ * @test id=Poly
  * @bug 8191814
- * @summary Verifies that Marlin rendering generates the same
- * images with and without clipping optimization with all possible
- * stroke (cap/join) and/or dashes or fill modes (EO rules)
- * for paths made of either 9 lines, 4 quads, 2 cubics (random)
- * Note: Use the argument -slow to run more intensive tests (too much time)
- *
+ * @summary Runs the test with "-poly" option
  * @run main/othervm/timeout=300 -Dsun.java2d.renderer=sun.java2d.marlin.DMarlinRenderingEngine ClipShapeTest -poly
+ */
+
+/*
+ * @test id=PolyDoDash
+ * @bug 8191814
+ * @summary Runs the test with "-poly -doDash" options
  * @run main/othervm/timeout=300 -Dsun.java2d.renderer=sun.java2d.marlin.DMarlinRenderingEngine ClipShapeTest -poly -doDash
+ */
+
+/*
+ * @test id=Cubic
+ * @bug 8191814
+ * @summary Runs the test with "-cubic" option
  * @run main/othervm/timeout=300 -Dsun.java2d.renderer=sun.java2d.marlin.DMarlinRenderingEngine ClipShapeTest -cubic
+ */
+
+/*
+ * @test id=CubicDoDash
+ * @bug 8191814
+ * @summary Runs the test with "-cubic -doDash" options
  * @run main/othervm/timeout=300 -Dsun.java2d.renderer=sun.java2d.marlin.DMarlinRenderingEngine ClipShapeTest -cubic -doDash
-*/
+ */
+
+/**
+ * Verifies that Marlin rendering generates the same images with and without
+ * clipping optimization with all possible stroke (cap/join) and/or dashes or
+ * fill modes (EO rules) for paths made of either 9 lines, 4 quads, 2 cubics
+ * (random).
+ * <p>
+ * Note: Use the argument {@code -slow} to run more intensive tests (too much
+ * time).
+ */
 public final class ClipShapeTest {
 
     // test options:
diff --git a/test/jdk/sun/jvmstat/monitor/MonitoredVm/MonitorVmStartTerminate.java b/test/jdk/sun/jvmstat/monitor/MonitoredVm/MonitorVmStartTerminate.java
index 3a1c425..114ddaa 100644
--- a/test/jdk/sun/jvmstat/monitor/MonitoredVm/MonitorVmStartTerminate.java
+++ b/test/jdk/sun/jvmstat/monitor/MonitoredVm/MonitorVmStartTerminate.java
@@ -98,6 +98,7 @@
         System.out.println("Waiting for all processes to get started notification");
         listener.started.acquire(PROCESS_COUNT);
 
+        System.out.println("Terminating all processes");
         for (JavaProcess javaProcess : javaProcesses) {
             javaProcess.terminate();
         }
@@ -138,7 +139,7 @@
         }
 
         private void releaseStarted(Set<Integer> ids) {
-            System.out.println("realeaseStarted(" + ids + ")");
+            System.out.println("releaseStarted(" + ids + ")");
             for (Integer id : ids) {
                 releaseStarted(id);
             }
@@ -149,11 +150,12 @@
                 if (hasMainArgs(id, jp.getMainArgsIdentifier())) {
                     // store id for terminated identification
                     jp.setId(id);
-                    System.out.println("RELEASED (id=" + jp.getId() + ", args=" + jp.getMainArgsIdentifier() + ")");
+                    System.out.println("RELEASED started (id=" + jp.getId() + ", args=" + jp.getMainArgsIdentifier() + ")");
                     started.release();
                     return;
                 }
             }
+            System.out.println("releaseStarted: not a test pid: " + id);
         }
 
         private void releaseTerminated(Set<Integer> ids) {
@@ -166,23 +168,44 @@
         private void releaseTerminated(Integer id) {
             for (JavaProcess jp : processes) {
                 if (id.equals(jp.getId())) {
-                    System.out.println("RELEASED (id=" + jp.getId() + ", args=" + jp.getMainArgsIdentifier() + ")");
+                    System.out.println("RELEASED terminated (id=" + jp.getId() + ", args=" + jp.getMainArgsIdentifier() + ")");
                     terminated.release();
                     return;
                 }
             }
         }
 
+        private static final int ARGS_ATTEMPTS = 3;
+
         private boolean hasMainArgs(Integer id, String args) {
+            VmIdentifier vmid = null;
             try {
-                VmIdentifier vmid = new VmIdentifier("//" + id.intValue());
-                MonitoredVm target = host.getMonitoredVm(vmid);
-                String monitoredArgs = MonitoredVmUtil.mainArgs(target);
-                if (monitoredArgs != null && monitoredArgs.contains(args)) {
-                    return true;
+                vmid = new VmIdentifier("//" + id.intValue());
+            } catch (URISyntaxException e) {
+                System.out.println("hasMainArgs(" + id + "): " + e);
+                return false;
+            }
+            // Retry a failing attempt to check arguments for a match,
+            // as not recognizing a test process will cause timeout and failure.
+            for (int i = 0; i < ARGS_ATTEMPTS; i++) {
+                try {
+                    MonitoredVm target = host.getMonitoredVm(vmid);
+                    String monitoredArgs = MonitoredVmUtil.mainArgs(target);
+                    System.out.println("hasMainArgs(" + id + "): has main args: '" + monitoredArgs + "'");
+                    if (monitoredArgs == null || monitoredArgs.equals("Unknown")) {
+                        System.out.println("hasMainArgs(" + id + "): retry" );
+                        takeNap();
+                        continue;
+                    } else if (monitoredArgs.contains(args)) {
+                        return true;
+                    } else {
+                        return false;
+                    }
+                } catch (MonitorException e) {
+                    // Process probably not running or not ours, e.g.
+                    // sun.jvmstat.monitor.MonitorException: Could not attach to PID
+                    System.out.println("hasMainArgs(" + id + "): " + e);
                 }
-            } catch (URISyntaxException | MonitorException e) {
-                // ok. process probably not running
             }
             return false;
         }
@@ -247,14 +270,6 @@
             }
         }
 
-        private static void takeNap() {
-            try {
-                Thread.sleep(100);
-            } catch (InterruptedException e) {
-                // ignore
-            }
-        }
-
         private final String mainArgsIdentifier;
         private final ShutdownHook shutdownHook;
         private volatile Integer id;
@@ -323,4 +338,12 @@
             return mainArgsIdentifier;
         }
     }
+
+    public static void takeNap() {
+        try {
+            Thread.sleep(1000);
+        } catch (InterruptedException e) {
+            // ignore
+        }
+    }
 }
diff --git a/test/jdk/sun/nio/cs/TestCharsetMapping.java b/test/jdk/sun/nio/cs/TestCharsetMapping.java
index 63eeba1..211f951 100644
--- a/test/jdk/sun/nio/cs/TestCharsetMapping.java
+++ b/test/jdk/sun/nio/cs/TestCharsetMapping.java
@@ -22,7 +22,7 @@
  */
 
 /* @test
- * @bug 8186801 8186751
+ * @bug 8186801 8186751 8310631
  * @summary Test the charset mappings
  * @modules jdk.charsets
  */
@@ -569,11 +569,9 @@
 
     public static void main(String args[]) throws Exception {
         Path dir = Paths.get(System.getProperty("test.src", ".") +
-                             "/../../../../make/data/charsetmapping");
+            "/../../../../../make/data/charsetmapping").normalize();
         if (!Files.exists(dir)) {
-            // not inside jdk repo, no mappings, exit silently
-            log.println("Nothing done, not in a jdk repo: ");
-            return;
+            throw new Exception("charsetmapping files cannot be located in " + dir);
         }
         if (args.length > 0 && "-v".equals(args[0])) {
             // For debugging: java CoderTest [-v]
@@ -608,7 +606,8 @@
                            + " vs " + cs.name() + "]");
             }
             // test aliases()
-            if (!cs.aliases().equals(csinfo.aliases)) {
+            if (!cs.aliases().equals(csinfo.aliases)
+                && !csname.equals("GB18030")) {  // no alias in "charsets" file
                 errors++;
                 log.printf("    [error wrong aliases]");
                 if (verbose) {
@@ -625,6 +624,19 @@
             }
 
             if (!csinfo.loadMappings(dir)) {
+                // Ignore these cs, as mapping files are not provided
+                if (csinfo.csName.equals("x-IBM942C") ||
+                        csinfo.csName.equals("x-IBM943C") ||
+                        csinfo.csName.equals("x-IBM834") ||
+                        csinfo.csName.equals("x-IBM949C") ||
+                        csinfo.csName.equals("x-IBM964") ||
+                        csinfo.csName.equals("x-IBM29626C"))
+                {
+                    log.println("    [**** skipped, mapping file is not provided]");
+                    known++;
+                    continue;
+                }
+
                 log.println("    [error loading mappings failed]");
                 errors++;
                 continue;
diff --git a/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java b/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java
index 80e5931..03f3f4f 100644
--- a/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java
+++ b/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,7 @@
  *      8223499 8225392 8232019 8234245 8233223 8225068 8225069 8243321 8243320
  *      8243559 8225072 8258630 8259312 8256421 8225081 8225082 8225083 8245654
  *      8305975 8304760 8307134 8295894 8314960 8317373 8317374 8318759 8319187
+ *      8321408
  * @summary Check root CA entries in cacerts file
  */
 import java.io.ByteArrayInputStream;
@@ -47,12 +48,12 @@
             + File.separator + "security" + File.separator + "cacerts";
 
     // The numbers of certs now.
-    private static final int COUNT = 106;
+    private static final int COUNT = 108;
 
     // SHA-256 of cacerts, can be generated with
     // shasum -a 256 cacerts | sed -e 's/../&:/g' | tr '[:lower:]' '[:upper:]' | cut -c1-95
     private static final String CHECKSUM
-            = "61:5F:6D:C5:9C:A3:8A:65:3F:CB:F9:F5:26:04:23:F4:53:A6:8C:B3:8B:2B:0A:F0:66:7D:9E:67:B9:4D:AC:B7";
+            = "81:D4:84:F6:92:78:A4:82:25:06:DC:42:25:C9:5D:6C:63:E4:99:CE:BC:ED:66:B3:8C:BA:E6:BA:6B:34:0F:01";
 
     // Hex formatter to upper case with ":" delimiter
     private static final HexFormat HEX = HexFormat.ofDelimiter(":").withUpperCase();
@@ -273,6 +274,10 @@
                     "86:A1:EC:BA:08:9C:4A:8D:3B:BE:27:34:C6:12:BA:34:1D:81:3E:04:3C:F9:E8:A8:62:CD:5C:57:A3:6B:BE:6B");
             put("emsignrootcag2 [jdk]",
                     "1A:A0:C2:70:9E:83:1B:D6:E3:B5:12:9A:00:BA:41:F7:EE:EF:02:08:72:F1:E6:50:4B:F0:F6:C3:F2:4F:3A:F3");
+            put("certainlyrootr1 [jdk]",
+                    "77:B8:2C:D8:64:4C:43:05:F7:AC:C5:CB:15:6B:45:67:50:04:03:3D:51:C6:0C:62:02:A8:E0:C3:34:67:D3:A0");
+            put("certainlyroote1 [jdk]",
+                    "B4:58:5F:22:E4:AC:75:6A:4E:86:12:A1:36:1C:5D:9D:03:1A:93:FD:84:FE:BB:77:8F:A3:06:8B:0F:C4:2D:C2");
         }
     };
 
diff --git a/test/jdk/sun/security/pkcs11/Cipher/TestGCMKeyAndIvCheck.java b/test/jdk/sun/security/pkcs11/Cipher/TestGCMKeyAndIvCheck.java
index 2e3a83d..adabcc5 100644
--- a/test/jdk/sun/security/pkcs11/Cipher/TestGCMKeyAndIvCheck.java
+++ b/test/jdk/sun/security/pkcs11/Cipher/TestGCMKeyAndIvCheck.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8080462 8229243
+ * @bug 8080462 8229243 8307185
  * @library /test/lib ..
  * @modules jdk.crypto.cryptoki
  * @run main TestGCMKeyAndIvCheck
diff --git a/test/jdk/sun/security/pkcs11/KeyStore/Basic.java b/test/jdk/sun/security/pkcs11/KeyStore/Basic.java
index 21a081e..b7ae84b 100644
--- a/test/jdk/sun/security/pkcs11/KeyStore/Basic.java
+++ b/test/jdk/sun/security/pkcs11/KeyStore/Basic.java
@@ -58,6 +58,8 @@
 
 import com.sun.security.auth.module.*;
 import com.sun.security.auth.callback.*;
+import jtreg.SkippedException;
+import org.testng.SkipException;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
@@ -113,7 +115,11 @@
     @Test
     public void testBasic() throws Exception {
         String[] args = {"sm", "Basic.policy"};
-        main(new Basic(), args);
+        try {
+            main(new Basic(), args);
+        } catch (SkippedException se) {
+            throw new SkipException("One or more tests are skipped");
+        }
     }
 
     private static class FooEntry implements KeyStore.Entry { }
diff --git a/test/jdk/sun/security/pkcs11/KeyStore/ClientAuth.java b/test/jdk/sun/security/pkcs11/KeyStore/ClientAuth.java
index 5c609b2..259f9ed 100644
--- a/test/jdk/sun/security/pkcs11/KeyStore/ClientAuth.java
+++ b/test/jdk/sun/security/pkcs11/KeyStore/ClientAuth.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,8 @@
  * @run testng/othervm ClientAuth
  */
 
+import jtreg.SkippedException;
+import org.testng.SkipException;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
@@ -119,7 +121,11 @@
     private void runTest(String[] args) throws Exception {
         System.out.println("Running with args: " + Arrays.toString(args));
         parseArguments(args);
-        main(new ClientAuth());
+        try {
+            main(new ClientAuth());
+        } catch (SkippedException se) {
+            throw new SkipException("One or more tests are skipped");
+        }
     }
 
     /*
diff --git a/test/jdk/sun/security/pkcs11/KeyStore/ClientAuthData/cert9.db b/test/jdk/sun/security/pkcs11/KeyStore/ClientAuthData/cert9.db
new file mode 100644
index 0000000..f701c4f
--- /dev/null
+++ b/test/jdk/sun/security/pkcs11/KeyStore/ClientAuthData/cert9.db
Binary files differ
diff --git a/test/jdk/sun/security/pkcs11/KeyStore/ClientAuthData/key4.db b/test/jdk/sun/security/pkcs11/KeyStore/ClientAuthData/key4.db
new file mode 100644
index 0000000..3c48998
--- /dev/null
+++ b/test/jdk/sun/security/pkcs11/KeyStore/ClientAuthData/key4.db
Binary files differ
diff --git a/test/jdk/sun/security/pkcs11/KeyStore/SecretKeysBasic.java b/test/jdk/sun/security/pkcs11/KeyStore/SecretKeysBasic.java
index 741a389..4d87660 100644
--- a/test/jdk/sun/security/pkcs11/KeyStore/SecretKeysBasic.java
+++ b/test/jdk/sun/security/pkcs11/KeyStore/SecretKeysBasic.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,8 @@
  * @library /test/lib ..
  * @run testng/othervm SecretKeysBasic
  */
+import jtreg.SkippedException;
+import org.testng.SkipException;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
@@ -62,7 +64,11 @@
 
     @Test
     public void testBasic() throws Exception {
-        main(new SecretKeysBasic());
+        try {
+            main(new SecretKeysBasic());
+        } catch (SkippedException se) {
+            throw new SkipException("One or more tests are skipped");
+        }
     }
 
     public void main(Provider p) throws Exception {
diff --git a/test/jdk/sun/security/pkcs11/MessageDigest/TestCloning.java b/test/jdk/sun/security/pkcs11/MessageDigest/TestCloning.java
index c37f6d3..5863567 100644
--- a/test/jdk/sun/security/pkcs11/MessageDigest/TestCloning.java
+++ b/test/jdk/sun/security/pkcs11/MessageDigest/TestCloning.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -39,6 +39,8 @@
 import java.util.Random;
 import java.util.List;
 
+import jtreg.SkippedException;
+
 public class TestCloning extends PKCS11Test {
 
     public static void main(String[] args) throws Exception {
@@ -57,15 +59,31 @@
         r.nextBytes(data1);
         r.nextBytes(data2);
         System.out.println("Testing against provider " + p.getName());
+
+        boolean skipTest = true;
+
         for (String alg : ALGS) {
-            System.out.println("Testing " + alg);
+            System.out.println("Digest algo: " + alg);
             MessageDigest md = MessageDigest.getInstance(alg, p);
-            md = testCloning(md, p);
+            try {
+                md = testCloning(md, p);;
+            } catch (CloneNotSupportedException cnse) {
+                // skip test if clone isn't supported
+                System.out.println("=> Clone not supported; skip!");
+                continue;
+            }
+
+            // start testing below
+            skipTest = false;
+
             // repeat the test again after generating digest once
             for (int j = 0; j < 10; j++) {
                 md = testCloning(md, p);
             }
         }
+        if (skipTest) {
+            throw new SkippedException("Test Skipped!");
+        }
     }
 
     private static MessageDigest testCloning(MessageDigest mdObj, Provider p)
@@ -125,4 +143,3 @@
         }
     }
 }
-
diff --git a/test/jdk/sun/security/pkcs11/PKCS11Test.java b/test/jdk/sun/security/pkcs11/PKCS11Test.java
index a9a8a81..9c61ffe 100644
--- a/test/jdk/sun/security/pkcs11/PKCS11Test.java
+++ b/test/jdk/sun/security/pkcs11/PKCS11Test.java
@@ -58,27 +58,37 @@
 import jdk.test.lib.artifacts.Artifact;
 import jdk.test.lib.artifacts.ArtifactResolver;
 import jdk.test.lib.artifacts.ArtifactResolverException;
+import jtreg.SkippedException;
 
 public abstract class PKCS11Test {
 
-    private boolean enableSM = false;
-
     static final Properties props = System.getProperties();
-
     static final String PKCS11 = "PKCS11";
-
     // directory of the test source
     static final String BASE = System.getProperty("test.src", ".");
-
     static final String TEST_CLASSES = System.getProperty("test.classes", ".");
-
     static final char SEP = File.separatorChar;
-
-    private static final String DEFAULT_POLICY =
-            BASE + SEP + ".." + SEP + "policy";
-
     // directory corresponding to BASE in the /closed hierarchy
     static final String CLOSED_BASE;
+    private static final String DEFAULT_POLICY = BASE + SEP + ".." + SEP + "policy";
+    private static final String PKCS11_REL_PATH = "sun/security/pkcs11";
+    private static final char[] HEX_DIGITS = "0123456789abcdef".toCharArray();
+
+    static double nss_version = -1;
+    static ECCState nss_ecc_status = ECCState.Basic;
+
+    // The NSS library we need to search for in getNSSLibDir()
+    // Default is "libsoftokn3.so", listed as "softokn3"
+    // The other is "libnss3.so", listed as "nss3".
+    static String nss_library = "softokn3";
+
+    // NSS versions of each library.  It is simpler to keep nss_version
+    // for quick checking for generic testing than many if-else statements.
+    static double softoken3_version = -1;
+    static double nss3_version = -1;
+    static Provider pkcs11 = newPKCS11Provider();
+    private static String PKCS11_BASE;
+    private static Map<String, String[]> osMap;
 
     static {
         // hack
@@ -93,24 +103,18 @@
         System.setProperty("closed.base", CLOSED_BASE);
     }
 
-    // NSS version info
-    public static enum ECCState { None, Basic, Extended };
-    static double nss_version = -1;
-    static ECCState nss_ecc_status = ECCState.Basic;
+    static {
+        try {
+            PKCS11_BASE = getBase();
+        } catch (Exception e) {
+            // ignore
+        }
+    }
 
-    // The NSS library we need to search for in getNSSLibDir()
-    // Default is "libsoftokn3.so", listed as "softokn3"
-    // The other is "libnss3.so", listed as "nss3".
-    static String nss_library = "softokn3";
-
-    // NSS versions of each library.  It is simplier to keep nss_version
-    // for quick checking for generic testing than many if-else statements.
-    static double softoken3_version = -1;
-    static double nss3_version = -1;
-    static Provider pkcs11 = newPKCS11Provider();
+    private boolean enableSM = false;
 
     public static Provider newPKCS11Provider() {
-        ServiceLoader sl = ServiceLoader.load(java.security.Provider.class);
+        ServiceLoader<Provider> sl = ServiceLoader.load(java.security.Provider.class);
         Iterator<Provider> iter = sl.iterator();
         Provider p = null;
         boolean found = false;
@@ -128,8 +132,8 @@
         // Nothing found through ServiceLoader; fall back to reflection
         if (!found) {
             try {
-                Class clazz = Class.forName("sun.security.pkcs11.SunPKCS11");
-                p = (Provider) clazz.newInstance();
+                Class<?> clazz = Class.forName("sun.security.pkcs11.SunPKCS11");
+                p = (Provider) clazz.getDeclaredConstructor().newInstance();
             } catch (Exception ex) {
                 ex.printStackTrace();
             }
@@ -150,38 +154,6 @@
         return p.configure(config);
     }
 
-    public abstract void main(Provider p) throws Exception;
-
-    protected boolean skipTest(Provider p) {
-        return false;
-    }
-
-    private void premain(Provider p) throws Exception {
-        if (skipTest(p)) {
-            return;
-        }
-
-        // set a security manager and policy before a test case runs,
-        // and disable them after the test case finished
-        try {
-            if (enableSM) {
-                System.setSecurityManager(new SecurityManager());
-            }
-            long start = System.currentTimeMillis();
-            System.out.printf(
-                    "Running test with provider %s (security manager %s) ...%n",
-                        p.getName(), enableSM ? "enabled" : "disabled");
-            main(p);
-            long stop = System.currentTimeMillis();
-            System.out.println("Completed test with provider " + p.getName() +
-                " (" + (stop - start) + " ms).");
-        } finally {
-            if (enableSM) {
-                System.setSecurityManager(null);
-            }
-        }
-    }
-
     public static void main(PKCS11Test test) throws Exception {
         main(test, null);
     }
@@ -206,19 +178,18 @@
         Provider[] oldProviders = Security.getProviders();
         try {
             System.out.println("Beginning test run " + test.getClass().getName() + "...");
-            testDefault(test);
             testNSS(test);
-            testDeimos(test);
+
         } finally {
             // NOTE: Do not place a 'return' in any finally block
             // as it will suppress exceptions and hide test failures.
             Provider[] newProviders = Security.getProviders();
             boolean found = true;
-            // Do not restore providers if nothing changed. This is especailly
+            // Do not restore providers if nothing changed. This is especially
             // useful for ./Provider/Login.sh, where a SecurityManager exists.
             if (oldProviders.length == newProviders.length) {
                 found = false;
-                for (int i = 0; i<oldProviders.length; i++) {
+                for (int i = 0; i < oldProviders.length; i++) {
                     if (oldProviders[i] != newProviders[i]) {
                         found = true;
                         break;
@@ -226,54 +197,16 @@
                 }
             }
             if (found) {
-                for (Provider p: newProviders) {
+                for (Provider p : newProviders) {
                     Security.removeProvider(p.getName());
                 }
-                for (Provider p: oldProviders) {
+                for (Provider p : oldProviders) {
                     Security.addProvider(p);
                 }
             }
         }
     }
 
-    public static void testDeimos(PKCS11Test test) throws Exception {
-        if (new File("/opt/SUNWconn/lib/libpkcs11.so").isFile() == false ||
-            "true".equals(System.getProperty("NO_DEIMOS"))) {
-            return;
-        }
-        String base = getBase();
-        String p11config = base + SEP + "nss" + SEP + "p11-deimos.txt";
-        Provider p = getSunPKCS11(p11config);
-        test.premain(p);
-    }
-
-    public static void testDefault(PKCS11Test test) throws Exception {
-        // run test for default configured PKCS11 providers (if any)
-
-        if ("true".equals(System.getProperty("NO_DEFAULT"))) {
-            return;
-        }
-
-        Provider[] providers = Security.getProviders();
-        for (int i = 0; i < providers.length; i++) {
-            Provider p = providers[i];
-            if (p.getName().startsWith("SunPKCS11-")) {
-                test.premain(p);
-            }
-        }
-    }
-
-    private static String PKCS11_BASE;
-    static {
-        try {
-            PKCS11_BASE = getBase();
-        } catch (Exception e) {
-            // ignore
-        }
-    }
-
-    private final static String PKCS11_REL_PATH = "sun/security/pkcs11";
-
     public static String getBase() throws Exception {
         if (PKCS11_BASE != null) {
             return PKCS11_BASE;
@@ -286,7 +219,7 @@
             }
             cwd = cwd.getParentFile();
             if (cwd == null) {
-                throw new Exception("Test root directory not found");
+                throw new RuntimeException("Test root directory not found");
             }
         }
         PKCS11_BASE = new File(cwd, PKCS11_REL_PATH.replace('/', SEP)).getAbsolutePath();
@@ -318,7 +251,7 @@
         String[] nssLibDirs = getNssLibPaths(osid);
         if (nssLibDirs == null) {
             System.out.println("Warning: unsupported OS: " + osid
-                    + ", please initialize NSS librarys location firstly, skipping test");
+                    + ", please initialize NSS library location, skipping test");
             return null;
         }
         if (nssLibDirs.length == 0) {
@@ -335,7 +268,7 @@
             }
         }
         if (nssLibPath == null) {
-            System.out.println("Warning: can't find NSS librarys on this machine, skipping test");
+            System.out.println("Warning: can't find NSS library on this machine, skipping test");
             return null;
         }
         return nssLibPath;
@@ -348,9 +281,8 @@
         } else if (osName.equals("Mac OS X")) {
             osName = "MacOSX";
         }
-        String osid = osName + "-" + props.getProperty("os.arch") + "-"
+        return osName + "-" + props.getProperty("os.arch") + "-"
                 + props.getProperty("sun.arch.data.model");
-        return osid;
     }
 
     static boolean isBadNSSVersion(Provider p) {
@@ -363,7 +295,7 @@
         return false;
     }
 
-    protected static void safeReload(String lib) throws Exception {
+    protected static void safeReload(String lib) {
         try {
             System.load(lib);
         } catch (UnsatisfiedLinkError e) {
@@ -373,11 +305,9 @@
         }
     }
 
-    static boolean loadNSPR(String libdir) throws Exception {
+    static boolean loadNSPR(String libdir) {
         // load NSS softoken dependencies in advance to avoid resolver issues
-        String dir = libdir.endsWith(File.separator)
-                     ? libdir
-                     : libdir + File.separator;
+        String dir = libdir.endsWith(File.separator) ? libdir : libdir + File.separator;
         safeReload(dir + System.mapLibraryName("nspr4"));
         safeReload(dir + System.mapLibraryName("plc4"));
         safeReload(dir + System.mapLibraryName("plds4"));
@@ -388,7 +318,7 @@
 
     // Check the provider being used is NSS
     public static boolean isNSS(Provider p) {
-        return p.getName().toUpperCase().equals("SUNPKCS11-NSS");
+        return p.getName().equalsIgnoreCase("SUNPKCS11-NSS");
     }
 
     static double getNSSVersion() {
@@ -484,25 +414,25 @@
 
         // the index after whitespace after nssHeader
         int afterheader = s.indexOf("NSS", i) + 4;
-        String version = String.valueOf(s.charAt(afterheader));
+        StringBuilder version = new StringBuilder(String.valueOf(s.charAt(afterheader)));
         for (char c = s.charAt(++afterheader);
-                c == '.' || (c >= '0' && c <= '9');
-                c = s.charAt(++afterheader)) {
-            version += c;
+             c == '.' || (c >= '0' && c <= '9');
+             c = s.charAt(++afterheader)) {
+            version.append(c);
         }
 
         // If a "dot dot" release, strip the extra dots for double parsing
-        String[] dot = version.split("\\.");
+        String[] dot = version.toString().split("\\.");
         if (dot.length > 2) {
-            version = dot[0]+"."+dot[1];
+            version = new StringBuilder(dot[0] + "." + dot[1]);
             for (int j = 2; dot.length > j; j++) {
-                version += dot[j];
+                version.append(dot[j]);
             }
         }
 
         // Convert to double for easier version value checking
         try {
-            nss_version = Double.parseDouble(version);
+            nss_version = Double.parseDouble(version.toString());
         } catch (NumberFormatException e) {
             System.out.println("===== Content start =====");
             System.out.println(s);
@@ -512,7 +442,7 @@
             e.printStackTrace();
         }
 
-        System.out.print("lib" + library + " version = "+version+".  ");
+        System.out.print("library: " + library + ", version: " + version + ".  ");
 
         // Check for ECC
         if (s.indexOf("Basic") > 0) {
@@ -541,13 +471,15 @@
 
     // Run NSS testing on a Provider p configured with test nss config
     public static void testNSS(PKCS11Test test) throws Exception {
+        System.out.println("===> testNSS: Starting test run");
         String nssConfig = getNssConfig();
         if (nssConfig == null) {
-            // issue loading libraries
-            return;
+            throw new SkippedException("testNSS: Problem loading NSS libraries");
         }
+
         Provider p = getSunPKCS11(nssConfig);
         test.premain(p);
+        System.out.println("testNSS: Completed");
     }
 
     public static String getNssConfig() throws Exception {
@@ -556,7 +488,7 @@
             return null;
         }
 
-        if (loadNSPR(libdir) == false) {
+        if (!loadNSPR(libdir)) {
             return null;
         }
 
@@ -594,12 +526,12 @@
 
         if (kcProp == null) {
             throw new RuntimeException(
-            "\"AlgorithmParameters.EC SupportedCurves property\" not found");
+                    "\"AlgorithmParameters.EC SupportedCurves property\" not found");
         }
 
         System.out.println("Finding supported curves using list from SunEC\n");
         index = 0;
-        for (;;) {
+        for (; ; ) {
             // Each set of curve names is enclosed with brackets.
             begin = kcProp.indexOf('[', index);
             end = kcProp.indexOf(']', index);
@@ -616,12 +548,12 @@
             end = kcProp.indexOf(',', begin);
             if (end == -1) {
                 // Only one name in the set.
-                end = index -1;
+                end = index - 1;
             }
 
             curve = kcProp.substring(begin, end);
             getSupportedECParameterSpec(curve, p)
-                .ifPresent(spec -> results.add(spec));
+                    .ifPresent(spec -> results.add(spec));
         }
 
         if (results.size() == 0) {
@@ -632,9 +564,9 @@
     }
 
     static Optional<ECParameterSpec> getSupportedECParameterSpec(String curve,
-            Provider p) throws Exception {
+                                                                 Provider p) throws Exception {
         ECParameterSpec e = getECParameterSpec(p, curve);
-        System.out.print("\t "+ curve + ": ");
+        System.out.print("\t " + curve + ": ");
         try {
             KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", p);
             kpg.initialize(e);
@@ -656,26 +588,13 @@
             throws Exception {
 
         AlgorithmParameters parameters =
-            AlgorithmParameters.getInstance("EC", p);
+                AlgorithmParameters.getInstance("EC", p);
 
         parameters.init(new ECGenParameterSpec(name));
 
         return parameters.getParameterSpec(ECParameterSpec.class);
     }
 
-    // Check support for a curve with a provided Vector of EC support
-    boolean checkSupport(List<ECParameterSpec> supportedEC,
-            ECParameterSpec curve) {
-        for (ECParameterSpec ec: supportedEC) {
-            if (ec.equals(curve)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private static Map<String,String[]> osMap;
-
     // Location of the NSS libraries on each supported platform
     private static Map<String, String[]> getOsMap() {
         if (osMap != null) {
@@ -683,29 +602,27 @@
         }
 
         osMap = new HashMap<>();
-        osMap.put("Linux-i386-32", new String[] {
+        osMap.put("Linux-i386-32", new String[]{
                 "/usr/lib/i386-linux-gnu/",
                 "/usr/lib32/",
-                "/usr/lib/" });
-        osMap.put("Linux-amd64-64", new String[] {
+                "/usr/lib/"});
+        osMap.put("Linux-amd64-64", new String[]{
                 "/usr/lib/x86_64-linux-gnu/",
                 "/usr/lib/x86_64-linux-gnu/nss/",
-                "/usr/lib64/" });
-        osMap.put("Linux-ppc64-64", new String[] { "/usr/lib64/" });
-        osMap.put("Linux-ppc64le-64", new String[] { "/usr/lib64/" });
-        osMap.put("Linux-s390x-64", new String[] { "/usr/lib64/" });
-        osMap.put("Windows-x86-32", new String[] {});
-        osMap.put("Windows-amd64-64", new String[] {});
-        osMap.put("MacOSX-x86_64-64", new String[] {});
-        osMap.put("Linux-arm-32", new String[] {
+                "/usr/lib64/"});
+        osMap.put("Linux-ppc64-64", new String[]{"/usr/lib64/"});
+        osMap.put("Linux-ppc64le-64", new String[]{"/usr/lib64/"});
+        osMap.put("Linux-s390x-64", new String[]{"/usr/lib64/"});
+        osMap.put("Windows-x86-32", new String[]{});
+        osMap.put("Windows-amd64-64", new String[]{});
+        osMap.put("MacOSX-x86_64-64", new String[]{});
+        osMap.put("Linux-arm-32", new String[]{
                 "/usr/lib/arm-linux-gnueabi/nss/",
-                "/usr/lib/arm-linux-gnueabihf/nss/" });
-        // Exclude linux-aarch64 at the moment until the following bug is fixed:
-        // 8296631: NSS tests failing on OL9 linux-aarch64 hosts
-//        osMap.put("Linux-aarch64-64", new String[] {
-//                "/usr/lib/aarch64-linux-gnu/",
-//                "/usr/lib/aarch64-linux-gnu/nss/",
-//                "/usr/lib64/" });
+                "/usr/lib/arm-linux-gnueabihf/nss/"});
+        osMap.put("Linux-aarch64-64", new String[] {
+                "/usr/lib/aarch64-linux-gnu/",
+                "/usr/lib/aarch64-linux-gnu/nss/",
+                "/usr/lib64/" });
         return osMap;
     }
 
@@ -740,11 +657,9 @@
             }
         }
 
-        return nssLibPaths.toArray(new String[nssLibPaths.size()]);
+        return nssLibPaths.toArray(new String[0]);
     }
 
-    private final static char[] hexDigits = "0123456789abcdef".toCharArray();
-
     public static String toString(byte[] b) {
         if (b == null) {
             return "(null)";
@@ -755,8 +670,8 @@
             if (i != 0) {
                 sb.append(':');
             }
-            sb.append(hexDigits[k >>> 4]);
-            sb.append(hexDigits[k & 0xf]);
+            sb.append(HEX_DIGITS[k >>> 4]);
+            sb.append(HEX_DIGITS[k & 0xf]);
         }
         return sb.toString();
     }
@@ -802,20 +717,11 @@
         }
     }
 
-    <T> T[] concat(T[] a, T[] b) {
-        if ((b == null) || (b.length == 0)) {
-            return a;
-        }
-        T[] r = Arrays.copyOf(a, a.length + b.length);
-        System.arraycopy(b, 0, r, a.length, b.length);
-        return r;
-    }
-
     /**
      * Returns supported algorithms of specified type.
      */
     static List<String> getSupportedAlgorithms(String type, String alg,
-            Provider p) {
+                                               Provider p) {
         // prepare a list of supported algorithms
         List<String> algorithms = new ArrayList<>();
         Set<Provider.Service> services = p.getServices();
@@ -830,7 +736,7 @@
 
     static byte[] generateData(int length) {
         byte data[] = new byte[length];
-        for (int i=0; i<data.length; i++) {
+        for (int i = 0; i < data.length; i++) {
             data[i] = (byte) (i % 256);
         }
         return data;
@@ -838,20 +744,20 @@
 
     private static String fetchNssLib(String osId) {
         switch (osId) {
-        case "Windows-x86-32":
-            return fetchNssLib(WINDOWS_X86.class);
+            case "Windows-x86-32":
+                return fetchNssLib(WINDOWS_X86.class);
 
-        case "Windows-amd64-64":
-            return fetchNssLib(WINDOWS_X64.class);
+            case "Windows-amd64-64":
+                return fetchNssLib(WINDOWS_X64.class);
 
-        case "MacOSX-x86_64-64":
-            return fetchNssLib(MACOSX_X64.class);
+            case "MacOSX-x86_64-64":
+                return fetchNssLib(MACOSX_X64.class);
 
-        case "Linux-amd64-64":
-            return fetchNssLib(LINUX_X64.class);
+            case "Linux-amd64-64":
+                return fetchNssLib(LINUX_X64.class);
 
-        default:
-            return null;
+            default:
+                return null;
         }
     }
 
@@ -875,10 +781,60 @@
         return path;
     }
 
+    public abstract void main(Provider p) throws Exception;
+
+    protected boolean skipTest(Provider p) {
+        return false;
+    }
+
+    private void premain(Provider p) throws Exception {
+        if (skipTest(p)) {
+            return;
+        }
+
+        // set a security manager and policy before a test case runs,
+        // and disable them after the test case finished
+        try {
+            if (enableSM) {
+                System.setSecurityManager(new SecurityManager());
+            }
+            long start = System.currentTimeMillis();
+            System.out.printf(
+                    "Running test with provider %s (security manager %s) ...%n",
+                    p.getName(), enableSM ? "enabled" : "disabled");
+            main(p);
+            long stop = System.currentTimeMillis();
+            System.out.println("Completed test with provider " + p.getName() +
+                    " (" + (stop - start) + " ms).");
+        } finally {
+            if (enableSM) {
+                System.setSecurityManager(null);
+            }
+        }
+    }
+
+    // Check support for a curve with a provided Vector of EC support
+    boolean checkSupport(List<ECParameterSpec> supportedEC,
+                         ECParameterSpec curve) {
+        for (ECParameterSpec ec : supportedEC) {
+            if (ec.equals(curve)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    <T> T[] concat(T[] a, T[] b) {
+        if ((b == null) || (b.length == 0)) {
+            return a;
+        }
+        T[] r = Arrays.copyOf(a, a.length + b.length);
+        System.arraycopy(b, 0, r, a.length, b.length);
+        return r;
+    }
+
     protected void setCommonSystemProps() {
         System.setProperty("java.security.debug", "true");
-        System.setProperty("NO_DEIMOS", "true");
-        System.setProperty("NO_DEFAULT", "true");
         System.setProperty("CUSTOM_DB_DIR", TEST_CLASSES);
     }
 
@@ -889,42 +845,57 @@
 
     protected void copyNssCertKeyToClassesDir(Path dbPath) throws IOException {
         Path destinationPath = Path.of(TEST_CLASSES);
-        String keyDbFile = "key3.db";
-        String certDbFile = "cert8.db";
+        String keyDbFile3 = "key3.db";
+        String keyDbFile4 = "key4.db";
+        String certDbFile8 = "cert8.db";
+        String certDbFile9 = "cert9.db";
 
-        Files.copy(dbPath.resolve(certDbFile),
-                destinationPath.resolve(certDbFile),
+        Files.copy(dbPath.resolve(certDbFile8),
+                destinationPath.resolve(certDbFile8),
                 StandardCopyOption.REPLACE_EXISTING);
-        Files.copy(dbPath.resolve(keyDbFile),
-                destinationPath.resolve(keyDbFile),
+        Files.copy(dbPath.resolve(certDbFile9),
+                destinationPath.resolve(certDbFile9),
+                StandardCopyOption.REPLACE_EXISTING);
+        Files.copy(dbPath.resolve(keyDbFile3),
+                destinationPath.resolve(keyDbFile3),
+                StandardCopyOption.REPLACE_EXISTING);
+        Files.copy(dbPath.resolve(keyDbFile4),
+                destinationPath.resolve(keyDbFile4),
                 StandardCopyOption.REPLACE_EXISTING);
     }
 
+    // NSS version info
+    public static enum ECCState {None, Basic, Extended}
+
     @Artifact(
             organization = "jpg.tests.jdk.nsslib",
             name = "nsslib-windows_x64",
             revision = "3.46-VS2017",
             extension = "zip")
-    private static class WINDOWS_X64 { }
+    private static class WINDOWS_X64 {
+    }
 
     @Artifact(
             organization = "jpg.tests.jdk.nsslib",
             name = "nsslib-windows_x86",
             revision = "3.46-VS2017",
             extension = "zip")
-    private static class WINDOWS_X86 { }
+    private static class WINDOWS_X86 {
+    }
 
     @Artifact(
             organization = "jpg.tests.jdk.nsslib",
             name = "nsslib-macosx_x64",
             revision = "3.46",
             extension = "zip")
-    private static class MACOSX_X64 { }
+    private static class MACOSX_X64 {
+    }
 
     @Artifact(
             organization = "jpg.tests.jdk.nsslib",
             name = "nsslib-linux_x64",
             revision = "3.46",
             extension = "zip")
-    private static class LINUX_X64 { }
+    private static class LINUX_X64 {
+    }
 }
diff --git a/test/jdk/sun/security/pkcs11/PSSUtil.java b/test/jdk/sun/security/pkcs11/PSSUtil.java
new file mode 100644
index 0000000..d184880
--- /dev/null
+++ b/test/jdk/sun/security/pkcs11/PSSUtil.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.Provider;
+import java.security.Signature;
+
+public class PSSUtil {
+
+    /**
+     * ALGORITHM name, fixed as RSA for PKCS11
+     */
+    private static final String KEYALG = "RSA";
+    private static final String SIGALG = "RSASSA-PSS";
+
+    public static enum AlgoSupport {
+        NO, MAYBE, YES
+    };
+
+    public static boolean isSignatureSupported(Provider p) {
+        try {
+            Signature.getInstance(SIGALG, p);
+            return true;
+        } catch (NoSuchAlgorithmException e) {
+            System.out.println("Skip testing " + SIGALG +
+                " due to no support");
+            return false;
+        }
+    }
+
+    public static AlgoSupport isHashSupported(Provider p, String... hashAlgs) {
+
+        AlgoSupport status = AlgoSupport.YES;
+        for (String h : hashAlgs) {
+            String sigAlg = (h.startsWith("SHA3-") ?
+                    h : h.replace("-", "")) + "with" + SIGALG;
+            try {
+                Signature.getInstance(sigAlg, p);
+                // Yes, proceed to check next hash algorithm
+                continue;
+            } catch (NoSuchAlgorithmException e) {
+                // continue trying other checks
+            }
+            try {
+                MessageDigest.getInstance(h, p);
+                status = AlgoSupport.MAYBE;
+            } catch (NoSuchAlgorithmException e) {
+                // if not supported as a standalone digest algo, chance of it
+                // being supported by PSS is very very low
+                return AlgoSupport.NO;
+            }
+        }
+        return status;
+    }
+
+    public static KeyPair generateKeys(Provider p, int size)
+            throws NoSuchAlgorithmException {
+        KeyPairGenerator kpg = KeyPairGenerator.getInstance(KEYALG, p);
+        kpg.initialize(size);
+        return kpg.generateKeyPair();
+    }
+}
diff --git a/test/jdk/sun/security/pkcs11/Provider/ConfigQuotedString.java b/test/jdk/sun/security/pkcs11/Provider/ConfigQuotedString.java
index 2434064..a6c2a97 100644
--- a/test/jdk/sun/security/pkcs11/Provider/ConfigQuotedString.java
+++ b/test/jdk/sun/security/pkcs11/Provider/ConfigQuotedString.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,8 @@
  * @run testng/othervm ConfigQuotedString
  */
 
+import jtreg.SkippedException;
+import org.testng.SkipException;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
@@ -44,7 +46,11 @@
 
     @Test
     public void testQuotedString() throws Exception {
-        main(new ConfigQuotedString());
+        try {
+            main(new ConfigQuotedString());
+        } catch (SkippedException se) {
+            throw new SkipException("One or more tests are skipped");
+        }
     }
 
     public void main(Provider p) throws Exception {
diff --git a/test/jdk/sun/security/pkcs11/Provider/Login.java b/test/jdk/sun/security/pkcs11/Provider/Login.java
index 18fd3b9..69ac303 100644
--- a/test/jdk/sun/security/pkcs11/Provider/Login.java
+++ b/test/jdk/sun/security/pkcs11/Provider/Login.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,8 @@
  * @run testng/othervm -Djava.security.manager=allow Login
  */
 
+import jtreg.SkippedException;
+import org.testng.SkipException;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
@@ -55,7 +57,11 @@
     @Test
     public void testLogin() throws Exception {
         String[] args = new String[]{ "sm", "Login.policy"};
-        main(new Login(), args);
+        try {
+            main(new Login(), args);
+        } catch (SkippedException se) {
+            throw new SkipException("One or more tests are skipped");
+        }
     }
 
     public void main(Provider p) throws Exception {
diff --git a/test/jdk/sun/security/pkcs11/Provider/MultipleLogins.sh b/test/jdk/sun/security/pkcs11/Provider/MultipleLogins.sh
index 1e40fcf..4e8da9b 100644
--- a/test/jdk/sun/security/pkcs11/Provider/MultipleLogins.sh
+++ b/test/jdk/sun/security/pkcs11/Provider/MultipleLogins.sh
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -98,6 +98,12 @@
 
 # first make cert/key DBs writable
 
+${CP} ${TESTSRC}${FS}..${FS}nss${FS}db${FS}cert9.db ${TESTCLASSES}
+${CHMOD} +w ${TESTCLASSES}${FS}cert9.db
+
+${CP} ${TESTSRC}${FS}..${FS}nss${FS}db${FS}key4.db ${TESTCLASSES}
+${CHMOD} +w ${TESTCLASSES}${FS}key4.db
+
 ${CP} ${TESTSRC}${FS}..${FS}nss${FS}db${FS}cert8.db ${TESTCLASSES}
 ${CHMOD} +w ${TESTCLASSES}${FS}cert8.db
 
@@ -111,6 +117,7 @@
         --add-modules jdk.crypto.cryptoki \
         --add-exports jdk.crypto.cryptoki/sun.security.pkcs11=ALL-UNNAMED \
         ${TESTSRC}${FS}..${FS}..${FS}..${FS}..${FS}..${FS}lib${FS}jdk${FS}test${FS}lib${FS}artifacts${FS}*.java \
+        ${TESTSRC}${FS}..${FS}..${FS}..${FS}..${FS}..${FS}lib${FS}jtreg${FS}*.java \
         ${TESTSRC}${FS}MultipleLogins.java \
         ${TESTSRC}${FS}..${FS}PKCS11Test.java
 
@@ -119,8 +126,6 @@
         --add-exports jdk.crypto.cryptoki/sun.security.pkcs11=ALL-UNNAMED \
         -DCUSTOM_DB_DIR=${TESTCLASSES} \
         -DCUSTOM_P11_CONFIG=${TESTSRC}${FS}MultipleLogins-nss.txt \
-        -DNO_DEFAULT=true \
-        -DNO_DEIMOS=true \
         -Dtest.src=${TESTSRC} \
         -Dtest.classes=${TESTCLASSES} \
         -Djava.security.debug=${DEBUG}"
diff --git a/test/jdk/sun/security/pkcs11/Secmod/cert9.db b/test/jdk/sun/security/pkcs11/Secmod/cert9.db
index a202bea..b823a79 100644
--- a/test/jdk/sun/security/pkcs11/Secmod/cert9.db
+++ b/test/jdk/sun/security/pkcs11/Secmod/cert9.db
Binary files differ
diff --git a/test/jdk/sun/security/pkcs11/Secmod/key4.db b/test/jdk/sun/security/pkcs11/Secmod/key4.db
index 222adb3..8ddfc4c 100644
--- a/test/jdk/sun/security/pkcs11/Secmod/key4.db
+++ b/test/jdk/sun/security/pkcs11/Secmod/key4.db
Binary files differ
diff --git a/test/jdk/sun/security/pkcs11/Secmod/pkcs11.txt b/test/jdk/sun/security/pkcs11/Secmod/pkcs11.txt
index 60cc1c5..ba339b2 100644
--- a/test/jdk/sun/security/pkcs11/Secmod/pkcs11.txt
+++ b/test/jdk/sun/security/pkcs11/Secmod/pkcs11.txt
@@ -1,4 +1,9 @@
 library=
 name=NSS Internal PKCS #11 Module
-parameters=configdir='sql:./tmpdb' certPrefix='' keyPrefix='' secmod='' flags= updatedir='' updateCertPrefix='' updateKeyPrefix='' updateid='' updateTokenDescription='' 
-NSS=Flags=internal,critical trustOrder=75 cipherOrder=100 slotParams=(1={slotFlags=[RSA,DSA,DH,RC2,RC4,DES,RANDOM,SHA1,MD5,MD2,SSL,TLS,AES,Camellia,SEED,SHA256,SHA512] askpw=any timeout=30})
+parameters=configdir='sql:./tmpdb' certPrefix='' keyPrefix='' secmod='secmod.db' flags= updatedir='' updateCertPrefix='' updateKeyPrefix='' updateid='' updateTokenDescription='' 
+NSS=trustOrder=75 cipherOrder=100 slotParams={0x00000001=[slotFlags=RSA,RC4,RC2,DES,DH,SHA1,MD5,MD2,SSL,TLS,AES,RANDOM askpw=any timeout=30 ] }  Flags=internal,critical
+
+library=libnssckbi.so
+name=Builtin Roots Module
+NSS=trustOrder=100    
+
diff --git a/test/jdk/sun/security/pkcs11/SecmodTest.java b/test/jdk/sun/security/pkcs11/SecmodTest.java
index 6ff6dd2..c1b5e44 100644
--- a/test/jdk/sun/security/pkcs11/SecmodTest.java
+++ b/test/jdk/sun/security/pkcs11/SecmodTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,8 @@
 
 // common infrastructure for Secmod tests
 
+import jtreg.SkippedException;
+
 import java.io.*;
 
 import java.security.Provider;
@@ -34,7 +36,7 @@
     static String DBDIR;
     static char[] password = "test12".toCharArray();
     static String keyAlias = "mykey";
-    static boolean useSqlite = false;
+    static boolean useSqlite = true;
 
     static void useSqlite(boolean b) {
         useSqlite = b;
@@ -43,13 +45,11 @@
     static boolean initSecmod() throws Exception {
         useNSS();
         LIBPATH = getNSSLibDir();
-        if (LIBPATH == null) {
-            return false;
-        }
         // load all the libraries except libnss3 into memory
-        if (loadNSPR(LIBPATH) == false) {
-            return false;
+        if ((LIBPATH == null) || (!loadNSPR(LIBPATH))) {
+            throw new SkippedException("Failed to load NSS libraries");
         }
+
         safeReload(LIBPATH + System.mapLibraryName("softokn3"));
         safeReload(LIBPATH + System.mapLibraryName("nssckbi"));
 
diff --git a/test/jdk/sun/security/pkcs11/SecureRandom/Basic.java b/test/jdk/sun/security/pkcs11/SecureRandom/Basic.java
index 78cd051..a014ae1 100644
--- a/test/jdk/sun/security/pkcs11/SecureRandom/Basic.java
+++ b/test/jdk/sun/security/pkcs11/SecureRandom/Basic.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
diff --git a/test/jdk/sun/security/pkcs11/Signature/KeyAndParamCheckForPSS.java b/test/jdk/sun/security/pkcs11/Signature/KeyAndParamCheckForPSS.java
index f1c0492..adf7a08 100644
--- a/test/jdk/sun/security/pkcs11/Signature/KeyAndParamCheckForPSS.java
+++ b/test/jdk/sun/security/pkcs11/Signature/KeyAndParamCheckForPSS.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,8 @@
 import java.security.interfaces.*;
 import java.security.spec.*;
 
+import jtreg.SkippedException;
+
 /**
  * @test
  * @bug 8080462 8226651 8242332
@@ -35,25 +37,19 @@
  */
 public class KeyAndParamCheckForPSS extends PKCS11Test {
 
-    /**
-     * ALGORITHM name, fixed as RSA for PKCS11
-     */
-    private static final String KEYALG = "RSA";
     private static final String SIGALG = "RSASSA-PSS";
 
     public static void main(String[] args) throws Exception {
         main(new KeyAndParamCheckForPSS(), args);
     }
 
+    private static boolean skipTest = true;
+
     @Override
     public void main(Provider p) throws Exception {
-        Signature sig;
-        try {
-            sig = Signature.getInstance(SIGALG, p);
-        } catch (NoSuchAlgorithmException e) {
-            System.out.println("Skip testing RSASSA-PSS" +
-                " due to no support");
-            return;
+        if (!PSSUtil.isSignatureSupported(p)) {
+            throw new SkippedException("Skip due to no support for " +
+                    SIGALG);
         }
 
         // NOTE: key length >= (digest length + 2) in bytes
@@ -76,27 +72,26 @@
         runTest(p, 1040, "SHA3-512", "SHA3-256");
         runTest(p, 1040, "SHA3-512", "SHA3-384");
         runTest(p, 1040, "SHA3-512", "SHA3-512");
+
+        if (skipTest) {
+            throw new SkippedException("Test Skipped");
+        }
     }
 
-    private void runTest(Provider p, int keySize, String hashAlg,
+    private static void runTest(Provider p, int keySize, String hashAlg,
             String mgfHashAlg) throws Exception {
 
-        // skip further test if this provider does not support hashAlg or
-        // mgfHashAlg
-        try {
-            MessageDigest.getInstance(hashAlg, p);
-            MessageDigest.getInstance(mgfHashAlg, p);
-        } catch (NoSuchAlgorithmException nsae) {
-            System.out.println("No support for " + hashAlg + ", skip");
+        System.out.println("Testing " + hashAlg + " and MGF1" + mgfHashAlg);
+        PSSUtil.AlgoSupport s = PSSUtil.isHashSupported(p, hashAlg, mgfHashAlg);
+        if (s == PSSUtil.AlgoSupport.NO) {
+            System.out.println("=> Skip; no support");
             return;
         }
 
-        System.out.println("Testing [" + keySize + " " + hashAlg + "]");
+        Signature sig = Signature.getInstance(SIGALG, p);
 
         // create a key pair with the supplied size
-        KeyPairGenerator kpg = KeyPairGenerator.getInstance(KEYALG, p);
-        kpg.initialize(keySize);
-        KeyPair kp = kpg.generateKeyPair();
+        KeyPair kp = PSSUtil.generateKeys(p, keySize);
 
         int bigSaltLen = keySize/8 - 14;
         AlgorithmParameterSpec paramsBad = new PSSParameterSpec(hashAlg,
@@ -108,58 +103,71 @@
         PublicKey pub = kp.getPublic();
 
         // test#1 - setParameter then initSign
-        Signature sig = Signature.getInstance("RSASSA-PSS", p);
-        sig.setParameter(paramsBad);
+        sig = Signature.getInstance(SIGALG, p);
         try {
+            sig.setParameter(paramsGood);
+            sig.initSign(priv);
+            // algorithm support confirmed
+            skipTest = false;
+        } catch (Exception ex) {
+            if (s == PSSUtil.AlgoSupport.MAYBE) {
+                // confirmed to be unsupported; skip the rest of the test
+                System.out.println("=> Skip; no PSS support");
+                return;
+            } else {
+                throw new RuntimeException("Unexpected Exception", ex);
+            }
+        }
+
+        sig = Signature.getInstance(SIGALG, p);
+        try {
+            sig.setParameter(paramsBad);
             sig.initSign(priv);
             throw new RuntimeException("Expected IKE not thrown");
         } catch (InvalidKeyException ike) {
-            System.out.println("test#1: got expected IKE");
+            // expected
         }
 
-        sig.setParameter(paramsGood);
-        sig.initSign(priv);
-        System.out.println("test#1: pass");
-
         // test#2 - setParameter then initVerify
-        sig = Signature.getInstance("RSASSA-PSS", p);
-        sig.setParameter(paramsBad);
+        sig = Signature.getInstance(SIGALG, p);
+        sig.setParameter(paramsGood);
+        sig.initVerify(pub);
+
+        sig = Signature.getInstance(SIGALG, p);
         try {
+            sig.setParameter(paramsBad);
             sig.initVerify(pub);
             throw new RuntimeException("Expected IKE not thrown");
         } catch (InvalidKeyException ike) {
-            System.out.println("test#2: got expected IKE");
+            // expected
         }
 
-        sig.setParameter(paramsGood);
-        sig.initVerify(pub);
-
-        System.out.println("test#2: pass");
-
         // test#3 - initSign, then setParameter
-        sig = Signature.getInstance("RSASSA-PSS", p);
+        sig = Signature.getInstance(SIGALG, p);
         sig.initSign(priv);
+        sig.setParameter(paramsGood);
+
+        sig = Signature.getInstance(SIGALG, p);
         try {
+            sig.initSign(priv);
             sig.setParameter(paramsBad);
             throw new RuntimeException("Expected IAPE not thrown");
         } catch (InvalidAlgorithmParameterException iape) {
-            System.out.println("test#3: got expected IAPE");
+            // expected
         }
 
-        sig.setParameter(paramsGood);
-        System.out.println("test#3: pass");
-
         // test#4 - initVerify, then setParameter
-        sig = Signature.getInstance("RSASSA-PSS", p);
+        sig = Signature.getInstance(SIGALG, p);
+        sig.setParameter(paramsGood);
         sig.initVerify(pub);
+
+        sig = Signature.getInstance(SIGALG, p);
         try {
+            sig.initVerify(pub);
             sig.setParameter(paramsBad);
             throw new RuntimeException("Expected IAPE not thrown");
         } catch (InvalidAlgorithmParameterException iape) {
-            System.out.println("test#4: got expected IAPE");
+            // expected
         }
-
-        sig.setParameter(paramsGood);
-        System.out.println("test#4: pass");
     }
 }
diff --git a/test/jdk/sun/security/pkcs11/Signature/SignatureTestPSS.java b/test/jdk/sun/security/pkcs11/Signature/SignatureTestPSS.java
index 4c1f728..c87554a 100644
--- a/test/jdk/sun/security/pkcs11/Signature/SignatureTestPSS.java
+++ b/test/jdk/sun/security/pkcs11/Signature/SignatureTestPSS.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
 import java.security.interfaces.*;
 import java.security.spec.*;
 import java.util.stream.IntStream;
+import jtreg.SkippedException;
 
 /**
  * @test
@@ -35,8 +36,6 @@
  */
 public class SignatureTestPSS extends PKCS11Test {
 
-    // PKCS11 does not support RSASSA-PSS keys yet
-    private static final String KEYALG = "RSA";
     private static final String SIGALG = "RSASSA-PSS";
 
     private static final int[] KEYSIZES = { 2048, 3072 };
@@ -44,7 +43,7 @@
             "SHA-224", "SHA-256", "SHA-384" , "SHA-512",
             "SHA3-224", "SHA3-256", "SHA3-384" , "SHA3-512",
     };
-    private Provider prov;
+    private static final byte[] DATA = generateData(100);
 
     /**
      * How much times signature updated.
@@ -56,88 +55,72 @@
      */
     private static final int UPDATE_TIMES_HUNDRED = 100;
 
+    private static boolean skipTest = true;
+
     public static void main(String[] args) throws Exception {
         main(new SignatureTestPSS(), args);
     }
 
     @Override
     public void main(Provider p) throws Exception {
-        Signature sig;
-        try {
-            sig = Signature.getInstance(SIGALG, p);
-        } catch (NoSuchAlgorithmException e) {
-            System.out.println("Skip testing RSASSA-PSS" +
-                " due to no support");
-            return;
+        if (!PSSUtil.isSignatureSupported(p)) {
+            throw new SkippedException("Skip due to no support for " + SIGALG);
         }
-        this.prov = p;
-        for (int i : KEYSIZES) {
-            runTest(i);
-        }
-    }
 
-    private void runTest(int keySize) throws Exception {
-        byte[] data = new byte[100];
-        IntStream.range(0, data.length).forEach(j -> {
-            data[j] = (byte) j;
-        });
-        System.out.println("[KEYSIZE = " + keySize + "]");
-
-        // create a key pair
-        KeyPair kpair = generateKeys(KEYALG, keySize);
-        test(DIGESTS, kpair.getPrivate(), kpair.getPublic(), data);
-    }
-
-    private void test(String[] digestAlgs, PrivateKey privKey,
-            PublicKey pubKey, byte[] data) throws RuntimeException {
-        // For signature algorithm, create and verify a signature
-        for (String hash : digestAlgs) {
-            for (String mgfHash : digestAlgs) {
-                try {
-                    checkSignature(data, pubKey, privKey, hash, mgfHash);
-                } catch (NoSuchAlgorithmException | InvalidKeyException |
-                         SignatureException | NoSuchProviderException ex) {
-                    throw new RuntimeException(ex);
-                } catch (InvalidAlgorithmParameterException ex2) {
-                    System.out.println("Skip test due to " + ex2);
+        for (int kSize : KEYSIZES) {
+            System.out.println("[KEYSIZE = " + kSize + "]");
+            KeyPair kp = PSSUtil.generateKeys(p, kSize);
+            PrivateKey privKey = kp.getPrivate();
+            PublicKey pubKey = kp.getPublic();
+            for (String hash : DIGESTS) {
+                for (String mgfHash : DIGESTS) {
+                    System.out.println("    [Hash  = " + hash +
+                            ", MGF1 Hash = " + mgfHash + "]");
+                    PSSUtil.AlgoSupport s =
+                            PSSUtil.isHashSupported(p, hash, mgfHash);
+                    if (s == PSSUtil.AlgoSupport.NO) {
+                        System.out.println("    => Skip; no support");
+                        continue;
+                    }
+                    checkSignature(p, DATA, pubKey, privKey, hash, mgfHash, s);
                 }
-            }
-        };
+            };
+        }
+
+        // start testing below
+        if (skipTest) {
+            throw new SkippedException("Test Skipped");
+        }
     }
 
-    private KeyPair generateKeys(String keyalg, int size)
-            throws NoSuchAlgorithmException {
-        KeyPairGenerator kpg = KeyPairGenerator.getInstance(keyalg, prov);
-        kpg.initialize(size);
-        return kpg.generateKeyPair();
-    }
-
-    private void checkSignature(byte[] data, PublicKey pub,
-            PrivateKey priv, String hash, String mgfHash)
+    private static void checkSignature(Provider p, byte[] data, PublicKey pub,
+            PrivateKey priv, String hash, String mgfHash, PSSUtil.AlgoSupport s)
             throws NoSuchAlgorithmException, InvalidKeyException,
             SignatureException, NoSuchProviderException,
             InvalidAlgorithmParameterException {
 
-        String testName = hash + " and MGF1_" + mgfHash;
         // only test RSASSA-PSS signature against the supplied hash/mgfHash
         // if they are supported; otherwise PKCS11 library will throw
         // CKR_MECHANISM_PARAM_INVALID at Signature.initXXX calls
-        try {
-            MessageDigest md = MessageDigest.getInstance(hash, prov);
-            if (!hash.equalsIgnoreCase(mgfHash)) {
-                md = MessageDigest.getInstance(mgfHash, prov);
-            }
-        } catch (NoSuchAlgorithmException nsae) {
-            System.out.println("Skip testing " + hash + "/" + mgfHash);
-            return;
-        }
-
-        System.out.println("Testing against " + testName);
-        Signature sig = Signature.getInstance(SIGALG, prov);
+        Signature sig = Signature.getInstance(SIGALG, p);
         AlgorithmParameterSpec params = new PSSParameterSpec(
-            hash, "MGF1", new MGF1ParameterSpec(mgfHash), 0, 1);
-        sig.setParameter(params);
+                hash, "MGF1", new MGF1ParameterSpec(mgfHash), 0, 1);
         sig.initSign(priv);
+
+        try {
+            sig.setParameter(params);
+        } catch (InvalidAlgorithmParameterException iape) {
+            if (s == PSSUtil.AlgoSupport.MAYBE) {
+                // confirmed to be unsupported; skip the rest of the test
+                System.out.println("    => Skip; no PSS support");
+                return;
+            } else {
+                throw new RuntimeException("Unexpected Exception", iape);
+            }
+        }
+        // start testing below
+        skipTest = false;
+
         for (int i = 0; i < UPDATE_TIMES_HUNDRED; i++) {
             sig.update(data);
         }
@@ -163,5 +146,6 @@
         if (sig.verify(signedData)) {
             throw new RuntimeException("Failed to detect bad signature");
         }
+        System.out.println("    => Passed");
     }
 }
diff --git a/test/jdk/sun/security/pkcs11/nss/p11-deimos.txt b/test/jdk/sun/security/pkcs11/nss/p11-deimos.txt
deleted file mode 100644
index 8139300..0000000
--- a/test/jdk/sun/security/pkcs11/nss/p11-deimos.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-#
-#
-#
-# Configuration to run unit tests with the Deimos (SCA1000) software
-#
-
-name = Deimos
-
-#showInfo = true
-
-library = /opt/SUNWconn/lib/libpkcs11.so
-
-attributes = compatibility
-
diff --git a/test/jdk/sun/security/pkcs11/rsa/TestP11KeyFactoryGetRSAKeySpec.java b/test/jdk/sun/security/pkcs11/rsa/TestP11KeyFactoryGetRSAKeySpec.java
index 07f07f7..2d8ab35 100644
--- a/test/jdk/sun/security/pkcs11/rsa/TestP11KeyFactoryGetRSAKeySpec.java
+++ b/test/jdk/sun/security/pkcs11/rsa/TestP11KeyFactoryGetRSAKeySpec.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2021, Amazon.com, Inc. or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -39,7 +39,7 @@
  * @library /test/lib ..
  * @run main/othervm TestP11KeyFactoryGetRSAKeySpec
  * @run main/othervm -Djava.security.manager=allow TestP11KeyFactoryGetRSAKeySpec sm rsakeys.ks.policy
- * @run main/othervm -DCUSTOM_P11_CONFIG_NAME=p11-nss-sensitive.txt -DNO_DEIMOS=true -DNO_DEFAULT=true TestP11KeyFactoryGetRSAKeySpec
+ * @run main/othervm -DCUSTOM_P11_CONFIG_NAME=p11-nss-sensitive.txt TestP11KeyFactoryGetRSAKeySpec
  * @modules jdk.crypto.cryptoki
  */
 
diff --git a/test/jdk/sun/security/pkcs11/tls/tls12/cert9.db b/test/jdk/sun/security/pkcs11/tls/tls12/cert9.db
new file mode 100644
index 0000000..57acfb4
--- /dev/null
+++ b/test/jdk/sun/security/pkcs11/tls/tls12/cert9.db
Binary files differ
diff --git a/test/jdk/sun/security/pkcs11/tls/tls12/key4.db b/test/jdk/sun/security/pkcs11/tls/tls12/key4.db
new file mode 100644
index 0000000..c68eaf0
--- /dev/null
+++ b/test/jdk/sun/security/pkcs11/tls/tls12/key4.db
Binary files differ
diff --git a/test/jdk/sun/security/pkcs11/tls/tls12/pkcs11.txt b/test/jdk/sun/security/pkcs11/tls/tls12/pkcs11.txt
new file mode 100644
index 0000000..992c58c
--- /dev/null
+++ b/test/jdk/sun/security/pkcs11/tls/tls12/pkcs11.txt
@@ -0,0 +1,9 @@
+library=
+name=NSS Internal PKCS #11 Module
+parameters=configdir='sql:./tmpdb' certPrefix='' keyPrefix='' secmod='secmod.db' flags= updatedir='' updateCertPrefix='' updateKeyPrefix='' updateid='' updateTokenDescription='' 
+NSS=trustOrder=75 cipherOrder=100 slotParams={0x00000001=[slotFlags=RSA,RC4,RC2,DES,DH,SHA1,MD5,MD2,SSL,TLS,AES,RANDOM askpw=any timeout=30 ] }  Flags=internal,critical,FIPS
+
+library=libnssckbi.so
+name=Builtin Roots Module
+NSS=trustOrder=100    
+
diff --git a/test/jdk/sun/security/rsa/SignedObjectChain.java b/test/jdk/sun/security/rsa/SignedObjectChain.java
index 885dc6c..5a4bb47 100644
--- a/test/jdk/sun/security/rsa/SignedObjectChain.java
+++ b/test/jdk/sun/security/rsa/SignedObjectChain.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -21,6 +21,8 @@
  * questions.
  */
 
+import java.util.Arrays;
+
 /*
  * @test
  * @bug 8050374 8146293
@@ -31,7 +33,6 @@
  * @summary Verify a chain of signed objects
  */
 public class SignedObjectChain {
-
     private static class Test extends Chain.Test {
 
         public Test(Chain.SigAlg sigAlg) {
@@ -52,10 +53,9 @@
     };
 
     public static void main(String argv[]) {
-        boolean resutl = java.util.Arrays.stream(tests).allMatch(
-                (test) -> Chain.runTest(test));
+        boolean result = Arrays.stream(tests).parallel().allMatch(Chain::runTest);
 
-        if(resutl) {
+        if (result) {
             System.out.println("All tests passed");
         } else {
             throw new RuntimeException("Some tests failed");
diff --git a/test/jdk/sun/security/ssl/SSLSocketImpl/BlockedAsyncClose.java b/test/jdk/sun/security/ssl/SSLSocketImpl/BlockedAsyncClose.java
index c350b5c..dad21e9 100644
--- a/test/jdk/sun/security/ssl/SSLSocketImpl/BlockedAsyncClose.java
+++ b/test/jdk/sun/security/ssl/SSLSocketImpl/BlockedAsyncClose.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,7 +29,8 @@
 /*
  * @test
  * @bug 8224829
- * @summary AsyncSSLSocketClose.java has timing issue
+ * @summary AsyncSSLSocketClose.java has timing issue.
+ * @library /javax/net/ssl/templates
  * @run main/othervm BlockedAsyncClose
  */
 
@@ -38,52 +39,41 @@
 import java.net.SocketException;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
+import java.util.Arrays;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
 
-public class BlockedAsyncClose implements Runnable {
+/*
+ * To manually verify that the write thread was blocked when socket.close() is called,
+ * run the test with -Djavax.net.debug=ssl. You should see the message
+ * "SSLSocket output duplex close failed: SO_LINGER timeout, close_notify message cannot be sent."
+ */
+public class BlockedAsyncClose extends SSLContextTemplate implements Runnable {
     SSLSocket socket;
     SSLServerSocket ss;
 
     // Is the socket ready to close?
     private final CountDownLatch closeCondition = new CountDownLatch(1);
-
-    // Where do we find the keystores?
-    static String pathToStores = "../../../../javax/net/ssl/etc";
-    static String keyStoreFile = "keystore";
-    static String trustStoreFile = "truststore";
-    static String passwd = "passphrase";
+    private final Lock writeLock = new ReentrantLock();
 
     public static void main(String[] args) throws Exception {
-        String keyFilename =
-            System.getProperty("test.src", "./") + "/" + pathToStores +
-                "/" + keyStoreFile;
-        String trustFilename =
-            System.getProperty("test.src", "./") + "/" + pathToStores +
-                "/" + trustStoreFile;
-
-        System.setProperty("javax.net.ssl.keyStore", keyFilename);
-        System.setProperty("javax.net.ssl.keyStorePassword", passwd);
-        System.setProperty("javax.net.ssl.trustStore", trustFilename);
-        System.setProperty("javax.net.ssl.trustStorePassword", passwd);
-
-        new BlockedAsyncClose();
+        new BlockedAsyncClose().runTest();
     }
 
-    public BlockedAsyncClose() throws Exception {
-        SSLServerSocketFactory sslssf =
-                (SSLServerSocketFactory)SSLServerSocketFactory.getDefault();
+    public void runTest() throws Exception {
+        SSLServerSocketFactory sslssf = createServerSSLContext().getServerSocketFactory();
         InetAddress loopback = InetAddress.getLoopbackAddress();
         ss = (SSLServerSocket)sslssf.createServerSocket();
         ss.bind(new InetSocketAddress(loopback, 0));
 
-        SSLSocketFactory sslsf =
-            (SSLSocketFactory)SSLSocketFactory.getDefault();
+        SSLSocketFactory sslsf = createClientSSLContext().getSocketFactory();
         socket = (SSLSocket)sslsf.createSocket(loopback, ss.getLocalPort());
         SSLSocket serverSoc = (SSLSocket)ss.accept();
         ss.close();
 
-        (new Thread(this)).start();
+        new Thread(this).start();
         serverSoc.startHandshake();
 
         boolean closeIsReady = closeCondition.await(90L, TimeUnit.SECONDS);
@@ -94,23 +84,22 @@
         }
 
         socket.setSoLinger(true, 10);
-        System.out.println("Calling Socket.close");
 
-        // Sleep for a while so that the write thread blocks by hitting the
-        // output stream buffer limit.
-        Thread.sleep(1000);
+        // if the writeLock is not released by the other thread within 10
+        // seconds it is probably blocked, and we can try to close the socket
+        while (writeLock.tryLock(10, TimeUnit.SECONDS)) {
+            writeLock.unlock();
+        }
 
+        System.out.println("Calling socket.close()");
         socket.close();
-        System.out.println("ssl socket get closed");
         System.out.flush();
     }
 
     // block in write
     public void run() {
         byte[] ba = new byte[1024];
-        for (int i = 0; i < ba.length; i++) {
-            ba[i] = 0x7A;
-        }
+        Arrays.fill(ba, (byte) 0x7A);
 
         try {
             OutputStream os = socket.getOutputStream();
@@ -128,8 +117,16 @@
             // write more
             while (true) {
                 count += ba.length;
+
                 System.out.println(count + " bytes to be written");
+
+                writeLock.lock();
                 os.write(ba);
+                // This isn't in a try/finally. If an exception is thrown
+                // and the lock is released, the main thread will
+                // loop until the test times out. So don't release it.
+                writeLock.unlock();
+
                 System.out.println(count + " bytes written");
             }
         } catch (SocketException se) {
@@ -144,4 +141,3 @@
         }
     }
 }
-
diff --git a/test/jdk/sun/security/tools/jarsigner/compatibility/Compatibility.java b/test/jdk/sun/security/tools/jarsigner/compatibility/Compatibility.java
index 8e14ec6..b01ad90 100644
--- a/test/jdk/sun/security/tools/jarsigner/compatibility/Compatibility.java
+++ b/test/jdk/sun/security/tools/jarsigner/compatibility/Compatibility.java
@@ -1026,7 +1026,7 @@
         cmd[3] = JdkUtils.class.getName();
         cmd[4] = method;
         System.arraycopy(args, 0, cmd, 5, args.length);
-        return ProcessTools.executeCommand(cmd).getOutput();
+        return ProcessTools.executeCommand(cmd).getStdout();
     }
 
     // Executes the specified JDK tools, such as keytool and jarsigner, and
diff --git a/test/jdk/sun/security/tools/keytool/PKCS12Passwd.java b/test/jdk/sun/security/tools/keytool/PKCS12Passwd.java
index e5a60b5..9f381cf 100644
--- a/test/jdk/sun/security/tools/keytool/PKCS12Passwd.java
+++ b/test/jdk/sun/security/tools/keytool/PKCS12Passwd.java
@@ -108,7 +108,7 @@
 
         check("p12", "newpass", "newpass");
 
-        // Conversely, a JKS keystore can be laoded as a PKCS12, and it follows
+        // Conversely, a JKS keystore can be loaded as a PKCS12, and it follows
         // PKCS12 rules that both passwords are changed at the same time and
         // some commands are rejected.
 
diff --git a/test/jdk/sun/security/util/RegisteredDomain/tests.dat b/test/jdk/sun/security/util/RegisteredDomain/tests.dat
index 8d8ba34..280e66f 100644
--- a/test/jdk/sun/security/util/RegisteredDomain/tests.dat
+++ b/test/jdk/sun/security/util/RegisteredDomain/tests.dat
@@ -152,6 +152,10 @@
 s.pvt.k12.ma.us         pvt.k12.ma.us   s.pvt.k12.ma.us
 w.s.pvt.k12.ma.us       pvt.k12.ma.us   s.pvt.k12.ma.us
 
+# vn
+site.com.vn             com.vn          site.com.vn
+site.ai.vn              ai.vn           site.ai.vn
+
 # السعودية
 السعودية                السعودية        null
 foo.السعودية            السعودية        foo.السعودية
diff --git a/test/jdk/sun/security/x509/X509CRLImpl/UnexpectedNPE.java b/test/jdk/sun/security/x509/X509CRLImpl/UnexpectedNPE.java
index 8c14c48..fb85353 100644
--- a/test/jdk/sun/security/x509/X509CRLImpl/UnexpectedNPE.java
+++ b/test/jdk/sun/security/x509/X509CRLImpl/UnexpectedNPE.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,56 +23,43 @@
 
 /*
  * @test
- * @bug 5052433
- * @summary NullPointerException for generateCRL and generateCRLs methods.
+ * @bug 5052433 8315042
+ * @summary Verify that generateCRL and generateCRLs methods do not throw
+ *          NullPointerException. They should throw CRLException instead.
+ * @library /test/lib
  */
 import java.security.NoSuchProviderException;
 import java.security.cert.*;
 import java.io.ByteArrayInputStream;
+import java.util.Base64;
+
+import jdk.test.lib.Utils;
 
 public class UnexpectedNPE {
-    CertificateFactory cf = null ;
+    static CertificateFactory cf = null;
 
-    public UnexpectedNPE() {}
-
-    public static void main( String[] av ) {
+    public static void main(String[] av ) throws CertificateException,
+            NoSuchProviderException {
         byte[] encoded_1 = { 0x00, 0x00, 0x00, 0x00 };
         byte[] encoded_2 = { 0x30, 0x01, 0x00, 0x00 };
         byte[] encoded_3 = { 0x30, 0x01, 0x00 };
+        byte[] encoded_4 = Base64.getDecoder().decode(
+                "MAsGCSqGSMP7TQEHAjI1Bgn///////8wCwUyAQ==");
 
-        UnexpectedNPE unpe = new UnexpectedNPE() ;
+        cf = CertificateFactory.getInstance("X.509", "SUN");
 
-        if(!unpe.run(encoded_1)) {
-            throw new SecurityException("CRLException has not been thrown");
-        }
-
-        if(!unpe.run(encoded_2)) {
-            throw new SecurityException("CRLException has not been thrown");
-        }
-
-        if(!unpe.run(encoded_2)) {
-            throw new SecurityException("CRLException has not been thrown");
-        }
+        run(encoded_1);
+        run(encoded_2);
+        run(encoded_3);
+        run(encoded_4);
     }
 
-    private boolean run(byte[] buf) {
-        if (cf == null) {
-            try {
-                cf = CertificateFactory.getInstance("X.509", "SUN");
-            } catch (CertificateException e) {
-                throw new SecurityException("Cannot get CertificateFactory");
-            } catch (NoSuchProviderException npe) {
-                throw new SecurityException("Cannot get CertificateFactory");
-            }
-        }
-        try {
-            cf.generateCRL(new ByteArrayInputStream(buf));
-        } catch (CRLException ce) {
-            System.out.println("NPE checking passed");
-            return true;
-        }
-
-        System.out.println("CRLException has not been thrown");
-        return false;
+    private static void run(byte[] buf) {
+        Utils.runAndCheckException(
+                () -> cf.generateCRL(new ByteArrayInputStream(buf)),
+                CRLException.class);
+        Utils.runAndCheckException(
+                () -> cf.generateCRLs(new ByteArrayInputStream(buf)),
+                CRLException.class);
     }
 }
diff --git a/test/jdk/tools/jar/InputFilesTest.java b/test/jdk/tools/jar/InputFilesTest.java
index 3dc0829..6a0a7e2 100644
--- a/test/jdk/tools/jar/InputFilesTest.java
+++ b/test/jdk/tools/jar/InputFilesTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8165944
+ * @bug 8165944 8318971
  * @summary test several jar tool input file scenarios with variations on -C
  *          options with/without a --release option.  Some input files are
  *          duplicates that sometimes cause exceptions and other times do not,
@@ -153,6 +153,84 @@
         jar("cf test.jar --release 9 -C test1 a -C test2 a");
     }
 
+    /**
+     * Containing non-existent file in the file list
+     * The final jar should not be created and correct error message should be caught.
+     * IOException is triggered as expected.
+     */
+    @Test
+    public void testNonExistentFileInput() throws IOException {
+        touch("existingTestFile.txt");
+        onCompletion = () -> rm("existingTestFile.txt");
+        try {
+            jar("cf test.jar existingTestFile.txt nonExistentTestFile.txt");
+            Assert.fail("jar tool unexpectedly completed successfully");
+        } catch (IOException e) {
+            Assert.assertEquals(e.getMessage().trim(), "nonExistentTestFile.txt : no such file or directory");
+            Assert.assertTrue(Files.notExists(Path.of("test.jar")), "Jar file should not be created.");
+        }
+    }
+
+    /**
+     * With @File as a part of jar command line, where the File is containing one or more
+     * non-existent files or directories
+     * The final jar should not be created and correct error message should be caught.
+     * IOException is triggered as expected.
+     */
+    @Test
+    public void testNonExistentFileInputClassList() throws IOException {
+        touch("existingTestFile.txt");
+        touch("classes.list");
+        Files.writeString(Path.of("classes.list"), """
+                existingTestFile.txt
+                nonExistentTestFile.txt
+                nonExistentDirectory
+                 """);
+        onCompletion = () -> rm("existingTestFile.txt classes.list");
+        try {
+            jar("cf test.jar @classes.list");
+            Assert.fail("jar tool unexpectedly completed successfully");
+        } catch (IOException e) {
+            String msg = e.getMessage().trim();
+            Assert.assertTrue(msg.contains("nonExistentTestFile.txt : no such file or directory"));
+            Assert.assertTrue(msg.trim().contains("nonExistentDirectory : no such file or directory"));
+            Assert.assertTrue(Files.notExists(Path.of("test.jar")), "Jar file should not be created.");
+        }
+
+    }
+
+    /**
+     * Create a jar file; then with @File as a part of jar command line, where the File is containing one or more
+     * non-existent files or directories
+     * The final jar should not be created and correct error message should be caught.
+     * IOException is triggered as expected.
+     */
+    @Test
+    public void testUpdateNonExistentFileInputClassList() throws IOException {
+        touch("existingTestFileUpdate.txt");
+        touch("existingTestFileUpdate2.txt");
+        touch("classesUpdate.list");
+        Files.writeString(Path.of("classesUpdate.list"), """
+                existingTestFileUpdate2.txt
+                nonExistentTestFileUpdate.txt
+                nonExistentDirectoryUpdate
+                 """);
+        onCompletion = () -> rm("existingTestFileUpdate.txt existingTestFileUpdate2.txt " +
+                "classesUpdate.list testUpdate.jar");
+        try {
+            jar("cf testUpdate.jar existingTestFileUpdate.txt");
+            Assert.assertTrue(Files.exists(Path.of("testUpdate.jar")));
+            jar("uf testUpdate.jar @classesUpdate.list");
+            Assert.fail("jar tool unexpectedly completed successfully");
+        } catch (IOException e) {
+            String msg = e.getMessage().trim();
+            Assert.assertFalse(msg.contains("existingTestFileUpdate.txt : no such file or directory"));
+            Assert.assertTrue(msg.contains("nonExistentTestFileUpdate.txt : no such file or directory"));
+            Assert.assertTrue(msg.trim().contains("nonExistentDirectoryUpdate : no such file or directory"));
+        }
+
+    }
+
     private Stream<Path> mkpath(String... args) {
         return Arrays.stream(args).map(d -> Paths.get(".", d.split("/")));
     }
diff --git a/test/jtreg-ext/requires/VMProps.java b/test/jtreg-ext/requires/VMProps.java
index 4b06666..6eea979 100644
--- a/test/jtreg-ext/requires/VMProps.java
+++ b/test/jtreg-ext/requires/VMProps.java
@@ -508,9 +508,10 @@
 
     private boolean checkDockerSupport() throws IOException, InterruptedException {
         log("checkDockerSupport(): entering");
-        ProcessBuilder pb = new ProcessBuilder(Container.ENGINE_COMMAND, "ps");
-        Map<String, String> logFileNames = redirectOutputToLogFile("checkDockerSupport(): <container> ps",
-                                                      pb, "container-ps");
+        ProcessBuilder pb = new ProcessBuilder("which", Container.ENGINE_COMMAND);
+        Map<String, String> logFileNames =
+            redirectOutputToLogFile("checkDockerSupport(): which <container-engine>",
+                                                      pb, "which-container");
         Process p = pb.start();
         p.waitFor(10, TimeUnit.SECONDS);
         int exitValue = p.exitValue();
@@ -595,15 +596,19 @@
         // check -X flags
         var ignoredXFlags = Set.of(
                 // default, yet still seen to be explicitly set
-                "mixed"
+                "mixed",
+                // -XmxmNNNm added by run-test framework for non-hotspot tests
+                "mx"
         );
         result &= allFlags.stream()
                           .filter(s -> s.startsWith("-X") && !s.startsWith("-XX:"))
                           // map to names:
-                              // remove -X
-                              .map(s -> s.substring(2))
-                              // remove :.* from flags with values
-                              .map(s -> s.contains(":") ? s.substring(0, s.indexOf(':')) : s)
+                          // remove -X
+                          .map(s -> s.substring(2))
+                          // remove :.* from flags with values
+                          .map(s -> s.contains(":") ? s.substring(0, s.indexOf(':')) : s)
+                          // remove size like 4G, 768m which might be set for non-hotspot tests
+                          .map(s -> s.replaceAll("(\\d+)[mMgGkK]", ""))
                           // skip known-to-be-there flags
                           .filter(s -> !ignoredXFlags.contains(s))
                           .findAny()
diff --git a/test/langtools/TEST.groups b/test/langtools/TEST.groups
index 8df9dca..2acd985 100644
--- a/test/langtools/TEST.groups
+++ b/test/langtools/TEST.groups
@@ -67,10 +67,13 @@
     tools/all \
     tools/sjavac
 
+# All tests
+
+all = \
+    :langtools_all
+
 langtools_all = \
-    jdk \
-    lib \
-    tools
+    /
 
 # Tiered testing definitions
 
diff --git a/test/langtools/jdk/javadoc/lib/javadoc/tester/JavadocTester.java b/test/langtools/jdk/javadoc/lib/javadoc/tester/JavadocTester.java
index ff84f37..3a78d5b 100644
--- a/test/langtools/jdk/javadoc/lib/javadoc/tester/JavadocTester.java
+++ b/test/langtools/jdk/javadoc/lib/javadoc/tester/JavadocTester.java
@@ -58,6 +58,7 @@
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 
 /**
@@ -264,33 +265,34 @@
 
     /**
      * Run all methods annotated with @Test, followed by printSummary.
-     * Typically called on a tester object in main()
+     * The methods are invoked in the order found using getDeclaredMethods.
+     * The arguments for the invocation are provided {@link #getTestArgs(Method)}.
      *
+     * Typically called on a tester object in main().
+     *
+     * @throws IllegalArgumentException if any test method does not have a recognized signature
      * @throws Exception if any errors occurred
      */
     public void runTests() throws Exception {
-        runTests(m -> new Object[0]);
+        runTests(this::getTestArgs);
     }
 
     /**
      * Runs all methods annotated with @Test, followed by printSummary.
+     * The methods are invoked in the order found using getDeclaredMethods.
+     * The arguments for the invocation are provided by a given function.
+     *
      * Typically called on a tester object in main()
      *
      * @param f a function which will be used to provide arguments to each
      *          invoked method
-     * @throws Exception if any errors occurred
+     * @throws Exception if any errors occurred while executing a test method
      */
     public void runTests(Function<Method, Object[]> f) throws Exception {
-        for (Method m: getClass().getDeclaredMethods()) {
+        for (Method m : getClass().getDeclaredMethods()) {
             Annotation a = m.getAnnotation(Test.class);
             if (a != null) {
-                try {
-                    out.println("Running test " + m.getName());
-                    m.invoke(this, f.apply(m));
-                } catch (InvocationTargetException e) {
-                    Throwable cause = e.getCause();
-                    throw (cause instanceof Exception) ? ((Exception) cause) : e;
-                }
+                runTest(m, f);
                 out.println();
             }
         }
@@ -298,6 +300,95 @@
     }
 
     /**
+     * Run the specified methods annotated with @Test, or all methods annotated
+     * with @Test if none are specified, followed by printSummary.
+     * The methods are invoked in the order given in the methodNames argument,
+     * or the order returned by getDeclaredMethods if no names are provided.
+     * The arguments for the invocation are provided {@link #getTestArgs(Method)}.
+     *
+     * Typically called on a tester object in main(String[] args), perhaps using
+     * args as the list of method names.
+     *
+     * @throws IllegalStateException if any methods annotated with @Test are overloaded
+     * @throws IllegalArgumentException if any of the method names does not name a suitable method
+     * @throws NullPointerException if {@code methodNames} is {@code null}, or if any of the names are {@code null}
+     * @throws Exception if any errors occurred while executing a test method
+     */
+    public void runTests(String... methodNames) throws Exception {
+        runTests(this::getTestArgs, methodNames);
+    }
+
+    /**
+     * Run the specified methods annotated with @Test, or all methods annotated
+     * with @Test if non are specified, followed by printSummary.
+     * The methods are invoked in the order given in the methodNames argument,
+     * or the order returned by getDeclaredMethods if no names are provided.
+     * The arguments for the invocation are provided {@link #getTestArgs(Method)}.
+     *
+     * Typically called on a tester object in main(String[] args), perhaps using
+     * args as the list of method names.
+     *
+     * @throws IllegalStateException if any methods annotated with @Test are overloaded
+     * @throws IllegalArgumentException if any of the method names does not name a suitable method
+     * @throws NullPointerException if {@code methodNames} is {@code null}, or if any of the names are {@code null}
+     * @throws Exception if any errors occurred while executing a test method
+     */
+    public void runTests(Function<Method, Object[]> f, String... methodNames) throws Exception {
+        if (methodNames.length == 0) {
+            runTests(f);
+        } else {
+            Map<String, Method> testMethods = Stream.of(getClass().getDeclaredMethods())
+                    .filter(this::isTestMethod)
+                    .collect(Collectors.toMap(Method::getName, Function.identity(),
+                            (o, n) -> {
+                                throw new IllegalStateException("test method " + o.getName() + " is overloaded");
+                            }));
+
+            List<Method> list = new ArrayList<>();
+            for (String mn : methodNames) {
+                Method m = testMethods.get(mn);
+                if (m == null) {
+                    throw new IllegalArgumentException("test method " + mn + " not found");
+                }
+                list.add(m);
+            }
+
+            for (Method m : list) {
+                runTest(m, f);
+            }
+        }
+    }
+
+    protected boolean isTestMethod(Method m) {
+        return m.getAnnotation(Test.class) != null;
+    }
+
+    protected Object[] getTestArgs(Method m) throws IllegalArgumentException {
+        Class<?>[] paramTypes = m.getParameterTypes();
+        if (paramTypes.length == 0) {
+            return new Object[] {};
+        } else if (paramTypes.length == 1 && paramTypes[0] == Path.class) {
+            return new Object[] { Path.of(m.getName())};
+        } else {
+            throw new IllegalArgumentException("unknown signature for method "
+                    + m + Stream.of(paramTypes)
+                    .map(Class::toString)
+                    .collect(Collectors.joining(", ", "(", ")")))  ;
+        }
+    }
+
+    protected void runTest(Method m, Function<Method, Object[]> f) throws Exception {
+        try {
+            out.println("Running test " + m.getName());
+            m.invoke(this, f.apply(m));
+        } catch (InvocationTargetException e) {
+            Throwable cause = e.getCause();
+            throw (cause instanceof Exception) ? ((Exception) cause) : e;
+        }
+
+    }
+
+    /**
      * Runs javadoc.
      * The output directory used by this call and the final exit code
      * will be saved for later use.
@@ -1470,4 +1561,4 @@
         }
     }
 
-}
\ No newline at end of file
+}
diff --git a/test/langtools/jdk/javadoc/testJavadocTester/TestRunTests.java b/test/langtools/jdk/javadoc/testJavadocTester/TestRunTests.java
new file mode 100644
index 0000000..ae5c97f
--- /dev/null
+++ b/test/langtools/jdk/javadoc/testJavadocTester/TestRunTests.java
@@ -0,0 +1,272 @@
+/*
+ * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+/*
+ * @test
+ * @bug 8272853
+ * @summary improve `JavadocTester.runTests`
+ * @library /tools/lib/ ../lib
+ * @modules jdk.javadoc/jdk.javadoc.internal.tool
+ * @build toolbox.ToolBox javadoc.tester.*
+ * @run main TestRunTests
+ */
+
+import javadoc.tester.JavadocTester;
+
+import java.io.PrintStream;
+import java.lang.annotation.Annotation;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Set;
+import java.util.function.Function;
+
+public class TestRunTests {
+    @Retention(RetentionPolicy.RUNTIME)
+    public @interface RunTest {
+    }
+
+    public static void main(String... args) throws Exception {
+        TestRunTests t = new TestRunTests();
+        t.run();
+    }
+
+    PrintStream out = System.out;
+
+    void run() throws Exception {
+        for (Method m : getClass().getDeclaredMethods()) {
+            Annotation a = m.getAnnotation(RunTest.class);
+            if (a != null) {
+                try {
+                    out.println("Running " + m);
+                    m.invoke(this);
+                    out.println();
+                } catch (InvocationTargetException e) {
+                    error("Invocation Target Exception while running " + m + ": " + e.getCause());
+                } catch (Exception e) {
+                    error("Exception while running " + m + ": " + e);
+                }
+            }
+        }
+        out.flush();
+        if (errors > 0) {
+            out.println(errors + " errors occurred");
+            throw new Exception(errors + " errors occurred");
+        }
+    }
+
+    int errors;
+
+    @RunTest
+    public void testNoArgs() throws Exception {
+        MainGroup g = new MainGroup();
+        g.runTests();
+        checkEqualUnordered(g.log, Set.of("m1()", "m2(m2)", "m3()", "m4(m4)"));
+    }
+
+    @RunTest
+    public void testMethodNames() throws Exception {
+        MainGroup g = new MainGroup();
+        g.runTests("m1", "m4", "m2");
+        checkEqualOrdered(g.log, List.of("m1()", "m4(m4)", "m2(m2)"));
+    }
+
+    @RunTest
+    public void testFunction() throws Exception {
+        Function<Method, Object[]> f = m ->
+                switch (m.getName()) {
+                    case "m1", "m3" -> new Object[]{};
+                    case "m2", "m4" -> new Object[]{Path.of(m.getName().toUpperCase(Locale.ROOT))};
+                    default -> throw new IllegalArgumentException(m.toString());
+                };
+        MainGroup g = new MainGroup();
+        g.runTests(f);
+        checkEqualUnordered(g.log, Set.of("m1()", "m2(M2)", "m3()", "m4(M4)"));
+    }
+
+    @RunTest
+    public void testFunctionMethodNames() throws Exception {
+        Function<Method, Object[]> f = m ->
+                switch (m.getName()) {
+                    case "m1", "m3" -> new Object[]{};
+                    case "m2", "m4" -> new Object[]{Path.of(m.getName().toUpperCase(Locale.ROOT))};
+                    default -> throw new IllegalArgumentException(m.toString());
+                };
+        MainGroup g = new MainGroup();
+        g.runTests(f, "m1", "m4", "m2");
+        checkEqualOrdered(g.log, List.of("m1()", "m4(M4)", "m2(M2)"));
+    }
+
+    @RunTest
+    public void testMethodNotFound() throws Exception {
+        MainGroup g = new MainGroup();
+        try {
+            g.runTests("m1", "m2", "mx", "m3", "m4");
+        } catch (IllegalArgumentException e) {
+            g.log.add(e.toString());
+        }
+        // implicit in the following is that the error was detected before any test methods were executed
+        checkEqualOrdered(g.log, List.of("java.lang.IllegalArgumentException: test method mx not found"));
+    }
+
+    @RunTest
+    public void testInvalidSignature() throws Exception {
+        InvalidSignatureGroup g = new InvalidSignatureGroup();
+        try {
+            g.runTests();
+        } catch (IllegalArgumentException e) {
+            g.log.add(e.toString());
+        }
+        // since the exception comes from the nested use of `getTestArgs`, it will be thrown
+        // when the test method is being called, and so is not constrained to be thrown
+        // before any test method is called
+        checkContainsAll(g.log, List.of("java.lang.IllegalArgumentException: unknown signature for method "
+                + "public void TestRunTests$InvalidSignatureGroup.invalidSignature(java.lang.Object)(class java.lang.Object)"));
+    }
+
+    @RunTest
+    public void testOverloadedMethod() throws Exception {
+        OverloadGroup g = new OverloadGroup();
+        try {
+            g.runTests("m1");
+        } catch (IllegalStateException e) {
+            g.log.add(e.toString());
+        }
+        // implicit in the following is that the error was detected before any test methods were executed
+        checkEqualOrdered(g.log, List.of("java.lang.IllegalStateException: test method m1 is overloaded"));
+    }
+
+    void checkContainsAll(List<String> found, List<String> expect) {
+        if (!found.containsAll(expect)) {
+            out.println("Found:  " + found);
+            out.println("Expect: " + expect);
+            error("Expected results not found");
+        }
+    }
+
+    void checkEqualOrdered(List<String> found, List<String> expect) {
+        if (!found.equals(expect)) {
+            out.println("Found:  " + found);
+            out.println("Expect: " + expect);
+            error("Expected results not found");
+        }
+    }
+
+    void checkEqualUnordered(List<String> found, Set<String> expect) {
+        if (!(found.containsAll(expect) && expect.containsAll(found))) {
+            out.println("Found:  " + found);
+            out.println("Expect: " + expect);
+            error("Expected results not found");
+        }
+    }
+
+    void error(String message) {
+        out.println("Error: " + message);
+        errors++;
+    }
+
+    /**
+     * A group of tests to be executed by different overloads of {@code runTests}.
+     */
+    public static class MainGroup extends JavadocTester {
+        List<String> log = new ArrayList<>();
+
+        @Test
+        public void m1() {
+            log.add("m1()");
+            checking("m1");
+            passed("OK");
+        }
+
+        @Test
+        public void m2(Path p) {
+            log.add("m2(" + p.getFileName() + ")");
+            checking("m2");
+            passed("OK");
+        }
+
+        @Test
+        public void m3() {
+            log.add("m3()");
+            checking("m3");
+            passed("OK");
+        }
+
+        @Test
+        public void m4(Path p) {
+            log.add("m4(" + p.getFileName() + ")");
+            checking("m4");
+            passed("OK");
+        }
+    }
+
+    /**
+     * A group of tests containing one with an invalid (unrecognized) signature.
+     * The invalid signature should cause an exception when trying to run that test.
+     */
+    public static class InvalidSignatureGroup extends JavadocTester {
+        List<String> log = new ArrayList<>();
+
+        @Test
+        public void m1() {
+            log.add("m1()");
+            checking("m1");
+            passed("OK");
+        }
+
+        @Test
+        public void invalidSignature(Object o) {
+            log.add("invalidSignature(" + o + ")");
+            checking("invalidSignature");
+            passed("OK");
+        }
+    }
+
+    /**
+     * A group of tests including an overloaded test method.
+     * The overload should cause an exception when trying to run that test by name.
+     */
+    public static class OverloadGroup extends JavadocTester {
+        List<String> log = new ArrayList<>();
+
+        @Test
+        public void m1() {
+            log.add("m1()");
+            checking("m1");
+            passed("OK");
+        }
+
+        @Test
+        public void m1(Path p) {
+            log.add("m1(" + p + ")");
+            checking("m1");
+            passed("OK");
+        }
+    }
+}
diff --git a/test/langtools/tools/javac/parser/JavacParserTest.java b/test/langtools/tools/javac/parser/JavacParserTest.java
index 2be3467..6bcd5c9 100644
--- a/test/langtools/tools/javac/parser/JavacParserTest.java
+++ b/test/langtools/tools/javac/parser/JavacParserTest.java
@@ -859,11 +859,7 @@
                 + expectedValues, values, expectedValues);
     }
 
-    /*
-     * The following tests do not work just yet with nb-javac nor javac,
-     * they need further investigation, see CR: 7167356
-     */
-
+    @Test
     void testPositionBrokenSource126732a() throws IOException {
         String[] commands = new String[]{
             "return Runnable()",
@@ -903,6 +899,7 @@
         }
     }
 
+    @Test
     void testPositionBrokenSource126732b() throws IOException {
         String[] commands = new String[]{
             "break",
@@ -944,6 +941,7 @@
         }
     }
 
+    @Test
     void testStartPositionEnumConstantInit() throws IOException {
 
         String code = "package t; enum Test { AAA; }";
@@ -957,7 +955,7 @@
         int start = (int) t.getSourcePositions().getStartPosition(cut,
                 enumAAA.getInitializer());
 
-        assertEquals("testStartPositionEnumConstantInit", -1, start);
+        assertEquals("testStartPositionEnumConstantInit", 23, start);
     }
 
     @Test
diff --git a/test/langtools/tools/javac/processing/environment/round/TestContext.java b/test/langtools/tools/javac/processing/environment/round/TestContext.java
index f572d2d..4d0b1674 100644
--- a/test/langtools/tools/javac/processing/environment/round/TestContext.java
+++ b/test/langtools/tools/javac/processing/environment/round/TestContext.java
@@ -31,7 +31,7 @@
  *          jdk.compiler/com.sun.tools.javac.processing
  *          jdk.compiler/com.sun.tools.javac.util
  * @build JavacTestingAbstractProcessor TestContext
- * @compile/process -processor TestContext -XprintRounds TestContext
+ * @compile/process -processor TestContext -XprintRounds -proc:full TestContext
  */
 
 import java.io.*;
diff --git a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnilocalreflock04/TestDescription.java b/test/langtools/tools/javac/processing/options/TestProcOption.java
similarity index 69%
rename from test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnilocalreflock04/TestDescription.java
rename to test/langtools/tools/javac/processing/options/TestProcOption.java
index 42d7299..882077a 100644
--- a/test/hotspot/jtreg/vmTestbase/gc/lock/jniref/jnilocalreflock04/TestDescription.java
+++ b/test/langtools/tools/javac/processing/options/TestProcOption.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -21,20 +21,21 @@
  * questions.
  */
 
-
 /*
  * @test
- * @key stress randomness
- *
- * @summary converted from VM Testbase gc/lock/jniref/jnilocalreflock04.
- * VM Testbase keywords: [gc, stress, stressopt, nonconcurrent]
- *
- * @library /vmTestbase
- *          /test/lib
- * @run main/othervm/native
- *      -XX:-UseGCOverheadLimit
- *      gc.lock.LockerTest
- *      -gp1 class
- *      -lockers jniLocalRef
+ * @bug 8308245
+ * @summary Test trivial handling of -proc:full option
+ * @compile -proc:full TestProcOption.java
+ * @run main TestProcOption
  */
 
+/*
+ * The test verifies that compilation takes place when -proc:full is used.
+ */
+public class TestProcOption {
+    private TestProcOption(){};
+
+    public static void main(String... args) {
+        ; // do nothing
+    }
+}
diff --git a/test/lib-test/TEST.groups b/test/lib-test/TEST.groups
index eb0c9b3..85067f3 100644
--- a/test/lib-test/TEST.groups
+++ b/test/lib-test/TEST.groups
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -21,4 +21,15 @@
 # questions.
 #
 
-tier1 = .
+# All tests
+
+all = \
+    :libtest_all
+
+libtest_all = \
+    /
+
+# Tiered testing definitions
+
+tier1 = \
+    :all
diff --git a/test/lib-test/jdk/test/lib/AssertsTest.java b/test/lib-test/jdk/test/lib/AssertsTest.java
index 86b1a7f..a4c739d 100644
--- a/test/lib-test/jdk/test/lib/AssertsTest.java
+++ b/test/lib-test/jdk/test/lib/AssertsTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -38,7 +38,7 @@
         }
 
         public int compareTo(Foo f) {
-            return new Integer(id).compareTo(new Integer(f.id));
+            return Integer.valueOf(id).compareTo(Integer.valueOf(f.id));
         }
         public String toString() {
             return "Foo(" + Integer.toString(id) + ")";
diff --git a/test/lib-test/jdk/test/lib/TestMutuallyExclusivePlatformPredicates.java b/test/lib-test/jdk/test/lib/TestMutuallyExclusivePlatformPredicates.java
index 045be53..355cd8a 100644
--- a/test/lib-test/jdk/test/lib/TestMutuallyExclusivePlatformPredicates.java
+++ b/test/lib-test/jdk/test/lib/TestMutuallyExclusivePlatformPredicates.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -53,7 +53,7 @@
         IGNORED("isEmulatedClient", "isDebugBuild", "isFastDebugBuild", "isMusl",
                 "isSlowDebugBuild", "hasSA", "isRoot", "isTieredSupported",
                 "areCustomLoadersSupportedForCDS", "isDefaultCDSArchiveSupported",
-                "isHardenedOSX");
+                "isHardenedOSX", "hasOSXPlistEntries");
 
         public final List<String> methodNames;
 
diff --git a/test/lib-test/jdk/test/lib/TestPlatformIsTieredSupported.java b/test/lib-test/jdk/test/lib/TestPlatformIsTieredSupported.java
index d61bb61..a14efc9 100644
--- a/test/lib-test/jdk/test/lib/TestPlatformIsTieredSupported.java
+++ b/test/lib-test/jdk/test/lib/TestPlatformIsTieredSupported.java
@@ -39,6 +39,7 @@
  */
 public class TestPlatformIsTieredSupported {
     public static void main(String args[]) {
+        @SuppressWarnings("deprecation")
         WhiteBox whiteBox = WhiteBox.getWhiteBox();
         boolean tieredCompilation = whiteBox.getBooleanVMFlag(
                 "TieredCompilation");
diff --git a/test/lib-test/jdk/test/lib/format/ArrayDiffTest.java b/test/lib-test/jdk/test/lib/format/ArrayDiffTest.java
index 7b7dfc0..c52fcd7 100644
--- a/test/lib-test/jdk/test/lib/format/ArrayDiffTest.java
+++ b/test/lib-test/jdk/test/lib/format/ArrayDiffTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -274,6 +274,7 @@
         class StrObj {
             private final String value;
             public boolean equals(Object another) { return ((StrObj)another).value.equals(value); }
+            public int hashCode() { return value.hashCode(); }
             public StrObj(String value) { this.value = value; }
             public String toString() { return value; }
         }
@@ -363,7 +364,7 @@
         }
 
         public void assertTwoWay() {
-            ArrayDiff diff;
+            ArrayDiff<?> diff;
 
             // Direct
             if (defaultParameters) {
diff --git a/test/lib-test/jdk/test/whitebox/vm_flags/VmFlagTest.java b/test/lib-test/jdk/test/whitebox/vm_flags/VmFlagTest.java
index d48aab6..7290cd1 100644
--- a/test/lib-test/jdk/test/whitebox/vm_flags/VmFlagTest.java
+++ b/test/lib-test/jdk/test/whitebox/vm_flags/VmFlagTest.java
@@ -72,9 +72,9 @@
     protected static <T> void runTest(String existentFlag, T[] tests,
             T[] results, BiConsumer<String, T> set, Function<String, T> get) {
         if (existentFlag != null) {
-            new VmFlagTest(existentFlag, set, get, true).test(tests, results);
+            new VmFlagTest<T>(existentFlag, set, get, true).test(tests, results);
         }
-        new VmFlagTest(NONEXISTENT_FLAG, set, get, false).test(tests, results);
+        new VmFlagTest<T>(NONEXISTENT_FLAG, set, get, false).test(tests, results);
     }
 
     public final void test(T[] tests, T[] results) {
diff --git a/test/lib/RedefineClassHelper.java b/test/lib/RedefineClassHelper.java
index 0fcfc52..88f31f8 100644
--- a/test/lib/RedefineClassHelper.java
+++ b/test/lib/RedefineClassHelper.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -21,7 +21,6 @@
  * questions.
  */
 
-import java.io.PrintWriter;
 import java.lang.instrument.Instrumentation;
 import java.lang.instrument.ClassDefinition;
 import jdk.test.lib.compiler.InMemoryJavaCompiler;
@@ -47,7 +46,7 @@
      * @param clazz Class to redefine
      * @param javacode String with the new java code for the class to be redefined
      */
-    public static void redefineClass(Class clazz, String javacode) throws Exception {
+    public static void redefineClass(Class<?> clazz, String javacode) throws Exception {
         byte[] bytecode = InMemoryJavaCompiler.compile(clazz.getName(), javacode);
         redefineClass(clazz, bytecode);
     }
@@ -58,7 +57,7 @@
      * @param clazz Class to redefine
      * @param bytecode byte[] with the new class
      */
-    public static void redefineClass(Class clazz, byte[] bytecode) throws Exception {
+    public static void redefineClass(Class<?> clazz, byte[] bytecode) throws Exception {
         instrumentation.redefineClasses(new ClassDefinition(clazz, bytecode));
     }
 
diff --git a/test/lib/jdk/test/lib/NetworkConfiguration.java b/test/lib/jdk/test/lib/NetworkConfiguration.java
index 716e2ae..386a2bf 100644
--- a/test/lib/jdk/test/lib/NetworkConfiguration.java
+++ b/test/lib/jdk/test/lib/NetworkConfiguration.java
@@ -451,6 +451,7 @@
     }
 
     /** Prints all the system interface information to the give stream. */
+    @SuppressWarnings("removal")
     public static void printSystemConfiguration(PrintStream out) {
         PrivilegedAction<Void> pa = () -> {
         try {
diff --git a/test/lib/jdk/test/lib/OSVersion.java b/test/lib/jdk/test/lib/OSVersion.java
index 5754fe5..bb9f128 100644
--- a/test/lib/jdk/test/lib/OSVersion.java
+++ b/test/lib/jdk/test/lib/OSVersion.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,13 +26,8 @@
 package jdk.test.lib;
 
 import java.util.Arrays;
-import java.io.BufferedReader;
-import java.io.FileReader;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
-import java.security.AccessController;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
 
 public final class OSVersion implements Comparable<OSVersion> {
     public static final OSVersion WINDOWS_95 = new OSVersion(4, 0);
diff --git a/test/lib/jdk/test/lib/Platform.java b/test/lib/jdk/test/lib/Platform.java
index 01e332b..1f92233 100644
--- a/test/lib/jdk/test/lib/Platform.java
+++ b/test/lib/jdk/test/lib/Platform.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -260,6 +260,36 @@
         return true;
     }
 
+    private static Process launchCodesignOnJavaBinary() throws IOException {
+        String jdkPath = System.getProperty("java.home");
+        Path javaPath = Paths.get(jdkPath + "/bin/java");
+        String javaFileName = javaPath.toAbsolutePath().toString();
+        if (Files.notExists(javaPath)) {
+            throw new FileNotFoundException("Could not find file " + javaFileName);
+        }
+        ProcessBuilder pb = new ProcessBuilder("codesign", "--display", "--verbose", javaFileName);
+        pb.redirectErrorStream(true); // redirect stderr to stdout
+        Process codesignProcess = pb.start();
+        return codesignProcess;
+    }
+
+    public static boolean hasOSXPlistEntries() throws IOException {
+        Process codesignProcess = launchCodesignOnJavaBinary();
+        BufferedReader is = new BufferedReader(new InputStreamReader(codesignProcess.getInputStream()));
+        String line;
+        while ((line = is.readLine()) != null) {
+            System.out.println("STDOUT: " + line);
+            if (line.indexOf("Info.plist=not bound") != -1) {
+                return false;
+            }
+            if (line.indexOf("Info.plist entries=") != -1) {
+                return true;
+            }
+        }
+        System.out.println("No matching Info.plist entry was found");
+        return false;
+    }
+
     /**
      * Return true if the test JDK is hardened, otherwise false. Only valid on OSX.
      */
@@ -269,19 +299,7 @@
         if (getOsVersionMajor() == 10 && getOsVersionMinor() < 14) {
             return false; // assume not hardened
         }
-
-        // Find the path to the java binary.
-        String jdkPath = System.getProperty("java.home");
-        Path javaPath = Paths.get(jdkPath + "/bin/java");
-        String javaFileName = javaPath.toAbsolutePath().toString();
-        if (Files.notExists(javaPath)) {
-            throw new FileNotFoundException("Could not find file " + javaFileName);
-        }
-
-        // Run codesign on the java binary.
-        ProcessBuilder pb = new ProcessBuilder("codesign", "--display", "--verbose", javaFileName);
-        pb.redirectErrorStream(true); // redirect stderr to stdout
-        Process codesignProcess = pb.start();
+        Process codesignProcess = launchCodesignOnJavaBinary();
         BufferedReader is = new BufferedReader(new InputStreamReader(codesignProcess.getInputStream()));
         String line;
         boolean isHardened = false;
diff --git a/test/lib/jdk/test/lib/Utils.java b/test/lib/jdk/test/lib/Utils.java
index 30f6e9e..f84ddab 100644
--- a/test/lib/jdk/test/lib/Utils.java
+++ b/test/lib/jdk/test/lib/Utils.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -52,7 +52,6 @@
 import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.Objects;
 import java.util.Random;
 import java.util.function.BooleanSupplier;
 import java.util.concurrent.TimeUnit;
@@ -131,6 +130,11 @@
     public static final String SEED_PROPERTY_NAME = "jdk.test.lib.random.seed";
 
     /**
+     * Returns the value of 'file.separator' system property
+     */
+    public static final String FILE_SEPARATOR = System.getProperty("file.separator");
+
+    /**
      * Random generator with predefined seed.
      */
     private static volatile Random RANDOM_GENERATOR;
diff --git a/test/lib/jdk/test/lib/apps/LingeredApp.java b/test/lib/jdk/test/lib/apps/LingeredApp.java
index 732c988..01c15b3 100644
--- a/test/lib/jdk/test/lib/apps/LingeredApp.java
+++ b/test/lib/jdk/test/lib/apps/LingeredApp.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,7 +37,6 @@
 import java.util.Collections;
 import java.util.Date;
 import java.util.List;
-import java.util.Map;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 import java.util.UUID;
diff --git a/test/lib/jdk/test/lib/artifacts/ArtifactManager.java b/test/lib/jdk/test/lib/artifacts/ArtifactManager.java
index 31b9622..38a68b6 100644
--- a/test/lib/jdk/test/lib/artifacts/ArtifactManager.java
+++ b/test/lib/jdk/test/lib/artifacts/ArtifactManager.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,6 @@
 
 package jdk.test.lib.artifacts;
 
-import java.io.FileNotFoundException;
 import java.nio.file.Path;
 
 public interface ArtifactManager {
diff --git a/test/lib/jdk/test/lib/classloader/ClassUnloadCommon.java b/test/lib/jdk/test/lib/classloader/ClassUnloadCommon.java
index ce0e3da..23e8fa6 100644
--- a/test/lib/jdk/test/lib/classloader/ClassUnloadCommon.java
+++ b/test/lib/jdk/test/lib/classloader/ClassUnloadCommon.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,8 +31,6 @@
 package jdk.test.lib.classloader;
 
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLClassLoader;
diff --git a/test/lib/jdk/test/lib/compiler/InMemoryJavaCompiler.java b/test/lib/jdk/test/lib/compiler/InMemoryJavaCompiler.java
index ec3a831..6016e48 100644
--- a/test/lib/jdk/test/lib/compiler/InMemoryJavaCompiler.java
+++ b/test/lib/jdk/test/lib/compiler/InMemoryJavaCompiler.java
@@ -107,7 +107,7 @@
         }
     }
 
-    private static class FileManagerWrapper extends ForwardingJavaFileManager {
+    private static class FileManagerWrapper extends ForwardingJavaFileManager<JavaFileManager> {
         private static final Location PATCH_LOCATION = new Location() {
             @Override
             public String getName() {
diff --git a/test/lib/jdk/test/lib/containers/docker/Common.java b/test/lib/jdk/test/lib/containers/docker/Common.java
index 4f1d0e0..4c9cccb 100644
--- a/test/lib/jdk/test/lib/containers/docker/Common.java
+++ b/test/lib/jdk/test/lib/containers/docker/Common.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,8 +31,6 @@
 import java.nio.file.Files;
 import java.nio.file.Paths;
 import java.nio.file.StandardCopyOption;
-import jdk.test.lib.containers.docker.DockerRunOptions;
-import jdk.test.lib.containers.docker.DockerTestUtils;
 import jdk.test.lib.Utils;
 import jdk.test.lib.process.OutputAnalyzer;
 
diff --git a/test/lib/jdk/test/lib/containers/docker/DockerTestUtils.java b/test/lib/jdk/test/lib/containers/docker/DockerTestUtils.java
index 091fe88..efabd79 100644
--- a/test/lib/jdk/test/lib/containers/docker/DockerTestUtils.java
+++ b/test/lib/jdk/test/lib/containers/docker/DockerTestUtils.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,6 @@
 
 package jdk.test.lib.containers.docker;
 
-import java.io.File;
 import java.io.FileWriter;
 import java.io.IOException;
 import java.nio.file.Files;
diff --git a/test/lib/jdk/test/lib/format/ArrayCodec.java b/test/lib/jdk/test/lib/format/ArrayCodec.java
index 0e34e7c..b5faf35 100644
--- a/test/lib/jdk/test/lib/format/ArrayCodec.java
+++ b/test/lib/jdk/test/lib/format/ArrayCodec.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,6 @@
 
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Optional;
 
 /**
  * A codec helping representing arrays in a string form.
@@ -141,7 +140,7 @@
      * @throws IllegalArgumentException if {@code array}'s component type is not supported
      * @return an ArrayCodec for the provided array
      */
-    public static ArrayCodec of(Object array) {
+    public static ArrayCodec<?> of(Object array) {
         var type = array.getClass().getComponentType();
         if (type == byte.class) {
             return ArrayCodec.of((byte[])array);
diff --git a/test/lib/jdk/test/lib/format/ArrayDiff.java b/test/lib/jdk/test/lib/format/ArrayDiff.java
index 6755a69..136827c 100644
--- a/test/lib/jdk/test/lib/format/ArrayDiff.java
+++ b/test/lib/jdk/test/lib/format/ArrayDiff.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,8 +23,6 @@
 
 package jdk.test.lib.format;
 
-import java.util.ArrayList;
-import java.util.List;
 import java.util.Objects;
 import java.util.Optional;
 
@@ -93,7 +91,7 @@
      * @param second the second array
      * @return an ArrayDiff instance for the two arrays
      */
-    public static ArrayDiff of(Object first, Object second) {
+    public static ArrayDiff<?> of(Object first, Object second) {
         return ArrayDiff.of(first, second, Diff.Defaults.WIDTH, Diff.Defaults.CONTEXT_BEFORE);
     }
 
@@ -109,7 +107,8 @@
      * @throws NullPointerException if at least one of the arrays is null
      * @return an ArrayDiff instance for the two arrays and formatting parameters provided
      */
-    public static ArrayDiff of(Object first, Object second, int width, int contextBefore) {
+    @SuppressWarnings("rawtypes")
+    public static ArrayDiff<?> of(Object first, Object second, int width, int contextBefore) {
         Objects.requireNonNull(first);
         Objects.requireNonNull(second);
 
@@ -204,4 +203,3 @@
     }
 
 }
-
diff --git a/test/lib/jdk/test/lib/helpers/ClassFileInstaller.java b/test/lib/jdk/test/lib/helpers/ClassFileInstaller.java
index a44207b..d344344 100644
--- a/test/lib/jdk/test/lib/helpers/ClassFileInstaller.java
+++ b/test/lib/jdk/test/lib/helpers/ClassFileInstaller.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,9 +27,7 @@
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
-import java.io.FileNotFoundException;
 import java.io.InputStream;
-import java.io.ByteArrayInputStream;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
diff --git a/test/lib/jdk/test/lib/hexdump/ASN1Formatter.java b/test/lib/jdk/test/lib/hexdump/ASN1Formatter.java
index 844b54d..41b13ec 100644
--- a/test/lib/jdk/test/lib/hexdump/ASN1Formatter.java
+++ b/test/lib/jdk/test/lib/hexdump/ASN1Formatter.java
@@ -626,6 +626,7 @@
      * @return the InputStream or the wrapped decoder of Base64Mime.
      * @throws IOException if an I/O error occurs
      */
+    @SuppressWarnings("deprecation")
     private static InputStream wrapIfBase64Mime(BufferedInputStream bis) throws IOException {
         bis.mark(256);
         DataInputStream dis = new DataInputStream(bis);
diff --git a/test/lib/jdk/test/lib/hexdump/ObjectStreamPrinter.java b/test/lib/jdk/test/lib/hexdump/ObjectStreamPrinter.java
index 3b52ece..1108402 100644
--- a/test/lib/jdk/test/lib/hexdump/ObjectStreamPrinter.java
+++ b/test/lib/jdk/test/lib/hexdump/ObjectStreamPrinter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -41,9 +41,6 @@
 import java.util.function.BiConsumer;
 
 import static java.io.ObjectStreamConstants.STREAM_MAGIC;
-import static java.io.ObjectStreamConstants.TC_BLOCKDATA;
-import static java.io.ObjectStreamConstants.TC_BLOCKDATALONG;
-import static java.io.ObjectStreamConstants.TC_ENDBLOCKDATA;
 import static java.io.ObjectStreamConstants.TC_MAX;
 import static java.io.ObjectStreamConstants.TC_NULL;
 import static java.io.ObjectStreamConstants.baseWireHandle;
diff --git a/test/lib/jdk/test/lib/hexdump/StreamDump.java b/test/lib/jdk/test/lib/hexdump/StreamDump.java
index 21ad296..cbdef1f 100644
--- a/test/lib/jdk/test/lib/hexdump/StreamDump.java
+++ b/test/lib/jdk/test/lib/hexdump/StreamDump.java
@@ -165,6 +165,7 @@
      * @return an InputStream, unchanged unless it is Base64 Mime
      * @throws IOException if an I/O Error occurs
      */
+    @SuppressWarnings("deprecation")
     static InputStream decodeMaybe(InputStream is) throws IOException {
         DataInputStream dis = new DataInputStream(is);
         is.mark(1024);
diff --git a/test/lib/jdk/test/lib/hprof/model/JavaObjectArray.java b/test/lib/jdk/test/lib/hprof/model/JavaObjectArray.java
index d6bbe85..232c627 100644
--- a/test/lib/jdk/test/lib/hprof/model/JavaObjectArray.java
+++ b/test/lib/jdk/test/lib/hprof/model/JavaObjectArray.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,7 +33,6 @@
 package jdk.test.lib.hprof.model;
 
 import java.io.IOException;
-import jdk.test.lib.hprof.parser.ReadBuffer;
 
 /**
  * @author      Bill Foote
diff --git a/test/lib/jdk/test/lib/hprof/model/JavaThing.java b/test/lib/jdk/test/lib/hprof/model/JavaThing.java
index f771039..024928e 100644
--- a/test/lib/jdk/test/lib/hprof/model/JavaThing.java
+++ b/test/lib/jdk/test/lib/hprof/model/JavaThing.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,10 +32,6 @@
 
 package jdk.test.lib.hprof.model;
 
-import java.util.Enumeration;
-import java.util.Hashtable;
-
-
 /**
  *
  * @author      Bill Foote
diff --git a/test/lib/jdk/test/lib/hprof/model/JavaValueArray.java b/test/lib/jdk/test/lib/hprof/model/JavaValueArray.java
index 9582def..1f32a3f 100644
--- a/test/lib/jdk/test/lib/hprof/model/JavaValueArray.java
+++ b/test/lib/jdk/test/lib/hprof/model/JavaValueArray.java
@@ -32,7 +32,6 @@
 
 package jdk.test.lib.hprof.model;
 
-import jdk.test.lib.hprof.parser.ReadBuffer;
 import java.io.IOException;
 
 /**
diff --git a/test/lib/jdk/test/lib/hprof/model/ReachableExcludesImpl.java b/test/lib/jdk/test/lib/hprof/model/ReachableExcludesImpl.java
index 5038f71..af4abbf 100644
--- a/test/lib/jdk/test/lib/hprof/model/ReachableExcludesImpl.java
+++ b/test/lib/jdk/test/lib/hprof/model/ReachableExcludesImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -35,7 +35,6 @@
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.InputStreamReader;
-import java.io.Reader;
 import java.io.BufferedReader;
 import java.io.IOException;
 
diff --git a/test/lib/jdk/test/lib/hprof/model/ReachableObjects.java b/test/lib/jdk/test/lib/hprof/model/ReachableObjects.java
index 8b96987..1ba41e9 100644
--- a/test/lib/jdk/test/lib/hprof/model/ReachableObjects.java
+++ b/test/lib/jdk/test/lib/hprof/model/ReachableObjects.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,7 +32,6 @@
 
 package jdk.test.lib.hprof.model;
 
-import java.util.Vector;
 import java.util.Hashtable;
 import java.util.Enumeration;
 
diff --git a/test/lib/jdk/test/lib/hprof/util/ArraySorter.java b/test/lib/jdk/test/lib/hprof/util/ArraySorter.java
index 04dbad7..5378528 100644
--- a/test/lib/jdk/test/lib/hprof/util/ArraySorter.java
+++ b/test/lib/jdk/test/lib/hprof/util/ArraySorter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,7 +31,6 @@
  */
 
 package jdk.test.lib.hprof.util;
-import java.util.*;
 
 /**
  * A singleton utility class that sorts an array of objects.
diff --git a/test/lib/jdk/test/lib/hprof/util/Misc.java b/test/lib/jdk/test/lib/hprof/util/Misc.java
index e654d71..42e0ce0 100644
--- a/test/lib/jdk/test/lib/hprof/util/Misc.java
+++ b/test/lib/jdk/test/lib/hprof/util/Misc.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,7 +31,6 @@
  */
 
 package jdk.test.lib.hprof.util;
-import java.util.*;
 
 /**
  * Miscellaneous functions I couldn't think of a good place to put.
diff --git a/test/lib/jdk/test/lib/jvmti/jvmti_common.h b/test/lib/jdk/test/lib/jvmti/jvmti_common.h
new file mode 100644
index 0000000..42455a9
--- /dev/null
+++ b/test/lib/jdk/test/lib/jvmti/jvmti_common.h
@@ -0,0 +1,910 @@
+/*
+ * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef JVMTI_COMMON_H
+#define JVMTI_COMMON_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <ctype.h>
+
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <unistd.h>
+#endif
+
+#include "jvmti.h"
+
+/**
+ * Additional Java basic types
+ */
+
+#ifdef _WIN32
+    typedef unsigned __int64 julong;
+#else
+    typedef unsigned long long julong;
+#endif
+
+#define LOG(...) \
+  { \
+    printf(__VA_ARGS__); \
+    fflush(stdout); \
+  }
+
+#define COMPLAIN LOG
+
+
+const char* TranslateState(jint flags);
+const char* TranslateError(jvmtiError err);
+
+static jvmtiExtensionFunction GetVirtualThread_func = NULL;
+static jvmtiExtensionFunction GetCarrierThread_func = NULL;
+
+/**
+ * Convert the digits of the given value argument to a null-terminated
+ * character string and store the result (up to 32 bytes) in string.
+ * If value is negative, the first character of the stored string is
+ * the minus sign (-). The function returns a pointer to the begining
+ * of the result string.
+ */
+char* jlong_to_string(jlong value, char *string) {
+  char buffer[32];
+  char *pbuf, *pstr;
+
+  pstr = string;
+  if (value == 0) {
+    *pstr++ = '0';
+  } else {
+    if (value < 0) {
+      *pstr++ = '-';
+      value = -value;
+    }
+    pbuf = buffer;
+    while (value != 0) {
+      *pbuf++ = '0' + (char)(value % 10);
+      value = value / 10;
+    }
+    while (pbuf != buffer) {
+      *pstr++ = *--pbuf;
+    }
+  }
+  *pstr = '\0';
+
+  return string;
+}
+
+/**
+ * Convert the digits of the given value argument to a null-terminated
+ * character string and store the result (up to 32 bytes) in string.
+ * The function returns a pointer to the begining of the result string.
+ */
+char* julong_to_string(julong value, char *string) {
+    char buffer[32];
+    char *pbuf, *pstr;
+
+    pstr = string;
+    if (value == 0) {
+        *pstr++ = '0';
+    } else {
+        pbuf = buffer;
+        while (value != 0) {
+            *pbuf++ = '0' + (char)(value % 10);
+            value = value / 10;
+        }
+        while (pbuf != buffer) {
+            *pstr++ = *--pbuf;
+        }
+    }
+    *pstr = '\0';
+
+    return string;
+}
+
+static void
+fatal(JNIEnv* jni, const char* msg) {
+  jni->FatalError(msg);
+}
+
+
+static void
+check_jvmti_status(JNIEnv* jni, jvmtiError err, const char* msg) {
+  if (err != JVMTI_ERROR_NONE) {
+    LOG("check_jvmti_status: JVMTI function returned error: %s (%d)\n", TranslateError(err), err);
+    jni->FatalError(msg);
+  }
+}
+
+/* JVMTI helper wrappers. Check errors and fail or return null if jvmti operation failed. */
+
+// Monitors often created in Agent_Initialize(..) where JNIEnv* jni doesn't exist.
+jrawMonitorID
+create_raw_monitor(jvmtiEnv *jvmti, const char* name) {
+  jrawMonitorID lock;
+  jvmtiError err = jvmti->CreateRawMonitor(name, &lock);
+  if (err != JVMTI_ERROR_NONE) {
+    return nullptr;
+  }
+  return lock;
+}
+
+void
+destroy_raw_monitor(jvmtiEnv *jvmti, JNIEnv *jni, jrawMonitorID lock) {
+  check_jvmti_status(jni, jvmti->DestroyRawMonitor(lock), "DestroyRawMonitor failed.");
+}
+
+class RawMonitorLocker {
+ private:
+  jvmtiEnv* _jvmti;
+  JNIEnv* _jni;
+  jrawMonitorID _monitor;
+
+ public:
+  RawMonitorLocker(jvmtiEnv *jvmti,JNIEnv* jni, jrawMonitorID monitor):_jvmti(jvmti), _jni(jni), _monitor(monitor) {
+    check_jvmti_status(_jni, _jvmti->RawMonitorEnter(_monitor), "Fatal Error in RawMonitorEnter.");
+  }
+
+  ~RawMonitorLocker() {
+    check_jvmti_status(_jni, _jvmti->RawMonitorExit(_monitor), "Fatal Error in RawMonitorEnter.");
+  }
+
+  void wait(jlong millis) {
+    check_jvmti_status(_jni, _jvmti->RawMonitorWait(_monitor, millis), "Fatal Error in RawMonitorWait.");
+  }
+
+  void wait() {
+    wait(0);
+  }
+
+  void notify() {
+    check_jvmti_status(_jni, _jvmti->RawMonitorNotify(_monitor), "Fatal Error in RawMonitorNotify.");
+  }
+
+  void notify_all() {
+    check_jvmti_status(_jni, _jvmti->RawMonitorNotifyAll(_monitor), "Fatal Error in RawMonitorNotifyAll.");
+  }
+
+};
+
+static void
+deallocate(jvmtiEnv *jvmti, JNIEnv* jni, void* ptr) {
+  jvmtiError err = jvmti->Deallocate((unsigned char*)ptr);
+  check_jvmti_status(jni, err, "deallocate: error in JVMTI Deallocate call");
+}
+
+static char*
+get_method_class_name(jvmtiEnv *jvmti, JNIEnv* jni, jmethodID method) {
+  jclass klass = NULL;
+  char*  cname = NULL;
+  char*  result = NULL;
+  jvmtiError err;
+
+  err = jvmti->GetMethodDeclaringClass(method, &klass);
+  check_jvmti_status(jni, err, "get_method_class_name: error in JVMTI GetMethodDeclaringClass");
+
+  err = jvmti->GetClassSignature(klass, &cname, NULL);
+  check_jvmti_status(jni, err, "get_method_class_name: error in JVMTI GetClassSignature");
+
+  size_t len = strlen(cname) - 2; // get rid of leading 'L' and trailing ';'
+
+  err = jvmti->Allocate((jlong)(len + 1), (unsigned char**)&result);
+  check_jvmti_status(jni, err, "get_method_class_name: error in JVMTI Allocate");
+
+  strncpy(result, cname + 1, len); // skip leading 'L'
+  result[len] = '\0';
+  deallocate(jvmti, jni, (void*)cname);
+  return result;
+}
+
+
+static void
+print_method(jvmtiEnv *jvmti, JNIEnv* jni, jmethodID method, jint depth) {
+  char*  cname = NULL;
+  char*  mname = NULL;
+  char*  msign = NULL;
+  jvmtiError err;
+
+  cname = get_method_class_name(jvmti, jni, method);
+
+  err = jvmti->GetMethodName(method, &mname, &msign, NULL);
+  check_jvmti_status(jni, err, "print_method: error in JVMTI GetMethodName");
+
+  LOG("%2d: %s: %s%s\n", depth, cname, mname, msign);
+  fflush(0);
+  deallocate(jvmti, jni, (void*)cname);
+  deallocate(jvmti, jni, (void*)mname);
+  deallocate(jvmti, jni, (void*)msign);
+}
+
+void
+print_thread_info(jvmtiEnv *jvmti, JNIEnv* jni, jthread thread_obj) {
+  jvmtiThreadInfo thread_info;
+  jint thread_state;
+  check_jvmti_status(jni, jvmti->GetThreadInfo(thread_obj, &thread_info), "Error in GetThreadInfo");
+  check_jvmti_status(jni, jvmti->GetThreadState(thread_obj, &thread_state), "Error in GetThreadInfo");
+  const char* state = TranslateState(thread_state);
+  LOG("Thread: %p, name: %s, state(%x): %s, attr: %s\n", thread_obj, thread_info.name, thread_state, TranslateState(thread_state),
+         (thread_info.is_daemon ? "daemon": ""));
+}
+
+static void
+print_stack_trace_frames(jvmtiEnv *jvmti, JNIEnv *jni, jint count, jvmtiFrameInfo *frames) {
+  LOG("JVMTI Stack Trace: frame count: %d\n", count);
+  for (int depth = 0; depth < count; depth++) {
+    print_method(jvmti, jni, frames[depth].method, depth);
+  }
+  LOG("\n");
+}
+
+static jint
+get_frame_count(jvmtiEnv *jvmti, JNIEnv* jni, jthread thread) {
+  jint frame_count;
+  jvmtiError err = jvmti->GetFrameCount(thread, &frame_count);
+  check_jvmti_status(jni, err, "get_frame_count: error in JVMTI GetFrameCount call");
+  return frame_count;
+}
+
+static jvmtiThreadInfo
+get_thread_info(jvmtiEnv *jvmti, JNIEnv* jni, jthread thread) {
+  jvmtiThreadInfo thr_info;
+  jvmtiError err = jvmti->GetThreadInfo(thread, &thr_info);
+  check_jvmti_status(jni, err, "get_thread_info: error in JVMTI GetThreadInfo call");
+  return thr_info;
+}
+
+static jint
+get_thread_state(jvmtiEnv *jvmti, JNIEnv* jni, jthread thread) {
+  jint thread_state;
+  jvmtiError err = jvmti->GetThreadState(thread, &thread_state);
+  check_jvmti_status(jni, err, "get_thread_state: error in JVMTI GetThreadState call");
+  return thread_state;
+}
+
+static char*
+get_thread_name(jvmtiEnv *jvmti, JNIEnv* jni, jthread thread) {
+  jvmtiThreadInfo thr_info;
+  jvmtiError err;
+
+  memset(&thr_info, 0, sizeof(thr_info));
+  err = jvmti->GetThreadInfo(thread, &thr_info);
+  if (err == JVMTI_ERROR_WRONG_PHASE || err == JVMTI_ERROR_THREAD_NOT_ALIVE) {
+    return NULL; // VM or target thread completed its work
+  }
+  check_jvmti_status(jni, err, "get_thread_name: error in JVMTI GetThreadInfo call");
+
+  static const char* UNNAMED_STR = "<Unnamed thread>";
+  static size_t UNNAMED_LEN = strlen(UNNAMED_STR);
+  char* tname = thr_info.name;
+  if (tname == NULL) {
+    err = jvmti->Allocate((jlong)(UNNAMED_LEN + 1), (unsigned char**)&tname);
+    check_jvmti_status(jni, err, "get_method_class_name: error in JVMTI Allocate");
+    strncpy(tname, UNNAMED_STR, UNNAMED_LEN);
+    tname[UNNAMED_LEN] = '\0';
+  }
+  return tname;
+}
+
+static char*
+get_method_name(jvmtiEnv *jvmti, JNIEnv* jni, jmethodID method) {
+  char*  mname = NULL;
+  jvmtiError err;
+
+  err = jvmti->GetMethodName(method, &mname, NULL, NULL);
+  check_jvmti_status(jni, err, "get_method_name: error in JVMTI GetMethodName call");
+
+  return mname;
+}
+
+static jclass
+find_class(jvmtiEnv *jvmti, JNIEnv *jni, jobject loader, const char* cname) {
+  jclass *classes = NULL;
+  jint count = 0;
+  jvmtiError err;
+
+  err = jvmti->GetClassLoaderClasses(loader, &count, &classes);
+  check_jvmti_status(jni, err, "find_class: error in JVMTI GetClassLoaderClasses");
+
+  // Find the jmethodID of the specified method
+  while (--count >= 0) {
+    char* name = NULL;
+    jclass klass = classes[count];
+
+    err = jvmti->GetClassSignature(klass, &name, NULL);
+    check_jvmti_status(jni, err, "find_class: error in JVMTI GetClassSignature call");
+
+    bool found = (strcmp(name, cname) == 0);
+    deallocate(jvmti, jni, (void*)name);
+    if (found) {
+      return klass;
+    }
+  }
+  return NULL;
+}
+
+static jmethodID
+find_method(jvmtiEnv *jvmti, JNIEnv *jni, jclass klass, const char* mname) {
+  jmethodID *methods = NULL;
+  jmethodID method = NULL;
+  jint count = 0;
+  jvmtiError err;
+
+  err = jvmti->GetClassMethods(klass, &count, &methods);
+  check_jvmti_status(jni, err, "find_method: error in JVMTI GetClassMethods");
+
+  // Find the jmethodID of the specified method
+  while (--count >= 0) {
+    char* name = NULL;
+
+    jmethodID meth = methods[count];
+
+    err = jvmti->GetMethodName(meth, &name, NULL, NULL);
+    check_jvmti_status(jni, err, "find_method: error in JVMTI GetMethodName call");
+
+    bool found = (strcmp(name, mname) == 0);
+    deallocate(jvmti, jni, (void*)name);
+    if (found) {
+      method = meth;
+      break;
+    }
+  }
+  deallocate(jvmti, jni, (void*)methods);
+  return method;
+}
+
+#define MAX_FRAME_COUNT_PRINT_STACK_TRACE 200
+
+static void
+print_current_stack_trace(jvmtiEnv *jvmti, JNIEnv* jni) {
+  jvmtiFrameInfo frames[MAX_FRAME_COUNT_PRINT_STACK_TRACE];
+  jint count = 0;
+
+  jvmtiError err = jvmti->GetStackTrace(NULL, 0, MAX_FRAME_COUNT_PRINT_STACK_TRACE, frames, &count);
+  check_jvmti_status(jni, err, "print_stack_trace: error in JVMTI GetStackTrace");
+
+  LOG("JVMTI Stack Trace for current thread: frame count: %d\n", count);
+  for (int depth = 0; depth < count; depth++) {
+    print_method(jvmti, jni, frames[depth].method, depth);
+  }
+  LOG("\n");
+}
+
+static void
+print_stack_trace(jvmtiEnv *jvmti, JNIEnv* jni, jthread thread) {
+  jvmtiFrameInfo frames[MAX_FRAME_COUNT_PRINT_STACK_TRACE];
+  char* tname = get_thread_name(jvmti, jni, thread);
+  jint count = 0;
+
+  jvmtiError err = jvmti->GetStackTrace(thread, 0, MAX_FRAME_COUNT_PRINT_STACK_TRACE, frames, &count);
+  check_jvmti_status(jni, err, "print_stack_trace: error in JVMTI GetStackTrace");
+
+  LOG("JVMTI Stack Trace for thread %s: frame count: %d\n", tname, count);
+  for (int depth = 0; depth < count; depth++) {
+    print_method(jvmti, jni, frames[depth].method, depth);
+  }
+  deallocate(jvmti, jni, (void*)tname);
+  LOG("\n");
+}
+
+
+static void suspend_thread(jvmtiEnv *jvmti, JNIEnv* jni, jthread thread) {
+  check_jvmti_status(jni, jvmti->SuspendThread(thread), "error in JVMTI SuspendThread");
+}
+
+static void resume_thread(jvmtiEnv *jvmti, JNIEnv* jni, jthread thread) {
+  check_jvmti_status(jni, jvmti->ResumeThread(thread), "error in JVMTI ResumeThread");
+}
+
+static jthread get_current_thread(jvmtiEnv *jvmti, JNIEnv* jni) {
+  jthread thread;
+  check_jvmti_status(jni, jvmti->GetCurrentThread(&thread), "error in JVMTI GetCurrentThread");
+  return thread;
+}
+
+
+
+/* Commonly used helper functions */
+const char*
+TranslateState(jint flags) {
+  static char str[15 * 20];
+
+  if (flags == 0) {
+    return "<none>";
+  }
+  str[0] = '\0';
+
+  if (flags & JVMTI_THREAD_STATE_ALIVE) {
+    strcat(str, " ALIVE");
+  }
+  if (flags & JVMTI_THREAD_STATE_TERMINATED) {
+    strcat(str, " TERMINATED");
+  }
+  if (flags & JVMTI_THREAD_STATE_RUNNABLE) {
+    strcat(str, " RUNNABLE");
+  }
+  if (flags & JVMTI_THREAD_STATE_WAITING) {
+    strcat(str, " WAITING");
+  }
+  if (flags & JVMTI_THREAD_STATE_WAITING_INDEFINITELY) {
+    strcat(str, " WAITING_INDEFINITELY");
+  }
+  if (flags & JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT) {
+    strcat(str, " WAITING_WITH_TIMEOUT");
+  }
+  if (flags & JVMTI_THREAD_STATE_SLEEPING) {
+    strcat(str, " SLEEPING");
+  }
+  if (flags & JVMTI_THREAD_STATE_IN_OBJECT_WAIT) {
+    strcat(str, " IN_OBJECT_WAIT");
+  }
+  if (flags & JVMTI_THREAD_STATE_PARKED) {
+    strcat(str, " PARKED");
+  }
+  if (flags & JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER) {
+    strcat(str, " BLOCKED_ON_MONITOR_ENTER");
+  }
+  if (flags & JVMTI_THREAD_STATE_SUSPENDED) {
+    strcat(str, " SUSPENDED");
+  }
+  if (flags & JVMTI_THREAD_STATE_INTERRUPTED) {
+    strcat(str, " INTERRUPTED");
+  }
+  if (flags & JVMTI_THREAD_STATE_IN_NATIVE) {
+    strcat(str, " IN_NATIVE");
+  }
+  return str;
+}
+
+const char*
+TranslateEvent(jvmtiEvent event_type) {
+    switch (event_type) {
+    case JVMTI_EVENT_VM_INIT:
+        return ("JVMTI_EVENT_VM_INIT");
+    case JVMTI_EVENT_VM_DEATH:
+        return ("JVMTI_EVENT_VM_DEATH");
+    case JVMTI_EVENT_THREAD_START:
+        return ("JVMTI_EVENT_THREAD_START");
+    case JVMTI_EVENT_THREAD_END:
+        return ("JVMTI_EVENT_THREAD_END");
+    case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK:
+        return ("JVMTI_EVENT_CLASS_FILE_LOAD_HOOK");
+    case JVMTI_EVENT_CLASS_LOAD:
+        return ("JVMTI_EVENT_CLASS_LOAD");
+    case JVMTI_EVENT_CLASS_PREPARE:
+        return ("JVMTI_EVENT_CLASS_PREPARE");
+    case JVMTI_EVENT_VM_START:
+        return ("JVMTI_EVENT_VM_START");
+    case JVMTI_EVENT_EXCEPTION:
+        return ("JVMTI_EVENT_EXCEPTION");
+    case JVMTI_EVENT_EXCEPTION_CATCH:
+        return ("JVMTI_EVENT_EXCEPTION_CATCH");
+    case JVMTI_EVENT_SINGLE_STEP:
+        return ("JVMTI_EVENT_SINGLE_STEP");
+    case JVMTI_EVENT_FRAME_POP:
+        return ("JVMTI_EVENT_FRAME_POP");
+    case JVMTI_EVENT_BREAKPOINT:
+        return ("JVMTI_EVENT_BREAKPOINT");
+    case JVMTI_EVENT_FIELD_ACCESS:
+        return ("JVMTI_EVENT_FIELD_ACCESS");
+    case JVMTI_EVENT_FIELD_MODIFICATION:
+        return ("JVMTI_EVENT_FIELD_MODIFICATION");
+    case JVMTI_EVENT_METHOD_ENTRY:
+        return ("JVMTI_EVENT_METHOD_ENTRY");
+    case JVMTI_EVENT_METHOD_EXIT:
+        return ("JVMTI_EVENT_METHOD_EXIT");
+    case JVMTI_EVENT_NATIVE_METHOD_BIND:
+        return ("JVMTI_EVENT_NATIVE_METHOD_BIND");
+    case JVMTI_EVENT_COMPILED_METHOD_LOAD:
+        return ("JVMTI_EVENT_COMPILED_METHOD_LOAD");
+    case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
+        return ("JVMTI_EVENT_COMPILED_METHOD_UNLOAD");
+    case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
+        return ("JVMTI_EVENT_DYNAMIC_CODE_GENERATED");
+    case JVMTI_EVENT_DATA_DUMP_REQUEST:
+        return ("JVMTI_EVENT_DATA_DUMP_REQUEST");
+    case JVMTI_EVENT_MONITOR_WAIT:
+        return ("JVMTI_EVENT_MONITOR_WAIT");
+    case JVMTI_EVENT_MONITOR_WAITED:
+        return ("JVMTI_EVENT_MONITOR_WAITED");
+    case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
+        return ("JVMTI_EVENT_MONITOR_CONTENDED_ENTER");
+    case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
+        return ("JVMTI_EVENT_MONITOR_CONTENDED_ENTERED");
+    case JVMTI_EVENT_GARBAGE_COLLECTION_START:
+        return ("JVMTI_EVENT_GARBAGE_COLLECTION_START");
+    case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
+        return ("JVMTI_EVENT_GARBAGE_COLLECTION_FINISH");
+    case JVMTI_EVENT_OBJECT_FREE:
+        return ("JVMTI_EVENT_OBJECT_FREE");
+    case JVMTI_EVENT_VM_OBJECT_ALLOC:
+        return ("JVMTI_EVENT_VM_OBJECT_ALLOC");
+    default:
+        return ("<unknown event>");
+    }
+}
+
+const char*
+TranslateError(jvmtiError err) {
+    switch (err) {
+    case JVMTI_ERROR_NONE:
+        return ("JVMTI_ERROR_NONE");
+    case JVMTI_ERROR_INVALID_THREAD:
+        return ("JVMTI_ERROR_INVALID_THREAD");
+    case JVMTI_ERROR_INVALID_THREAD_GROUP:
+        return ("JVMTI_ERROR_INVALID_THREAD_GROUP");
+    case JVMTI_ERROR_INVALID_PRIORITY:
+        return ("JVMTI_ERROR_INVALID_PRIORITY");
+    case JVMTI_ERROR_THREAD_NOT_SUSPENDED:
+        return ("JVMTI_ERROR_THREAD_NOT_SUSPENDED");
+    case JVMTI_ERROR_THREAD_SUSPENDED:
+        return ("JVMTI_ERROR_THREAD_SUSPENDED");
+    case JVMTI_ERROR_THREAD_NOT_ALIVE:
+        return ("JVMTI_ERROR_THREAD_NOT_ALIVE");
+    case JVMTI_ERROR_INVALID_OBJECT:
+        return ("JVMTI_ERROR_INVALID_OBJECT");
+    case JVMTI_ERROR_INVALID_CLASS:
+        return ("JVMTI_ERROR_INVALID_CLASS");
+    case JVMTI_ERROR_CLASS_NOT_PREPARED:
+        return ("JVMTI_ERROR_CLASS_NOT_PREPARED");
+    case JVMTI_ERROR_INVALID_METHODID:
+        return ("JVMTI_ERROR_INVALID_METHODID");
+    case JVMTI_ERROR_INVALID_LOCATION:
+        return ("JVMTI_ERROR_INVALID_LOCATION");
+    case JVMTI_ERROR_INVALID_FIELDID:
+        return ("JVMTI_ERROR_INVALID_FIELDID");
+    case JVMTI_ERROR_NO_MORE_FRAMES:
+        return ("JVMTI_ERROR_NO_MORE_FRAMES");
+    case JVMTI_ERROR_OPAQUE_FRAME:
+        return ("JVMTI_ERROR_OPAQUE_FRAME");
+    case JVMTI_ERROR_TYPE_MISMATCH:
+        return ("JVMTI_ERROR_TYPE_MISMATCH");
+    case JVMTI_ERROR_INVALID_SLOT:
+        return ("JVMTI_ERROR_INVALID_SLOT");
+    case JVMTI_ERROR_DUPLICATE:
+        return ("JVMTI_ERROR_DUPLICATE");
+    case JVMTI_ERROR_NOT_FOUND:
+        return ("JVMTI_ERROR_NOT_FOUND");
+    case JVMTI_ERROR_INVALID_MONITOR:
+        return ("JVMTI_ERROR_INVALID_MONITOR");
+    case JVMTI_ERROR_NOT_MONITOR_OWNER:
+        return ("JVMTI_ERROR_NOT_MONITOR_OWNER");
+    case JVMTI_ERROR_INTERRUPT:
+        return ("JVMTI_ERROR_INTERRUPT");
+    case JVMTI_ERROR_INVALID_CLASS_FORMAT:
+        return ("JVMTI_ERROR_INVALID_CLASS_FORMAT");
+    case JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION:
+        return ("JVMTI_ERROR_CIRCULAR_CLASS_DEFINITION");
+    case JVMTI_ERROR_FAILS_VERIFICATION:
+        return ("JVMTI_ERROR_FAILS_VERIFICATION");
+    case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED:
+        return ("JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_ADDED");
+    case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED:
+        return ("JVMTI_ERROR_UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED");
+    case JVMTI_ERROR_INVALID_TYPESTATE:
+        return ("JVMTI_ERROR_INVALID_TYPESTATE");
+    case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED:
+        return ("JVMTI_ERROR_UNSUPPORTED_REDEFINITION_HIERARCHY_CHANGED");
+    case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED:
+        return ("JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_DELETED");
+    case JVMTI_ERROR_UNSUPPORTED_VERSION:
+        return ("JVMTI_ERROR_UNSUPPORTED_VERSION");
+    case JVMTI_ERROR_NAMES_DONT_MATCH:
+        return ("JVMTI_ERROR_NAMES_DONT_MATCH");
+    case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED:
+        return ("JVMTI_ERROR_UNSUPPORTED_REDEFINITION_CLASS_MODIFIERS_CHANGED");
+    case JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED:
+        return ("JVMTI_ERROR_UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED");
+    case JVMTI_ERROR_UNMODIFIABLE_CLASS:
+        return ("JVMTI_ERROR_UNMODIFIABLE_CLASS");
+    case JVMTI_ERROR_NOT_AVAILABLE:
+        return ("JVMTI_ERROR_NOT_AVAILABLE");
+    case JVMTI_ERROR_MUST_POSSESS_CAPABILITY:
+        return ("JVMTI_ERROR_MUST_POSSESS_CAPABILITY");
+    case JVMTI_ERROR_NULL_POINTER:
+        return ("JVMTI_ERROR_NULL_POINTER");
+    case JVMTI_ERROR_ABSENT_INFORMATION:
+        return ("JVMTI_ERROR_ABSENT_INFORMATION");
+    case JVMTI_ERROR_INVALID_EVENT_TYPE:
+        return ("JVMTI_ERROR_INVALID_EVENT_TYPE");
+    case JVMTI_ERROR_ILLEGAL_ARGUMENT:
+        return ("JVMTI_ERROR_ILLEGAL_ARGUMENT");
+    case JVMTI_ERROR_NATIVE_METHOD:
+        return ("JVMTI_ERROR_NATIVE_METHOD");
+    case JVMTI_ERROR_OUT_OF_MEMORY:
+        return ("JVMTI_ERROR_OUT_OF_MEMORY");
+    case JVMTI_ERROR_ACCESS_DENIED:
+        return ("JVMTI_ERROR_ACCESS_DENIED");
+    case JVMTI_ERROR_WRONG_PHASE:
+        return ("JVMTI_ERROR_WRONG_PHASE");
+    case JVMTI_ERROR_INTERNAL:
+        return ("JVMTI_ERROR_INTERNAL");
+    case JVMTI_ERROR_UNATTACHED_THREAD:
+        return ("JVMTI_ERROR_UNATTACHED_THREAD");
+    case JVMTI_ERROR_INVALID_ENVIRONMENT:
+        return ("JVMTI_ERROR_INVALID_ENVIRONMENT");
+    default:
+        return ("<unknown error>");
+    }
+}
+
+const char*
+TranslatePhase(jvmtiPhase phase) {
+    switch (phase) {
+    case JVMTI_PHASE_ONLOAD:
+        return ("JVMTI_PHASE_ONLOAD");
+    case JVMTI_PHASE_PRIMORDIAL:
+        return ("JVMTI_PHASE_PRIMORDIAL");
+    case JVMTI_PHASE_START:
+        return ("JVMTI_PHASE_START");
+    case JVMTI_PHASE_LIVE:
+        return ("JVMTI_PHASE_LIVE");
+    case JVMTI_PHASE_DEAD:
+        return ("JVMTI_PHASE_DEAD");
+    default:
+        return ("<unknown phase>");
+    }
+}
+
+const char*
+TranslateRootKind(jvmtiHeapRootKind root) {
+    switch (root) {
+    case JVMTI_HEAP_ROOT_JNI_GLOBAL:
+        return ("JVMTI_HEAP_ROOT_JNI_GLOBAL");
+    case JVMTI_HEAP_ROOT_JNI_LOCAL:
+        return ("JVMTI_HEAP_ROOT_JNI_LOCAL");
+    case JVMTI_HEAP_ROOT_SYSTEM_CLASS:
+        return ("JVMTI_HEAP_ROOT_SYSTEM_CLASS");
+    case JVMTI_HEAP_ROOT_MONITOR:
+        return ("JVMTI_HEAP_ROOT_MONITOR");
+    case JVMTI_HEAP_ROOT_STACK_LOCAL:
+        return ("JVMTI_HEAP_ROOT_STACK_LOCAL");
+    case JVMTI_HEAP_ROOT_THREAD:
+        return ("JVMTI_HEAP_ROOT_THREAD");
+    case JVMTI_HEAP_ROOT_OTHER:
+        return ("JVMTI_HEAP_ROOT_OTHER");
+    default:
+        return ("<unknown root kind>");
+    }
+}
+
+const char*
+TranslateObjectRefKind(jvmtiObjectReferenceKind ref) {
+    switch (ref) {
+    case JVMTI_REFERENCE_CLASS:
+        return ("JVMTI_REFERENCE_CLASS");
+    case JVMTI_REFERENCE_FIELD:
+        return ("JVMTI_REFERENCE_FIELD");
+    case JVMTI_REFERENCE_ARRAY_ELEMENT:
+        return ("JVMTI_REFERENCE_ARRAY_ELEMENT");
+    case JVMTI_REFERENCE_CLASS_LOADER:
+        return ("JVMTI_REFERENCE_CLASS_LOADER");
+    case JVMTI_REFERENCE_SIGNERS:
+        return ("JVMTI_REFERENCE_SIGNERS");
+    case JVMTI_REFERENCE_PROTECTION_DOMAIN:
+        return ("JVMTI_REFERENCE_PROTECTION_DOMAIN");
+    case JVMTI_REFERENCE_INTERFACE:
+        return ("JVMTI_REFERENCE_INTERFACE");
+    case JVMTI_REFERENCE_STATIC_FIELD:
+        return ("JVMTI_REFERENCE_STATIC_FIELD");
+    case JVMTI_REFERENCE_CONSTANT_POOL:
+        return ("JVMTI_REFERENCE_CONSTANT_POOL");
+    default:
+        return ("<unknown reference kind>");
+    }
+}
+
+int
+isThreadExpected(jvmtiEnv *jvmti, jthread thread) {
+  static const char *vm_jfr_buffer_thread_name = "VM JFR Buffer Thread";
+  static const char *jfr_request_timer_thread_name = "JFR request timer";
+  static const char *graal_management_bean_registration_thread_name =
+                        "HotSpotGraalManagement Bean Registration";
+  static const char *graal_compiler_thread_name_prefix = "JVMCI CompilerThread";
+  static const size_t graal_prefix_length = strlen(graal_compiler_thread_name_prefix);
+
+  static const char *unparker_thread_name_prefix = "VirtualThread-unparker";
+  static const size_t unparker_prefix_length = strlen(unparker_thread_name_prefix);
+
+
+  jvmtiThreadInfo threadinfo;
+  jvmtiError err = jvmti->GetThreadInfo(thread, &threadinfo);
+  if (err != JVMTI_ERROR_NONE) {
+    return 0;
+  }
+  if (strcmp(threadinfo.name, vm_jfr_buffer_thread_name) == 0) {
+    return 0;
+  }
+  if (strcmp(threadinfo.name, jfr_request_timer_thread_name) == 0) {
+    return 0;
+  }
+  if (strcmp(threadinfo.name, graal_management_bean_registration_thread_name) == 0)
+    return 0;
+
+  if ((strlen(threadinfo.name) > graal_prefix_length) &&
+      strncmp(threadinfo.name, graal_compiler_thread_name_prefix, graal_prefix_length) == 0) {
+    return 0;
+  }
+  if (strncmp(threadinfo.name, unparker_thread_name_prefix, unparker_prefix_length) == 0) {
+    return 0;
+  }
+  return 1;
+}
+
+jthread find_thread_by_name(jvmtiEnv* jvmti, JNIEnv* jni, const char name[]) {
+  jthread* threads = NULL;
+  jint count = 0;
+  jthread found_thread = NULL;
+
+  if (name == NULL) {
+    return NULL;
+  }
+
+  check_jvmti_status(jni, jvmti->GetAllThreads(&count, &threads), "");
+
+  for (int i = 0; i < count; i++) {
+    jvmtiThreadInfo info = get_thread_info(jvmti, jni, threads[i]);
+    if (info.name != NULL && strcmp(name, info.name) == 0) {
+      found_thread = threads[i];
+      break;
+    }
+  }
+
+  check_jvmti_status(jni, jvmti->Deallocate((unsigned char*)threads), "");
+
+  found_thread = (jthread) jni->NewGlobalRef(found_thread);
+  return found_thread;
+}
+
+/*
+ * JVMTI Extension Mechanism
+ */
+static const jvmtiEvent
+  EXT_EVENT_VIRTUAL_THREAD_MOUNT   = (jvmtiEvent)((int)JVMTI_MIN_EVENT_TYPE_VAL - 2),
+  EXT_EVENT_VIRTUAL_THREAD_UNMOUNT = (jvmtiEvent)((int)JVMTI_MIN_EVENT_TYPE_VAL - 3);
+
+static jvmtiExtensionFunction
+find_ext_function(jvmtiEnv* jvmti, JNIEnv* jni, const char* fname) {
+  jint extCount = 0;
+  jvmtiExtensionFunctionInfo* extList = NULL;
+
+  jvmtiError err = jvmti->GetExtensionFunctions(&extCount, &extList);
+  check_jvmti_status(jni, err, "jvmti_common find_ext_function: Error in JVMTI GetExtensionFunctions");
+
+  for (int i = 0; i < extCount; i++) {
+    if (strstr(extList[i].id, (char*)fname) != NULL) {
+      return extList[i].func;
+    }
+  }
+  return NULL;
+}
+
+static jvmtiError
+GetVirtualThread(jvmtiEnv* jvmti, JNIEnv* jni, jthread cthread, jthread* vthread_ptr) {
+  if (GetVirtualThread_func == NULL) { // lazily initialize function pointer
+    GetVirtualThread_func = find_ext_function(jvmti, jni, "GetVirtualThread");
+  }
+  jvmtiError err = (*GetVirtualThread_func)(jvmti, cthread, vthread_ptr);
+
+  return err;
+}
+
+static jvmtiError
+GetCarrierThread(jvmtiEnv* jvmti, JNIEnv* jni, jthread vthread, jthread* cthread_ptr) {
+  if (GetCarrierThread_func == NULL) { // lazily initialize function pointer
+    GetCarrierThread_func = find_ext_function(jvmti, jni, "GetCarrierThread");
+  }
+  jvmtiError err = (*GetCarrierThread_func)(jvmti, vthread, cthread_ptr);
+
+  return err;
+}
+
+static jthread
+get_virtual_thread(jvmtiEnv* jvmti, JNIEnv* jni, jthread cthread) {
+  jthread vthread = NULL;
+  jvmtiError err = GetVirtualThread(jvmti, jni, cthread, &vthread);
+  check_jvmti_status(jni, err, "jvmti_common get_virtual_thread: Error in JVMTI extension GetVirtualThread");
+  return vthread;
+}
+
+static jthread
+get_carrier_thread(jvmtiEnv* jvmti, JNIEnv* jni, jthread vthread) {
+  jthread cthread = NULL;
+  jvmtiError err = GetCarrierThread(jvmti, jni, vthread, &cthread);
+  check_jvmti_status(jni, err, "jvmti_common get_carrier_thread: Error in JVMTI extension GetCarrierThread");
+
+  return cthread;
+}
+
+static jvmtiExtensionEventInfo*
+find_ext_event(jvmtiEnv* jvmti, const char* ename) {
+  jint extCount = 0;
+  jvmtiExtensionEventInfo* extList = NULL;
+
+  jvmtiError err = jvmti->GetExtensionEvents(&extCount, &extList);
+  if (err != JVMTI_ERROR_NONE) {
+    LOG("jvmti_common find_ext_event: Error in JVMTI GetExtensionFunctions: %s(%d)\n",TranslateError(err), err);
+    return NULL;
+  }
+  for (int i = 0; i < extCount; i++) {
+    if (strstr(extList[i].id, (char*)ename) != NULL) {
+      return &extList[i];
+    }
+  }
+  return NULL;
+}
+
+static jvmtiError
+set_ext_event_callback(jvmtiEnv* jvmti,  const char* ename, jvmtiExtensionEvent callback) {
+  jvmtiExtensionEventInfo* info = find_ext_event(jvmti, ename);
+
+  if (info == NULL) {
+    LOG("jvmti_common set_ext_event_callback: Extension event was not found: %s\n", ename);
+    return JVMTI_ERROR_NOT_AVAILABLE;
+  }
+  jvmtiError err = jvmti->SetExtensionEventCallback(info->extension_event_index, callback);
+  return err;
+}
+
+/** Enable or disable given events. */
+
+static jvmtiError
+set_event_notification_mode(jvmtiEnv* jvmti, jvmtiEventMode mode, jvmtiEvent event_type, jthread event_thread) {
+  jvmtiError err = jvmti->SetEventNotificationMode(mode, event_type, event_thread);
+  return err;
+}
+
+static void
+set_event_notification_mode(jvmtiEnv* jvmti, JNIEnv* jni, jvmtiEventMode mode, jvmtiEvent event_type, jthread event_thread) {
+  jvmtiError err = jvmti->SetEventNotificationMode(mode, event_type, event_thread);
+  check_jvmti_status(jni, err, "jvmti_common set_event_notification_mode: Error in JVMTI SetEventNotificationMode");
+}
+
+int
+enable_events_notifications(jvmtiEnv* jvmti, JNIEnv* jni, jvmtiEventMode enable, int size, jvmtiEvent list[], jthread thread) {
+  for (int i = 0; i < size; i++) {
+    check_jvmti_status(jni, jvmti->SetEventNotificationMode(enable, list[i], thread), "");
+  }
+  return JNI_TRUE;
+}
+
+void
+sleep_ms(int millis) {
+#ifdef _WIN32
+  Sleep(millis);
+#else
+  usleep(1000 * millis);
+#endif
+}
+
+void
+sleep_sec(jlong timeout) {
+  int seconds = (int)((timeout + 999) / 1000);
+#ifdef _WIN32
+  Sleep(1000L * seconds);
+#else
+  sleep(seconds);
+#endif
+}
+
+#endif
diff --git a/test/lib/jdk/test/lib/net/testkeys b/test/lib/jdk/test/lib/net/testkeys
index 4673898..d2818ec 100644
--- a/test/lib/jdk/test/lib/net/testkeys
+++ b/test/lib/jdk/test/lib/net/testkeys
Binary files differ
diff --git a/test/lib/jdk/test/lib/process/Proc.java b/test/lib/jdk/test/lib/process/Proc.java
index def8796..3541f34 100644
--- a/test/lib/jdk/test/lib/process/Proc.java
+++ b/test/lib/jdk/test/lib/process/Proc.java
@@ -113,8 +113,8 @@
 
     private List<String> args = new ArrayList<>();
     private Map<String,String> env = new HashMap<>();
-    private Map<String,String> prop = new HashMap();
-    private Map<String,String> secprop = new HashMap();
+    private Map<String,String> prop = new HashMap<>();
+    private Map<String,String> secprop = new HashMap<>();
     private boolean inheritIO = false;
     private boolean noDump = false;
 
diff --git a/test/lib/jdk/test/lib/process/ProcessTools.java b/test/lib/jdk/test/lib/process/ProcessTools.java
index 2cb5db3..19e3bb5 100644
--- a/test/lib/jdk/test/lib/process/ProcessTools.java
+++ b/test/lib/jdk/test/lib/process/ProcessTools.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -116,12 +116,12 @@
      * <span>The default redirects of STDOUT and STDERR are started</span>
      * <p>
      * It is possible to wait for the process to get to a warmed-up state
-     * via {@linkplain Predicate} condition on the STDOUT
+     * via {@linkplain Predicate} condition on the STDOUT/STDERR
      * </p>
      *
      * @param name           The process name
      * @param processBuilder The process builder
-     * @param linePredicate  The {@linkplain Predicate} to use on the STDOUT
+     * @param linePredicate  The {@linkplain Predicate} to use on the STDOUT and STDERR.
      *                       Used to determine the moment the target app is
      *                       properly warmed-up.
      *                       It can be null - in that case the warmup is skipped.
@@ -146,14 +146,14 @@
      * <span>The default redirects of STDOUT and STDERR are started</span>
      * <p>
      * It is possible to wait for the process to get to a warmed-up state
-     * via {@linkplain Predicate} condition on the STDOUT and monitor the
+     * via {@linkplain Predicate} condition on the STDOUT/STDERR and monitor the
      * in-streams via the provided {@linkplain Consumer}
      * </p>
      *
      * @param name           The process name
      * @param processBuilder The process builder
      * @param lineConsumer   The {@linkplain Consumer} the lines will be forwarded to
-     * @param linePredicate  The {@linkplain Predicate} to use on the STDOUT
+     * @param linePredicate  The {@linkplain Predicate} to use on the STDOUT and STDERR.
      *                       Used to determine the moment the target app is
      *                       properly warmed-up.
      *                       It can be null - in that case the warmup is skipped.
@@ -193,10 +193,14 @@
         CountDownLatch latch = new CountDownLatch(1);
         if (linePredicate != null) {
             StreamPumper.LinePump pump = new StreamPumper.LinePump() {
+                // synchronization between stdout and stderr pumps
+                private final Object sync = new Object();
                 @Override
                 protected void processLine(String line) {
-                    if (latch.getCount() > 0 && linePredicate.test(line)) {
-                        latch.countDown();
+                    synchronized (sync) {
+                        if (latch.getCount() > 0 && linePredicate.test(line)) {
+                            latch.countDown();
+                        }
                     }
                 }
             };
@@ -241,13 +245,13 @@
      * <span>The default redirects of STDOUT and STDERR are started</span>
      * <p>
      * It is possible to wait for the process to get to a warmed-up state
-     * via {@linkplain Predicate} condition on the STDOUT. The warm-up will
-     * wait indefinitely.
+     * via {@linkplain Predicate} condition on the STDOUT/STDERR.
+     * The warm-up will wait indefinitely.
      * </p>
      *
      * @param name           The process name
      * @param processBuilder The process builder
-     * @param linePredicate  The {@linkplain Predicate} to use on the STDOUT
+     * @param linePredicate  The {@linkplain Predicate} to use on the STDOUT and STDERR.
      *                       Used to determine the moment the target app is
      *                       properly warmed-up.
      *                       It can be null - in that case the warmup is skipped.
@@ -428,6 +432,7 @@
      *              the default charset.
      * @return The {@linkplain OutputAnalyzer} instance wrapping the process.
      */
+    @SuppressWarnings("removal")
     public static OutputAnalyzer executeProcess(ProcessBuilder pb, String input,
                                                 Charset cs) throws Exception {
         OutputAnalyzer output = null;
@@ -600,6 +605,7 @@
         return pb;
     }
 
+    @SuppressWarnings("removal")
     private static Process privilegedStart(ProcessBuilder pb) throws IOException {
         try {
             return AccessController.doPrivileged(
diff --git a/test/lib/jdk/test/lib/security/KeyStoreUtils.java b/test/lib/jdk/test/lib/security/KeyStoreUtils.java
index b205de2..aa5be6f 100644
--- a/test/lib/jdk/test/lib/security/KeyStoreUtils.java
+++ b/test/lib/jdk/test/lib/security/KeyStoreUtils.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,7 +31,6 @@
 import java.security.PrivateKey;
 import java.security.cert.Certificate;
 import java.security.cert.CertificateFactory;
-import java.security.KeyStore;
 import java.util.ArrayList;
 import java.util.Base64;
 import java.util.List;
diff --git a/test/lib/jdk/test/lib/security/XMLUtils.java b/test/lib/jdk/test/lib/security/XMLUtils.java
index fa93e3f..4616dfa 100644
--- a/test/lib/jdk/test/lib/security/XMLUtils.java
+++ b/test/lib/jdk/test/lib/security/XMLUtils.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,6 @@
 
 package jdk.test.lib.security;
 
-import jdk.test.lib.Asserts;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
@@ -49,15 +48,14 @@
 import javax.xml.xpath.XPath;
 import javax.xml.xpath.XPathConstants;
 import javax.xml.xpath.XPathFactory;
-import java.io.File;
 import java.io.StringReader;
 import java.io.StringWriter;
 import java.net.URI;
-import java.nio.file.Files;
-import java.nio.file.Path;
 import java.security.*;
 import java.security.cert.X509Certificate;
+import java.security.interfaces.EdECPrivateKey;
 import java.security.interfaces.RSAKey;
+import java.security.spec.NamedParameterSpec;
 import java.security.spec.PSSParameterSpec;
 import java.util.*;
 
@@ -68,37 +66,6 @@
     private static final XMLSignatureFactory FAC =
             XMLSignatureFactory.getInstance("DOM");
 
-    //////////// MAIN as TEST ////////////
-    public static void main(String[] args) throws Exception {
-        var x = "<a><b>c</b>x</a>";
-        var p = Files.write(Path.of("x.xml"), List.of(x));
-        var b = Path.of("").toUri().toString();
-        var d = string2doc(x);
-        // keytool -keystore ks -keyalg ec -storepass changeit -genkeypair -alias a -dname CN=a
-        var pass = "changeit".toCharArray();
-        var ks = KeyStore.getInstance(new File("ks"), pass);
-        var c = (X509Certificate) ks.getCertificate("a");
-        var pr = (PrivateKey) ks.getKey("a", pass);
-        var pu = c.getPublicKey();
-        var s0 = signer(pr); // No KeyInfo
-        var s1 = signer(pr, pu); // KeyInfo is PublicKey
-        var s2 = signer(pr, c); // KeyInfo is X509Data
-        var s3 = signer(ks, "a", pass); // KeyInfo is KeyName
-        var v1 = validator(); // knows nothing
-        var v2 = validator(ks); // knows KeyName
-        Asserts.assertTrue(v1.validate(s0.sign(d), pu)); // need PublicKey
-        Asserts.assertTrue(v1.validate(s1.sign(d))); // can read KeyInfo
-        Asserts.assertTrue(v1.validate(s2.sign(d))); // can read KeyInfo
-        Asserts.assertTrue(v2.validate(s3.sign(d))); // can read KeyInfo
-        Asserts.assertTrue(v2.secureValidation(false).validate(s3.sign(p.toUri()))); // can read KeyInfo
-        Asserts.assertTrue(v2.secureValidation(false).baseURI(b).validate(
-                s3.sign(p.toAbsolutePath().getParent().toUri(), p.getFileName().toUri()))); // can read KeyInfo
-        Asserts.assertTrue(v1.validate(s1.sign("text"))); // plain text
-        Asserts.assertTrue(v1.validate(s1.sign("binary".getBytes()))); // raw data
-        Asserts.assertTrue(v1.validate(s1.signEnveloping(d, "x", "#x")));
-        Asserts.assertTrue(v1.validate(s1.signEnveloping(d, "x", "#xpointer(id('x'))")));
-    }
-
     //////////// CONVERT ////////////
 
     // Converts a Document object to string
@@ -220,38 +187,20 @@
 
     public static class Signer {
 
-        PrivateKey privateKey;  // signer key, never null
+        final PrivateKey privateKey;  // signer key, never null
+
         X509Certificate cert;   // certificate, optional
         PublicKey publicKey;    // public key, optional
         String keyName;         // alias, optional
 
-        SignatureMethod sm;     // default determined by privateKey
-        DigestMethod dm;        // default SHA-256
-        CanonicalizationMethod cm;  // default EXCLUSIVE
-        Transform tr;           // default ENVELOPED
+        String sm = null;       // default determined by privateKey
+        SignatureMethodParameterSpec smSpec = null;
+        String dm = DigestMethod.SHA256;
+        String cm = CanonicalizationMethod.EXCLUSIVE;
+        String tr = Transform.ENVELOPED;
 
-        public Signer(PrivateKey privateKey) throws Exception {
-            this.privateKey = privateKey;
-            dm(DigestMethod.SHA256);
-            tr(Transform.ENVELOPED);
-            cm(CanonicalizationMethod.EXCLUSIVE);
-            String alg = privateKey.getAlgorithm();
-            if (alg.equals("RSASSA-PSS")) {
-                PSSParameterSpec pspec
-                        = (PSSParameterSpec) ((RSAKey) privateKey).getParams();
-                if (pspec != null) {
-                    sm(SignatureMethod.RSA_PSS, new RSAPSSParameterSpec(pspec));
-                } else {
-                    sm(SignatureMethod.RSA_PSS);
-                }
-            } else {
-                sm(switch (privateKey.getAlgorithm()) {
-                    case "RSA" -> SignatureMethod.RSA_SHA256;
-                    case "DSA" -> SignatureMethod.DSA_SHA256;
-                    case "EC" -> SignatureMethod.ECDSA_SHA256;
-                    default -> throw new InvalidKeyException();
-                });
-            }
+        public Signer(PrivateKey privateKey) {
+            this.privateKey = Objects.requireNonNull(privateKey);
         }
 
         // Change KeyInfo source
@@ -273,47 +222,29 @@
 
         // Change various methods
 
-        public Signer tr(String transform) throws Exception {
-            TransformParameterSpec params = null;
-            switch (transform) {
-                case Transform.XPATH:
-                    params = new XPathFilterParameterSpec("//.");
-                    break;
-                case Transform.XPATH2:
-                    params = new XPathFilter2ParameterSpec(
-                            Collections.singletonList(new XPathType("//.",
-                                    XPathType.Filter.INTERSECT)));
-                    break;
-            }
-            tr = FAC.newTransform(transform, params);
+        public Signer tr(String transform) {
+            tr = Objects.requireNonNull(transform);
+            return this;
+        }
+
+        public Signer dm(String method) {
+            dm = Objects.requireNonNull(method);
+            return this;
+        }
+
+        public Signer cm(String method) {
+            cm = Objects.requireNonNull(method);
+            return this;
+        }
+
+        public Signer sm(String method, SignatureMethodParameterSpec spec) {
+            sm = method;
+            smSpec = spec;
             return this;
         }
 
         public Signer sm(String method) throws Exception {
-            sm = FAC.newSignatureMethod(method, null);
-            return this;
-        }
-
-        public Signer dm(String method) throws Exception {
-            dm = FAC.newDigestMethod(method, null);
-            return this;
-        }
-
-        public Signer cm(String method) throws Exception {
-            cm = FAC.newCanonicalizationMethod(method, (C14NMethodParameterSpec) null);
-            return this;
-        }
-
-        public Signer sm(String method, SignatureMethodParameterSpec spec)
-                throws Exception {
-            sm = FAC.newSignatureMethod(method, spec);
-            return this;
-        }
-
-        public Signer dm(String method, DigestMethodParameterSpec spec)
-                throws Exception {
-            dm = FAC.newDigestMethod(method, spec);
-            return this;
+            return sm(method, null);
         }
 
         // Signs different sources
@@ -353,7 +284,7 @@
             Document newDocument = DocumentBuilderFactory.newInstance()
                     .newDocumentBuilder().newDocument();
             FAC.newXMLSignature(
-                    buildSignedInfo(FAC.newReference(ref, dm)),
+                    buildSignedInfo(FAC.newReference(ref, FAC.newDigestMethod(dm, null))),
                     buildKeyInfo(),
                     List.of(FAC.newXMLObject(List.of(new DOMStructure(document.getDocumentElement())),
                             id, null, null)),
@@ -368,7 +299,7 @@
             Document newDocument = DocumentBuilderFactory.newInstance()
                     .newDocumentBuilder().newDocument();
             FAC.newXMLSignature(
-                    buildSignedInfo(FAC.newReference("#object", dm, List.of
+                    buildSignedInfo(FAC.newReference("#object", FAC.newDigestMethod(dm, null), List.of
                             (FAC.newTransform(Transform.BASE64,
                                     (TransformParameterSpec) null)), null, null)),
                     buildKeyInfo(),
@@ -386,9 +317,11 @@
             Document newDocument = DocumentBuilderFactory.newInstance()
                     .newDocumentBuilder().newDocument();
             FAC.newXMLSignature(
-                    buildSignedInfo(FAC.newReference("#object", dm)),
+                    buildSignedInfo(
+                            FAC.newReference("#object", FAC.newDigestMethod(dm, null))),
                     buildKeyInfo(),
-                    List.of(FAC.newXMLObject(List.of(new DOMStructure(newDocument.createTextNode(str))),
+                    List.of(FAC.newXMLObject(
+                            List.of(new DOMStructure(newDocument.createTextNode(str))),
                             "object", null, null)),
                     null,
                     null)
@@ -397,22 +330,61 @@
         }
 
         // Builds a SignedInfo for a string reference
-        private SignedInfo buildSignedInfo(String ref) {
-            return FAC.newSignedInfo(
-                    cm,
-                    sm,
-                    List.of(FAC.newReference(
+        private SignedInfo buildSignedInfo(String ref) throws Exception {
+            return buildSignedInfo(FAC.newReference(
                             ref,
-                            dm,
-                            List.of(tr),
-                            null, null)));
+                            FAC.newDigestMethod(dm, null),
+                            List.of(FAC.newTransform(tr, switch (tr) {
+                                case Transform.XPATH ->
+                                    new XPathFilterParameterSpec("//.");
+                                case Transform.XPATH2 -> new XPathFilter2ParameterSpec(
+                                            Collections.singletonList(new XPathType("//.",
+                                                    XPathType.Filter.INTERSECT)));
+                                default -> null;
+                            })),
+                            null, null));
         }
 
         // Builds a SignedInfo for a Reference
-        private SignedInfo buildSignedInfo(Reference ref) {
+        private SignedInfo buildSignedInfo(Reference ref) throws Exception {
+            SignatureMethod signatureMethod;
+            if (sm == null) {
+                String alg = privateKey.getAlgorithm().toUpperCase(Locale.ROOT);
+                if (alg.equals("RSASSA-PSS")) {
+                    PSSParameterSpec pspec
+                            = (PSSParameterSpec) ((RSAKey) privateKey).getParams();
+                    if (pspec != null) {
+                        signatureMethod = FAC.newSignatureMethod(
+                                SignatureMethod.RSA_PSS, new RSAPSSParameterSpec(pspec));
+                    } else {
+                        signatureMethod = FAC.newSignatureMethod(SignatureMethod.RSA_PSS, null);
+                    }
+                } else {
+                    signatureMethod = FAC.newSignatureMethod(switch (alg) {
+                        case "RSA" -> SignatureMethod.RSA_SHA256;
+                        case "DSA" -> SignatureMethod.DSA_SHA256;
+                        case "EC" -> SignatureMethod.ECDSA_SHA256;
+                        case "ED25519" -> "http://www.w3.org/2021/04/xmldsig-more#eddsa-ed25519";
+                        case "ED448" -> "http://www.w3.org/2021/04/xmldsig-more#eddsa-ed448";
+                        case "EDDSA" -> {
+                            if (privateKey instanceof EdECPrivateKey edsk) {
+                                yield edsk.getParams().getName()
+                                        .equals(NamedParameterSpec.ED25519.getName())
+                                        ? "http://www.w3.org/2021/04/xmldsig-more#eddsa-ed25519"
+                                        : "http://www.w3.org/2021/04/xmldsig-more#eddsa-ed448";
+                            } else {
+                                throw new InvalidKeyException();
+                            }
+                        }
+                        default -> throw new InvalidKeyException();
+                    }, null);
+                }
+            } else {
+                signatureMethod = FAC.newSignatureMethod(sm, smSpec);
+            }
             return FAC.newSignedInfo(
-                    cm,
-                    sm,
+                    FAC.newCanonicalizationMethod(cm, (C14NMethodParameterSpec) null),
+                    signatureMethod,
                     List.of(ref));
         }
 
@@ -518,7 +490,9 @@
                                             AlgorithmMethod method,
                                             XMLCryptoContext context)
                     throws KeySelectorException {
-                Objects.requireNonNull(keyInfo, "Null KeyInfo object!");
+                if (keyInfo == null) {
+                    throw new IllegalArgumentException("Null KeyInfo object!");
+                }
 
                 for (XMLStructure xmlStructure : keyInfo.getContent()) {
                     PublicKey pk;
diff --git a/test/lib/jdk/test/lib/security/timestamp/DefaultRespInterceptor.java b/test/lib/jdk/test/lib/security/timestamp/DefaultRespInterceptor.java
index 8ec9d6f..49f9382 100644
--- a/test/lib/jdk/test/lib/security/timestamp/DefaultRespInterceptor.java
+++ b/test/lib/jdk/test/lib/security/timestamp/DefaultRespInterceptor.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,10 +23,7 @@
 
 package jdk.test.lib.security.timestamp;
 
-import java.math.BigInteger;
 import java.security.cert.X509Certificate;
-import java.time.Instant;
-import java.util.Date;
 import java.util.Objects;
 
 /**
diff --git a/test/lib/jdk/test/lib/security/timestamp/TsaHandler.java b/test/lib/jdk/test/lib/security/timestamp/TsaHandler.java
index b8ec2f2..d42d9f0 100644
--- a/test/lib/jdk/test/lib/security/timestamp/TsaHandler.java
+++ b/test/lib/jdk/test/lib/security/timestamp/TsaHandler.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -39,8 +39,6 @@
 import com.sun.net.httpserver.HttpHandler;
 
 import sun.security.util.KnownOIDs;
-import sun.security.util.SignatureUtil;
-import sun.security.x509.AlgorithmId;
 
 /**
  * A {@link HttpHandler} receiving time-stamping request and returning response.
diff --git a/test/lib/jdk/test/lib/security/timestamp/TsaServer.java b/test/lib/jdk/test/lib/security/timestamp/TsaServer.java
index a4f739d..9bffa1a 100644
--- a/test/lib/jdk/test/lib/security/timestamp/TsaServer.java
+++ b/test/lib/jdk/test/lib/security/timestamp/TsaServer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,6 @@
 import java.io.IOException;
 import java.net.InetSocketAddress;
 import java.security.KeyStore;
-import java.util.Objects;
 
 import com.sun.net.httpserver.HttpServer;
 
diff --git a/test/lib/jdk/test/lib/util/CoreUtils.java b/test/lib/jdk/test/lib/util/CoreUtils.java
index b3521a8..605862d 100644
--- a/test/lib/jdk/test/lib/util/CoreUtils.java
+++ b/test/lib/jdk/test/lib/util/CoreUtils.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -122,6 +122,8 @@
             }
 
             return coreFileLocation; // success!
+        } else {
+            System.out.println("Core file not found. Trying to find a reason why...");
         }
 
         // See if we can figure out the likely reason the core file was not found. Recover from
@@ -143,6 +145,11 @@
                     // We can't generate cores files with hardened binaries on OSX 10.15 and later.
                     throw new SkippedException("Cannot produce core file with hardened binary on OSX 10.15 and later");
                 }
+            } else {
+                // codesign has to add entitlements using the plist. If this is not present we might not generate a core file.
+                if (!Platform.hasOSXPlistEntries()) {
+                    throw new SkippedException("Cannot produce core file with binary having no plist entitlement entries");
+                }
             }
         } else if (Platform.isLinux()) {
             // Check if a crash report tool is installed.
diff --git a/test/lib/jdk/test/lib/util/JavaAgentBuilder.java b/test/lib/jdk/test/lib/util/JavaAgentBuilder.java
index e5fe0cb..d33aa30 100644
--- a/test/lib/jdk/test/lib/util/JavaAgentBuilder.java
+++ b/test/lib/jdk/test/lib/util/JavaAgentBuilder.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,14 +27,12 @@
 import java.io.IOException;
 import java.nio.file.Path;
 import java.nio.file.Paths;
-import java.util.Arrays;
 import java.util.Map;
 import java.util.HashMap;
 import java.util.jar.Attributes;
 import java.util.jar.Manifest;
 
 import jdk.test.lib.Utils;
-import jdk.test.lib.util.JarUtils;
 
 /**
  * A builder for a common Java agent.
diff --git a/test/lib/jdk/test/whitebox/WhiteBox.java b/test/lib/jdk/test/whitebox/WhiteBox.java
index 517c47e..5a0ab74 100644
--- a/test/lib/jdk/test/whitebox/WhiteBox.java
+++ b/test/lib/jdk/test/whitebox/WhiteBox.java
@@ -399,6 +399,8 @@
   public native long metaspaceCapacityUntilGC();
   public native long metaspaceSharedRegionAlignment();
 
+  public native void cleanMetaspaces();
+
   // Metaspace Arena Tests
   public native long createMetaspaceTestContext(long commit_limit, long reserve_limit);
   public native void destroyMetaspaceTestContext(long context);